// src/extension.ts - Extension VS Code principale
import * as vscode from 'vscode';
import axios from 'axios';
import * as fs from 'fs';
import * as path from 'path';

interface WebSentinelFinding {
    check: string;
    title: string;
    severity: 'info' | 'low' | 'medium' | 'high' | 'critical';
    description: string;
    remediation: string;
    line?: number;
    column?: number;
}

interface ScanResult {
    findings: WebSentinelFinding[];
    scan_id: string;
    timestamp: string;
}

class WebSentinelProvider {
    private diagnosticCollection: vscode.DiagnosticCollection;
    private statusBarItem: vscode.StatusBarItem;
    
    constructor() {
        this.diagnosticCollection = vscode.languages.createDiagnosticCollection('web-sentinel');
        this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
        this.statusBarItem.text = "$(shield) Web Sentinel";
        this.statusBarItem.show();
    }

    private getConfig() {
        const config = vscode.workspace.getConfiguration('webSentinel');
        return {
            apiUrl: config.get<string>('apiUrl', 'https://api.web-sentinel.com'),
            apiKey: config.get<string>('apiKey'),
            severityLevel: config.get<string>('severityLevel', 'medium')
        };
    }

    async scanFile(document: vscode.TextDocument): Promise<void> {
        const config = this.getConfig();
        
        if (!config.apiKey) {
            vscode.window.showErrorMessage('🔑 Clé API Web Sentinel manquante. Configurez-la dans les paramètres.');
            return;
        }

        this.statusBarItem.text = "$(loading~spin) Scanning...";
        
        try {
            // Lire le contenu du fichier
            const content = document.getText();
            const languageId = document.languageId;
            
            // Préparer la requête
            const payload = {
                source_content: content,
                language: this.mapLanguage(languageId),
                file_path: document.fileName,
                api_key: config.apiKey,
                options: {
                    severity_min: config.severityLevel,
                    detailed_report: true
                }
            };

            // Appel API
            const response = await axios.post(`${config.apiUrl}/api/v1/scan-source`, payload, {
                headers: {
                    'Content-Type': 'application/json',
                    'User-Agent': 'Web-Sentinel-VSCode/1.0'
                },
                timeout: 30000
            });

            const result: ScanResult = response.data;
            this.displayResults(document, result.findings);
            
            this.statusBarItem.text = `$(shield) ${result.findings.length} issues`;
            
        } catch (error: any) {
            this.statusBarItem.text = "$(shield) Error";
            
            if (error.response?.status === 401) {
                vscode.window.showErrorMessage('🔑 Clé API invalide ou expirée');
            } else if (error.code === 'ECONNREFUSED') {
                vscode.window.showErrorMessage('🌐 Impossible de connecter à l\'API Web Sentinel');
            } else {
                vscode.window.showErrorMessage(`❌ Erreur de scan: ${error.message}`);
            }
        }
    }

    async scanWorkspace(): Promise<void> {
        const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
        if (!workspaceFolder) {
            vscode.window.showErrorMessage('Aucun workspace ouvert');
            return;
        }

        const config = this.getConfig();
        if (!config.apiKey) {
            vscode.window.showErrorMessage('🔑 Clé API Web Sentinel manquante');
            return;
        }

        // Sélectionner les fichiers à scanner
        const files = await this.findSourceFiles(workspaceFolder.uri.fsPath);
        
        if (files.length === 0) {
            vscode.window.showInformationMessage('Aucun fichier source trouvé');
            return;
        }

        const choice = await vscode.window.showInformationMessage(
            `Scanner ${files.length} fichiers ?`,
            'Oui', 'Non'
        );

        if (choice === 'Oui') {
            await vscode.window.withProgress({
                location: vscode.ProgressLocation.Notification,
                title: "Scan Web Sentinel en cours...",
                cancellable: true
            }, async (progress, token) => {
                
                for (let i = 0; i < files.length; i++) {
                    if (token.isCancellationRequested) break;
                    
                    progress.report({
                        increment: (100 / files.length),
                        message: `Scanning ${path.basename(files[i])} (${i+1}/${files.length})`
                    });

                    const document = await vscode.workspace.openTextDocument(files[i]);
                    await this.scanFile(document);
                }
            });
        }
    }

    private async findSourceFiles(workspacePath: string): Promise<string[]> {
        const pattern = new vscode.RelativePattern(workspacePath, '**/*.{php,js,py,java,cs,go}');
        const uris = await vscode.workspace.findFiles(pattern, '**/node_modules/**');
        return uris.map(uri => uri.fsPath);
    }

    private mapLanguage(languageId: string): string {
        const mapping: {[key: string]: string} = {
            'php': 'php',
            'javascript': 'javascript', 
            'typescript': 'javascript',
            'python': 'python',
            'java': 'java',
            'csharp': 'csharp',
            'go': 'go'
        };
        return mapping[languageId] || 'auto';
    }

    private displayResults(document: vscode.TextDocument, findings: WebSentinelFinding[]): void {
        const diagnostics: vscode.Diagnostic[] = [];

        findings.forEach(finding => {
            const line = Math.max(0, (finding.line || 1) - 1);
            const range = new vscode.Range(line, 0, line, 999);
            
            const diagnostic = new vscode.Diagnostic(
                range,
                `${finding.title}: ${finding.description}`,
                this.getSeverityLevel(finding.severity)
            );
            
            diagnostic.source = 'Web Sentinel';
            diagnostic.code = finding.check;
            
            diagnostics.push(diagnostic);
        });

        this.diagnosticCollection.set(document.uri, diagnostics);
    }

    private getSeverityLevel(severity: string): vscode.DiagnosticSeverity {
        switch (severity) {
            case 'critical':
            case 'high':
                return vscode.DiagnosticSeverity.Error;
            case 'medium':
                return vscode.DiagnosticSeverity.Warning;
            case 'low':
            case 'info':
                return vscode.DiagnosticSeverity.Information;
            default:
                return vscode.DiagnosticSeverity.Warning;
        }
    }
}

export function activate(context: vscode.ExtensionContext) {
    console.log('Web Sentinel extension activated');
    
    const provider = new WebSentinelProvider();
    
    // Commandes
    const scanFileCommand = vscode.commands.registerCommand('web-sentinel.scanFile', async () => {
        const editor = vscode.window.activeTextEditor;
        if (editor) {
            await provider.scanFile(editor.document);
        }
    });
    
    const scanWorkspaceCommand = vscode.commands.registerCommand('web-sentinel.scanWorkspace', async () => {
        await provider.scanWorkspace();
    });
    
    const scanDomainCommand = vscode.commands.registerCommand('web-sentinel.scanDomain', async () => {
        const domain = await vscode.window.showInputBox({
            placeHolder: 'example.com',
            prompt: 'Entrez le domaine à scanner'
        });
        
        if (domain) {
            // TODO: Implémenter scan de domaine
            vscode.window.showInformationMessage(`Scan de ${domain} lancé`);
        }
    });

    // Auto-scan à la sauvegarde
    const onDidSaveDocument = vscode.workspace.onDidSaveTextDocument(async (document) => {
        const config = vscode.workspace.getConfiguration('webSentinel');
        if (config.get<boolean>('autoScan', false)) {
            const supportedLanguages = ['php', 'javascript', 'python', 'java', 'csharp', 'go'];
            if (supportedLanguages.includes(document.languageId)) {
                await provider.scanFile(document);
            }
        }
    });

    context.subscriptions.push(
        scanFileCommand,
        scanWorkspaceCommand, 
        scanDomainCommand,
        onDidSaveDocument
    );
}

export function deactivate() {}