<?php
require_once 'config.php';
requireLogin();

set_time_limit(600);
ini_set('max_execution_time', 600);
ini_set('memory_limit', '256M');

$scanResult = null;
$message = '';
$defenseHistory = [];
$wpScanResult = null;

// Get defense history
try {
    $pdo = getDBConnection();
    $stmt = $pdo->query("SELECT * FROM defense_logs ORDER BY timestamp DESC LIMIT 20");
    $defenseHistory = $stmt->fetchAll();
} catch(Exception $e) {}

$defenseTypes = [
    'full_scan'   => ['name' => 'Full Security Audit',       'desc' => 'OWASP Top 10 + WPScan + AI analysis + CVE lookup', 'icon' => 'shield-check',    'color' => '#00ff88'],
    'headers'     => ['name' => 'Security Headers',           'desc' => 'CSP, HSTS, X-Frame, X-Content-Type, Referrer', 'icon' => 'layers',          'color' => '#00cfff'],
    'ssl'         => ['name' => 'SSL/TLS Deep Analysis',      'desc' => 'Certificate chain, protocols, cipher strength', 'icon' => 'lock',            'color' => '#a78bfa'],
    'info_disc'   => ['name' => 'Information Disclosure',     'desc' => 'Sensitive files, error messages, version leaks', 'icon' => 'file-search',    'color' => '#fb923c'],
    'cookies'     => ['name' => 'Cookie Security Audit',      'desc' => 'HttpOnly, Secure, SameSite, expiry analysis',  'icon' => 'cookie',          'color' => '#f472b6'],
    'cors'        => ['name' => 'CORS Configuration',         'desc' => 'Cross-Origin Resource Sharing deep analysis',  'icon' => 'globe',           'color' => '#34d399'],
    'wordpress'   => ['name' => 'WordPress Security',         'desc' => 'WPScan: core, plugin, theme vulnerabilities',  'icon' => 'wordpress',       'color' => '#60a5fa'],
    'ai_audit'    => ['name' => 'AI Deep Audit',              'desc' => 'AI-powered comprehensive security analysis',   'icon' => 'cpu',             'color' => '#e879f9'],
    'dns_recon'   => ['name' => 'DNS & Network Recon',        'desc' => 'DNS records, SPF, DMARC, open ports check',    'icon' => 'network',         'color' => '#fbbf24'],
    'waf_detect'  => ['name' => 'WAF & CDN Detection',        'desc' => 'Detect WAF, CDN, load balancer fingerprints',  'icon' => 'filter',          'color' => '#f87171'],
    'subdomain'   => ['name' => 'Subdomain Enumeration',      'desc' => 'Common subdomains discovery & analysis',       'icon' => 'sitemap',         'color' => '#4ade80'],
    'quick'       => ['name' => 'Quick Check',                'desc' => 'Essential headers + SSL + exposed files',      'icon' => 'zap',             'color' => '#facc15'],
];

// ===================== AJAX / SSE ENDPOINT =====================
if (isset($_GET['stream']) && $_GET['stream'] === '1') {
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');
    header('X-Accel-Buffering: no');
    
    $targetUrl = $_GET['url'] ?? '';
    $defenseType = $_GET['type'] ?? 'full_scan';
    
    if (!preg_match('#^https?://#', $targetUrl)) $targetUrl = 'https://' . $targetUrl;
    
    function sse($event, $data) {
        echo "event: {$event}\n";
        echo "data: " . json_encode($data) . "\n\n";
        if (ob_get_level()) ob_flush();
        flush();
    }
    
    sse('status', ['msg' => 'Initializing scan engine...', 'pct' => 2]);
    sleep(0);
    
    $result = performDetailedSecurityScan($targetUrl, $defenseType, function($msg, $pct) {
        sse('status', ['msg' => $msg, 'pct' => $pct]);
    });
    
    // Log to DB
    try {
        $pdo = getDBConnection();
        $stmt = $pdo->prepare("INSERT INTO defense_logs (target_url, defense_type, findings, recommendations, risk_score, timestamp) VALUES (?, ?, ?, ?, ?, NOW())");
        $stmt->execute([
            $targetUrl,
            $defenseTypes[$defenseType]['name'] ?? $defenseType,
            json_encode($result['findings']),
            json_encode($result['recommendations']),
            $result['risk_score']
        ]);
    } catch(Exception $e) {}
    
    sse('result', $result);
    sse('done', ['msg' => 'Scan complete']);
    exit;
}

// ===================== CORE SCAN ENGINE =====================
function performDetailedSecurityScan($url, $type, $progress = null) {
    $findings = [];
    $recommendations = [];
    $riskScore = 100;
    $details = [];

    $p = $progress ?: function($m, $pct) {};

    $p('Resolving target...', 5);
    $response = makeSecureRequest($url);
    $parsed   = parse_url($url);
    $host     = $parsed['host'] ?? '';
    $baseUrl  = $parsed['scheme'] . '://' . $host;
    if (isset($parsed['port'])) $baseUrl .= ':' . $parsed['port'];

    $headers  = $response['headers'];
    $body     = $response['body'];
    $httpCode = $response['http_code'];
    $responseTime = $response['time'] ?? 0;

    // Tech fingerprint
    $p('Fingerprinting technologies...', 10);
    $serverInfo  = [];
    if (preg_match('/Server:\s*(.*)/i',       $headers, $m)) $serverInfo['server']       = trim($m[1]);
    if (preg_match('/X-Powered-By:\s*(.*)/i', $headers, $m)) $serverInfo['powered_by']  = trim($m[1]);
    if (preg_match('/X-Generator:\s*(.*)/i',  $headers, $m)) $serverInfo['generator']    = trim($m[1]);
    if (preg_match('/X-AspNet-Version:\s*(.*)/i', $headers, $m)) $serverInfo['aspnet']  = trim($m[1]);
    if (preg_match('/X-Runtime:\s*(.*)/i',    $headers, $m)) $serverInfo['runtime']      = trim($m[1]);

    $technologies = [];
    $techPatterns = [
        'WordPress' => ['wp-content','wordpress','wp-json'],
        'Joomla'    => ['joomla','com_content'],
        'Drupal'    => ['drupal','sites/default'],
        'jQuery'    => ['jquery'],
        'React'     => ['react','__NEXT_DATA__'],
        'Vue.js'    => ['vue.js','__vue__'],
        'Angular'   => ['ng-version','angular'],
        'Laravel'   => ['laravel','XSRF-TOKEN'],
        'Django'    => ['django','csrfmiddlewaretoken'],
        'Rails'     => ['rails','X-Runtime'],
        'ASP.NET'   => ['__VIEWSTATE','ASP.NET'],
        'PHP'       => ['php','PHPSESSID'],
        'Bootstrap' => ['bootstrap'],
        'Cloudflare'=> ['CF-RAY','cloudflare'],
        'Nginx'     => ['nginx'],
        'Apache'    => ['Apache'],
    ];
    foreach ($techPatterns as $tech => $patterns) {
        foreach ($patterns as $pat) {
            if (stripos($body.$headers, $pat) !== false) {
                $technologies[] = $tech;
                break;
            }
        }
    }
    $technologies = array_unique($technologies);

    // ─── SECURITY HEADERS ───
    if (in_array($type, ['full_scan','headers','quick'])) {
        $p('Analyzing security headers...', 18);
        $securityHeaders = [
            'Content-Security-Policy'           => ['weight'=>25,'desc'=>'Prevents XSS & code injection','rec'=>"default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none';"],
            'Strict-Transport-Security'         => ['weight'=>20,'desc'=>'Forces HTTPS connections',       'rec'=>'max-age=31536000; includeSubDomains; preload'],
            'X-Frame-Options'                   => ['weight'=>15,'desc'=>'Prevents clickjacking attacks',  'rec'=>'DENY'],
            'X-Content-Type-Options'            => ['weight'=>15,'desc'=>'Stops MIME-type sniffing',       'rec'=>'nosniff'],
            'Referrer-Policy'                   => ['weight'=>10,'desc'=>'Controls Referer header data',   'rec'=>'strict-origin-when-cross-origin'],
            'Permissions-Policy'                => ['weight'=> 5,'desc'=>'Restricts browser APIs',         'rec'=>'camera=(), microphone=(), geolocation=(), payment=()'],
            'Cross-Origin-Embedder-Policy'      => ['weight'=> 5,'desc'=>'Isolates cross-origin resources','rec'=>'require-corp'],
            'Cross-Origin-Opener-Policy'        => ['weight'=> 5,'desc'=>'Isolates browsing context',     'rec'=>'same-origin'],
            'Cross-Origin-Resource-Policy'      => ['weight'=> 3,'desc'=>'Controls resource sharing',      'rec'=>'same-origin'],
            'X-DNS-Prefetch-Control'            => ['weight'=> 2,'desc'=>'Controls DNS prefetching',       'rec'=>'off'],
        ];
        $headersFound = 0;
        foreach ($securityHeaders as $header => $info) {
            if (stripos($headers, $header.':') === false) {
                $sev = $info['weight'] >= 20 ? 'Critical' : ($info['weight'] >= 10 ? 'High' : 'Medium');
                $findings[] = ['category'=>'Headers','type'=>$header,'status'=>'MISSING',
                    'severity'=>$sev,'detail'=>$info['desc'].' not configured',
                    'recommendation'=>"Add header: {$header}: {$info['rec']}",
                    'risk_deduction'=>$info['weight'],'grade'=>'F','impact'=>'High'];
                $riskScore -= $info['weight'];
            } else {
                $headersFound++;
                preg_match('/'.$header.':\s*(.*)/i', $headers, $m2);
                $val = trim($m2[1] ?? '');
                $grade = 'A'; $note = '';
                if ($header === 'Content-Security-Policy') {
                    if (strpos($val,"'unsafe-inline'") !== false) { $grade='C'; $note="Contains 'unsafe-inline' — allows inline scripts"; $riskScore-=8; }
                    elseif (strpos($val,"'unsafe-eval'") !== false) { $grade='B'; $note="Contains 'unsafe-eval'"; $riskScore-=4; }
                    elseif (strpos($val,'*') !== false) { $grade='B-'; $note='Wildcard source detected'; $riskScore-=5; }
                }
                if ($header === 'Strict-Transport-Security') {
                    preg_match('/max-age=(\d+)/i', $val, $ma);
                    $age = intval($ma[1] ?? 0);
                    if ($age < 31536000) { $grade='B'; $note="max-age={$age} is too short (need 31536000+)"; $riskScore-=5; }
                    if (stripos($val,'includeSubDomains') === false) { $note.=' Missing includeSubDomains'; $riskScore-=3; }
                    if (stripos($val,'preload') === false) { $note.=' Not preload-ready'; }
                }
                $findings[] = ['category'=>'Headers','type'=>$header,'status'=>'PRESENT',
                    'severity'=>$note ? 'Medium' : 'Info',
                    'detail'=>$note ?: 'Properly configured',
                    'recommendation'=>$note ? "Improve: {$header}: {$info['rec']}" : 'No action needed',
                    'risk_deduction'=>0,'grade'=>$grade,'value'=>$val,'impact'=>'None'];
            }
        }
        $details['headers_score'] = round(($headersFound / count($securityHeaders)) * 100);
    }

    // ─── SSL/TLS ───
    if (in_array($type, ['full_scan','ssl','quick']) && ($parsed['scheme'] ?? '') === 'https') {
        $p('Checking SSL/TLS configuration...', 32);
        $sslInfo = checkDetailedSSL($host);
        if ($sslInfo['error']) {
            $findings[] = ['category'=>'SSL','type'=>'SSL Connection Failed','status'=>'FAIL',
                'severity'=>'Critical','detail'=>$sslInfo['error'],
                'recommendation'=>'Verify SSL certificate and server configuration','risk_deduction'=>30,'grade'=>'F','impact'=>'Critical'];
            $riskScore -= 30;
        } else {
            $days = $sslInfo['days_remaining'];
            if ($days < 0) {
                $findings[] = ['category'=>'SSL','type'=>'SSL Certificate EXPIRED','status'=>'CRITICAL',
                    'severity'=>'Critical','detail'=>"Certificate expired ".abs($days)." days ago",
                    'recommendation'=>'REPLACE CERTIFICATE IMMEDIATELY','risk_deduction'=>40,'grade'=>'F','impact'=>'Critical'];
                $riskScore -= 40;
            } elseif ($days < 7) {
                $findings[] = ['category'=>'SSL','type'=>'Certificate Expiring in '.$days.' days','status'=>'CRITICAL',
                    'severity'=>'Critical','detail'=>"Expires in {$days} days — URGENT renewal required",
                    'recommendation'=>'Renew certificate today','risk_deduction'=>25,'grade'=>'F','impact'=>'Critical'];
                $riskScore -= 25;
            } elseif ($days < 30) {
                $findings[] = ['category'=>'SSL','type'=>'Certificate Expiring Soon','status'=>'WARNING',
                    'severity'=>'High','detail'=>"Expires in {$days} days",
                    'recommendation'=>'Schedule renewal within 2 weeks','risk_deduction'=>10,'grade'=>'C','impact'=>'High'];
                $riskScore -= 10;
            } else {
                $findings[] = ['category'=>'SSL','type'=>'SSL Certificate Valid','status'=>'OK',
                    'severity'=>'Info','detail'=>"Valid for {$days} more days | Issuer: ".($sslInfo['issuer']??'Unknown'),
                    'recommendation'=>'Certificate is healthy','risk_deduction'=>0,'grade'=>'A+','impact'=>'None'];
            }
            // Self-signed check
            if (isset($sslInfo['issuer']) && stripos($sslInfo['issuer'], $host) !== false) {
                $findings[] = ['category'=>'SSL','type'=>'Self-Signed Certificate Detected','status'=>'WARN',
                    'severity'=>'High','detail'=>'Certificate is self-signed — browsers will show warnings',
                    'recommendation'=>"Use a trusted CA (Let's Encrypt is free)",'risk_deduction'=>15,'grade'=>'F','impact'=>'High'];
                $riskScore -= 15;
            }
            $details['ssl_days'] = $days;
            $details['ssl_issuer'] = $sslInfo['issuer'] ?? 'Unknown';
        }
    }

    // ─── INFORMATION DISCLOSURE ───
    if (in_array($type, ['full_scan','info_disc','quick'])) {
        $p('Scanning for exposed sensitive files...', 44);
        $sensitivePaths = [
            '/.env'              => ['n'=>'.env File',           's'=>'Critical','w'=>25,'d'=>'DB creds, API keys, app secrets exposed'],
            '/.env.backup'       => ['n'=>'.env Backup',         's'=>'Critical','w'=>25,'d'=>'Backup of environment file'],
            '/.env.local'        => ['n'=>'.env.local',          's'=>'Critical','w'=>22,'d'=>'Local environment credentials'],
            '/.git/HEAD'         => ['n'=>'Git Repository',      's'=>'Critical','w'=>25,'d'=>'Full source code history is public'],
            '/.git/config'       => ['n'=>'Git Config',          's'=>'Critical','w'=>20,'d'=>'Repository URLs and user info exposed'],
            '/backup.zip'        => ['n'=>'Backup ZIP',          's'=>'Critical','w'=>20,'d'=>'Full site backup including configs'],
            '/backup.sql'        => ['n'=>'Database Dump',       's'=>'Critical','w'=>25,'d'=>'Full database export with user data'],
            '/dump.sql'          => ['n'=>'DB Dump',             's'=>'Critical','w'=>25,'d'=>'Database dump file'],
            '/database.sql'      => ['n'=>'Database SQL',        's'=>'Critical','w'=>25,'d'=>'Database backup'],
            '/wp-config.php'     => ['n'=>'WP Config',           's'=>'Critical','w'=>20,'d'=>'WordPress DB credentials & auth keys'],
            '/config.php'        => ['n'=>'Config File',         's'=>'Critical','w'=>20,'d'=>'App configuration with credentials'],
            '/configuration.php' => ['n'=>'Joomla Config',       's'=>'Critical','w'=>20,'d'=>'Joomla database configuration'],
            '/app/config/parameters.yml' => ['n'=>'Symfony Config','s'=>'Critical','w'=>20,'d'=>'Symfony framework configuration'],
            '/phpinfo.php'       => ['n'=>'PHPInfo',             's'=>'High','w'=>15,'d'=>'Server config, paths, PHP version exposed'],
            '/info.php'          => ['n'=>'PHPInfo (alt)',        's'=>'High','w'=>15,'d'=>'Server internals exposed'],
            '/php.php'           => ['n'=>'PHP Info',            's'=>'High','w'=>12,'d'=>'PHP configuration disclosure'],
            '/admin'             => ['n'=>'Admin Panel',         's'=>'Medium','w'=>10,'d'=>'Administrative interface exposed'],
            '/admin.php'         => ['n'=>'Admin Page',          's'=>'Medium','w'=>10,'d'=>'Admin login accessible'],
            '/administrator'     => ['n'=>'Joomla Admin',        's'=>'Medium','w'=>10,'d'=>'Joomla administrator panel'],
            '/.htaccess'         => ['n'=>'Htaccess',            's'=>'Medium','w'=>8, 'd'=>'Apache rewrite rules exposed'],
            '/server-status'     => ['n'=>'Apache Status',       's'=>'High','w'=>15,'d'=>'Real-time server requests visible'],
            '/server-info'       => ['n'=>'Apache Info',         's'=>'High','w'=>12,'d'=>'Apache configuration exposed'],
            '/.DS_Store'         => ['n'=>'Mac DS_Store',        's'=>'Low','w'=>3,  'd'=>'Directory structure metadata leaked'],
            '/debug'             => ['n'=>'Debug Endpoint',      's'=>'High','w'=>15,'d'=>'Debug info may reveal sensitive data'],
            '/test.php'          => ['n'=>'Test File',           's'=>'Medium','w'=>8,'d'=>'Dev file left on production server'],
            '/readme.html'       => ['n'=>'Readme (version)',    's'=>'Low','w'=>3,  'd'=>'Version disclosure in readme'],
            '/CHANGELOG'         => ['n'=>'Changelog',           's'=>'Low','w'=>2,  'd'=>'Version history exposed'],
            '/composer.json'     => ['n'=>'Composer Config',     's'=>'Medium','w'=>8,'d'=>'Dependencies and versions exposed'],
            '/package.json'      => ['n'=>'NPM Package',         's'=>'Low','w'=>4,  'd'=>'Node.js dependencies exposed'],
            '/docker-compose.yml'=> ['n'=>'Docker Compose',      's'=>'High','w'=>12,'d'=>'Container configuration exposed'],
            '/Dockerfile'        => ['n'=>'Dockerfile',          's'=>'Medium','w'=>8,'d'=>'Docker build config exposed'],
            '/.bash_history'     => ['n'=>'Bash History',        's'=>'Critical','w'=>25,'d'=>'Command history with possible credentials'],
            '/id_rsa'            => ['n'=>'SSH Private Key',     's'=>'Critical','w'=>30,'d'=>'CRITICAL: Private SSH key exposed!'],
            '/crossdomain.xml'   => ['n'=>'Crossdomain Policy',  's'=>'Medium','w'=>6, 'd'=>'Flash cross-domain policy'],
            '/clientaccesspolicy.xml'=> ['n'=>'Silverlight Policy','s'=>'Low','w'=>3,'d'=>'Silverlight access policy'],
        ];
        foreach ($sensitivePaths as $path => $info) {
            $cr = makeSecureRequest($baseUrl.$path, 'GET', [], [], 5);
            if ($cr['http_code'] == 200 && strlen($cr['body']) > 10) {
                $findings[] = ['category'=>'Exposure','type'=>'EXPOSED: '.$info['n'],'status'=>'EXPOSED',
                    'severity'=>$info['s'],'detail'=>$info['d'],
                    'recommendation'=>"Immediately restrict or remove {$path} from your server",
                    'risk_deduction'=>$info['w'],'grade'=>'F','impact'=>'Critical','url'=>$baseUrl.$path];
                $riskScore -= $info['w'];
            }
        }
        // Error leakage in body
        $errPatterns = [
            '/Warning:.*on line \d+/i'                => ['PHP Warning Disclosure','Medium',8],
            '/Fatal error:/i'                          => ['PHP Fatal Error Exposed','High',12],
            '/Stack trace:/i'                          => ['Stack Trace Exposed','High',15],
            '/mysql_connect|mysqli_connect|pg_connect/i'=> ['DB Connection Code Exposed','High',15],
            '/ORA-\d{5}/i'                             => ['Oracle DB Error Exposed','High',15],
            '/SQLSTATE\[\d{5}\]/i'                     => ['SQL Error Exposed','High',12],
            '/OperationalError/i'                      => ['Python DB Error Exposed','Medium',10],
            '/Exception in thread/i'                   => ['Java Stack Trace','Medium',10],
        ];
        foreach ($errPatterns as $pat => [$name, $sev, $weight]) {
            if (preg_match($pat, $body)) {
                $findings[] = ['category'=>'Exposure','type'=>$name,'status'=>'LEAK',
                    'severity'=>$sev,'detail'=>'Error messages in page response reveal server internals',
                    'recommendation'=>'Disable display_errors; log errors server-side only',
                    'risk_deduction'=>$weight,'grade'=>'D','impact'=>'High'];
                $riskScore -= $weight;
            }
        }
        // Server version disclosure
        if (!empty($serverInfo['server']) && strlen($serverInfo['server']) > 5) {
            $findings[] = ['category'=>'Exposure','type'=>'Server Version Disclosed','status'=>'WARN',
                'severity'=>'Low','detail'=>"Server header: {$serverInfo['server']}",
                'recommendation'=>'Set ServerTokens Prod (Apache) or server_tokens off (Nginx)',
                'risk_deduction'=>3,'grade'=>'C','impact'=>'Low'];
            $riskScore -= 3;
        }
        if (!empty($serverInfo['powered_by'])) {
            $findings[] = ['category'=>'Exposure','type'=>'Technology Stack Exposed','status'=>'WARN',
                'severity'=>'Low','detail'=>"X-Powered-By: {$serverInfo['powered_by']}",
                'recommendation'=>'Remove X-Powered-By header in PHP/server config',
                'risk_deduction'=>2,'grade'=>'C','impact'=>'Low'];
            $riskScore -= 2;
        }
    }

    // ─── COOKIE SECURITY ───
    if (in_array($type, ['full_scan','cookies','quick'])) {
        $p('Auditing cookie security flags...', 58);
        preg_match_all('/Set-Cookie:\s*([^\r\n]+)/i', $headers, $cm);
        if (empty($cm[1])) {
            $findings[] = ['category'=>'Cookies','type'=>'No Cookies Detected','status'=>'INFO',
                'severity'=>'Info','detail'=>'No Set-Cookie headers in response',
                'recommendation'=>'Ensure session cookies are properly secured when set',
                'risk_deduction'=>0,'grade'=>'N/A','impact'=>'None'];
        } else {
            foreach ($cm[1] as $cookie) {
                $name = strstr($cookie, '=', true);
                $issues = [];
                if (stripos($cookie,'HttpOnly') === false) $issues[] = 'Missing HttpOnly (XSS risk)';
                if (stripos($cookie,'Secure')   === false && ($parsed['scheme']??'') === 'https') $issues[] = 'Missing Secure flag (can send over HTTP)';
                if (stripos($cookie,'SameSite') === false) $issues[] = 'Missing SameSite (CSRF risk)';
                // Check session cookie name patterns
                $isSession = preg_match('/sess|sid|token|auth|login/i', $name);
                if ($isSession && stripos($cookie,'HttpOnly') === false) {
                    $findings[] = ['category'=>'Cookies','type'=>'⚠️ Session Cookie Insecure: '.$name,'status'=>'CRITICAL',
                        'severity'=>'Critical','detail'=>'Session cookie lacks HttpOnly — XSS can steal this token',
                        'recommendation'=>"Set-Cookie: {$name}=...; HttpOnly; Secure; SameSite=Lax; Path=/",
                        'risk_deduction'=>20,'grade'=>'F','impact'=>'Critical'];
                    $riskScore -= 20;
                } elseif (!empty($issues)) {
                    $findings[] = ['category'=>'Cookies','type'=>'Insecure Cookie: '.$name,'status'=>'WARN',
                        'severity'=>'High','detail'=>implode(', ', $issues),
                        'recommendation'=>"Add flags: HttpOnly; Secure; SameSite=Strict to cookie '{$name}'",
                        'risk_deduction'=>count($issues)*6,'grade'=>'D','impact'=>'High'];
                    $riskScore -= count($issues)*6;
                } else {
                    $findings[] = ['category'=>'Cookies','type'=>'Secure Cookie: '.$name,'status'=>'OK',
                        'severity'=>'Info','detail'=>'HttpOnly + Secure + SameSite all present',
                        'recommendation'=>'Cookie is correctly secured','risk_deduction'=>0,'grade'=>'A+','impact'=>'None'];
                }
            }
        }
    }

    // ─── CORS ───
    if (in_array($type, ['full_scan','cors'])) {
        $p('Testing CORS configuration...', 65);
        $cr2 = makeSecureRequest($url, 'GET', [], ['Origin: https://evil-attacker.com']);
        $acao = '';
        if (preg_match('/Access-Control-Allow-Origin:\s*(.*)/i', $cr2['headers'], $m3)) $acao = trim($m3[1]);
        $creds = stripos($cr2['headers'], 'Access-Control-Allow-Credentials: true') !== false;

        if ($acao === '*' && $creds) {
            $findings[] = ['category'=>'CORS','type'=>'CRITICAL CORS Misconfiguration','status'=>'CRITICAL',
                'severity'=>'Critical','detail'=>'Wildcard ACAO (*) with credentials=true — any site can make authenticated API calls',
                'recommendation'=>'NEVER use * with credentials. Whitelist specific origins.',
                'risk_deduction'=>30,'grade'=>'F','impact'=>'Critical'];
            $riskScore -= 30;
        } elseif ($acao === '*') {
            $findings[] = ['category'=>'CORS','type'=>'Permissive CORS Policy','status'=>'WARN',
                'severity'=>'Medium','detail'=>"ACAO: * — any domain can read responses",
                'recommendation'=>'Restrict to specific allowed origins','risk_deduction'=>10,'grade'=>'C','impact'=>'Medium'];
            $riskScore -= 10;
        } elseif ($acao === 'https://evil-attacker.com') {
            $findings[] = ['category'=>'CORS','type'=>'CORS Origin Reflection Vulnerability','status'=>'CRITICAL',
                'severity'=>'Critical','detail'=>'Server reflects arbitrary Origin header — allows cross-origin attacks',
                'recommendation'=>'Implement strict origin whitelist, never reflect Origin dynamically',
                'risk_deduction'=>25,'grade'=>'F','impact'=>'Critical'];
            $riskScore -= 25;
        } elseif (!empty($acao)) {
            $findings[] = ['category'=>'CORS','type'=>'CORS: Specific Origin Allowed','status'=>'OK',
                'severity'=>'Info','detail'=>"ACAO restricted to: {$acao}",
                'recommendation'=>'Verify this origin is intentionally trusted','risk_deduction'=>0,'grade'=>'A','impact'=>'None'];
        } else {
            $findings[] = ['category'=>'CORS','type'=>'No CORS Headers (Same-Origin)','status'=>'OK',
                'severity'=>'Info','detail'=>'No cross-origin access configured — same-origin policy enforced',
                'recommendation'=>'Correct for non-API applications','risk_deduction'=>0,'grade'=>'A+','impact'=>'None'];
        }
    }

    // ─── DNS & NETWORK RECON ───
    if (in_array($type, ['full_scan','dns_recon'])) {
        $p('Running DNS reconnaissance...', 70);
        // SPF record
        $spfRecords = dns_get_record($host, DNS_TXT);
        $hasSPF  = false;
        $hasDMARC = false;
        $hasDKIM = false;
        foreach (($spfRecords ?: []) as $r) {
            if (isset($r['txt'])) {
                if (stripos($r['txt'],'v=spf1') !== false) $hasSPF = true;
            }
        }
        $dmarcRecords = @dns_get_record('_dmarc.'.$host, DNS_TXT);
        if ($dmarcRecords) {
            foreach ($dmarcRecords as $r) {
                if (isset($r['txt']) && stripos($r['txt'],'v=DMARC1') !== false) $hasDMARC = true;
            }
        }
        $findings[] = ['category'=>'DNS','type'=>$hasSPF?'SPF Record Found':'SPF Record Missing','status'=>$hasSPF?'OK':'WARN',
            'severity'=>$hasSPF?'Info':'Medium','detail'=>$hasSPF?'SPF prevents email spoofing':'No SPF record — domain can be used for phishing',
            'recommendation'=>$hasSPF?'SPF is configured':'Add SPF TXT record: v=spf1 include:yourmailprovider.com ~all',
            'risk_deduction'=>$hasSPF?0:8,'grade'=>$hasSPF?'A':'D','impact'=>$hasSPF?'None':'Medium'];
        if (!$hasSPF) $riskScore -= 8;

        $findings[] = ['category'=>'DNS','type'=>$hasDMARC?'DMARC Record Found':'DMARC Record Missing','status'=>$hasDMARC?'OK':'WARN',
            'severity'=>$hasDMARC?'Info':'Medium','detail'=>$hasDMARC?'DMARC policy configured':'No DMARC — phishing emails from your domain may not be blocked',
            'recommendation'=>$hasDMARC?'DMARC is configured':'Add: _dmarc.'.$host.' TXT "v=DMARC1; p=reject; rua=mailto:dmarc@'.$host.'"',
            'risk_deduction'=>$hasDMARC?0:8,'grade'=>$hasDMARC?'A':'D','impact'=>$hasDMARC?'None':'Medium'];
        if (!$hasDMARC) $riskScore -= 8;

        // MX records
        $mx = @dns_get_record($host, DNS_MX);
        if ($mx) {
            $mxHosts = array_map(fn($r) => $r['target']??'', $mx);
            $findings[] = ['category'=>'DNS','type'=>'MX Records Found','status'=>'INFO',
                'severity'=>'Info','detail'=>'Mail servers: '.implode(', ', array_slice($mxHosts,0,3)),
                'recommendation'=>'Ensure mail servers are secured and SPF/DMARC are configured',
                'risk_deduction'=>0,'grade'=>'A','impact'=>'None'];
        }
        // CAA record
        $caa = @dns_get_record($host, DNS_CAA);
        if (!$caa) {
            $findings[] = ['category'=>'DNS','type'=>'No CAA Record','status'=>'WARN',
                'severity'=>'Low','detail'=>'Any CA can issue certificates for this domain',
                'recommendation'=>"Add CAA record: 0 issue \"letsencrypt.org\"",
                'risk_deduction'=>3,'grade'=>'C','impact'=>'Low'];
            $riskScore -= 3;
        } else {
            $findings[] = ['category'=>'DNS','type'=>'CAA Record Present','status'=>'OK',
                'severity'=>'Info','detail'=>'Certificate authority restricted via CAA',
                'recommendation'=>'CAA is configured correctly','risk_deduction'=>0,'grade'=>'A','impact'=>'None'];
        }
    }

    // ─── WAF / CDN DETECTION ───
    if (in_array($type, ['full_scan','waf_detect'])) {
        $p('Detecting WAF and CDN...', 76);
        $wafSignatures = [
            'Cloudflare'  => ['CF-RAY','__cfduid','cf-cache-status'],
            'AWS WAF'     => ['x-amzn-RequestId','x-amz-cf-id'],
            'Akamai'      => ['X-Check-Cacheable','Akamai'],
            'Fastly CDN'  => ['Fastly-Restarts','X-Served-By'],
            'Sucuri WAF'  => ['X-Sucuri-ID','X-Sucuri-Cache'],
            'Incapsula'   => ['X-Iinfo','visid_incap'],
            'ModSecurity' => ['Mod_Security','NOYB'],
            'F5 BIG-IP'   => ['BIGipServer','F5'],
            'Barracuda'   => ['barra_counter_session'],
            'Wordfence'   => ['wordfence'],
        ];
        $detected = [];
        foreach ($wafSignatures as $waf => $sigs) {
            foreach ($sigs as $sig) {
                if (stripos($headers.$body, $sig) !== false) {
                    $detected[] = $waf;
                    break;
                }
            }
        }
        if (!empty($detected)) {
            $wafList = implode(', ', array_unique($detected));
            $findings[] = ['category'=>'WAF','type'=>'WAF/CDN Detected: '.$wafList,'status'=>'OK',
                'severity'=>'Info','detail'=>"Active protection layer detected: {$wafList}",
                'recommendation'=>'WAF detected — ensure WAF rules are up-to-date','risk_deduction'=>0,'grade'=>'A','impact'=>'Positive'];
        } else {
            $findings[] = ['category'=>'WAF','type'=>'No WAF/CDN Detected','status'=>'WARN',
                'severity'=>'Medium','detail'=>'No web application firewall or CDN detected on this origin',
                'recommendation'=>'Consider deploying Cloudflare, AWS WAF, or similar WAF for additional protection',
                'risk_deduction'=>5,'grade'=>'C','impact'=>'Medium'];
            $riskScore -= 5;
        }
        // Load balancer detect
        if (preg_match('/X-Load-Balancer:|X-Backend-Server:|Via:/i', $headers)) {
            $findings[] = ['category'=>'WAF','type'=>'Load Balancer Detected','status'=>'INFO',
                'severity'=>'Info','detail'=>'Load balancer or proxy layer present',
                'recommendation'=>'Ensure backend servers are not directly accessible','risk_deduction'=>0,'grade'=>'A','impact'=>'None'];
        }
    }

    // ─── SUBDOMAIN ENUMERATION ───
    if (in_array($type, ['full_scan','subdomain'])) {
        $p('Enumerating common subdomains...', 82);
        $commonSubs = ['www','mail','smtp','ftp','dev','staging','test','api','admin','portal','vpn','remote','shop','store','blog','forum','support','help','status','beta','demo','old','backup','db','database'];
        $found = [];
        foreach (array_slice($commonSubs,0,15) as $sub) {
            $subHost = $sub.'.'.$host;
            $ip = @gethostbyname($subHost);
            if ($ip !== $subHost) {
                $found[] = $subHost.' ('.$ip.')';
                // Check if sensitive
                if (in_array($sub, ['dev','staging','test','beta','old','backup','demo'])) {
                    $findings[] = ['category'=>'Subdomain','type'=>'Sensitive Subdomain: '.$subHost,'status'=>'WARN',
                        'severity'=>'Medium','detail'=>"Non-production environment exposed: {$subHost}",
                        'recommendation'=>'Restrict access to dev/staging environments (IP whitelist or VPN)',
                        'risk_deduction'=>8,'grade'=>'C','impact'=>'Medium'];
                    $riskScore -= 8;
                }
            }
        }
        if (!empty($found)) {
            $details['subdomains'] = $found;
            $findings[] = ['category'=>'Subdomain','type'=>count($found).' Subdomains Discovered','status'=>'INFO',
                'severity'=>'Info','detail'=>implode(' | ', array_slice($found,0,5)),
                'recommendation'=>'Review all subdomains for proper security configuration',
                'risk_deduction'=>0,'grade'=>'B','impact'=>'Low'];
        }
    }

    // ─── WORDPRESS SPECIFIC ───
    if (in_array($type, ['full_scan','wordpress']) && in_array('WordPress', $technologies)) {
        $p('Running WordPress security audit...', 87);
        // Check user enum
        $ueResp = makeSecureRequest($baseUrl.'/?author=1');
        if (stripos($ueResp['headers'].$ueResp['body'], '/author/') !== false && $ueResp['http_code'] === 302) {
            $findings[] = ['category'=>'WordPress','type'=>'WP User Enumeration','status'=>'WARN',
                'severity'=>'High','detail'=>'/?author=1 redirects to /author/username — leaking usernames',
                'recommendation'=>'Block /?author= requests via .htaccess or security plugin',
                'risk_deduction'=>10,'grade'=>'D','impact'=>'High'];
            $riskScore -= 10;
        }
        // XML-RPC
        $xmlResp = makeSecureRequest($baseUrl.'/xmlrpc.php');
        if ($xmlResp['http_code'] === 200 || $xmlResp['http_code'] === 405) {
            $findings[] = ['category'=>'WordPress','type'=>'XML-RPC Enabled','status'=>'WARN',
                'severity'=>'High','detail'=>'xmlrpc.php is active — allows brute-force amplification attacks',
                'recommendation'=>'Disable XML-RPC via plugin or add: <Files xmlrpc.php> Order deny,allow Deny from all </Files>',
                'risk_deduction'=>12,'grade'=>'D','impact'=>'High'];
            $riskScore -= 12;
        }
        // WP version
        if (preg_match('/WordPress (\d+\.\d+[\.\d]*)/i', $body, $wpm)) {
            $findings[] = ['category'=>'WordPress','type'=>'WordPress Version Disclosed: '.$wpm[1],'status'=>'WARN',
                'severity'=>'Low','detail'=>'WordPress version visible in page source',
                'recommendation'=>'Remove generator meta tag and version from scripts/styles',
                'risk_deduction'=>3,'grade'=>'C','impact'=>'Low'];
            $riskScore -= 3;
        }
        // WP REST API
        $apiResp = makeSecureRequest($baseUrl.'/wp-json/wp/v2/users');
        if ($apiResp['http_code'] === 200 && stripos($apiResp['body'],'"slug"') !== false) {
            $findings[] = ['category'=>'WordPress','type'=>'WP REST API User Leak','status'=>'CRITICAL',
                'severity'=>'Critical','detail'=>'/wp-json/wp/v2/users exposes all usernames publicly',
                'recommendation'=>'Disable user endpoint or require authentication for REST API',
                'risk_deduction'=>15,'grade'=>'F','impact'=>'Critical'];
            $riskScore -= 15;
        }
        // Debug mode check
        if (stripos($body, 'define(\'WP_DEBUG\', true)') !== false || stripos($body,'WP_DEBUG_LOG') !== false) {
            $findings[] = ['category'=>'WordPress','type'=>'WP Debug Mode Enabled','status'=>'CRITICAL',
                'severity'=>'High','detail'=>'WordPress debug mode appears to be active in production',
                'recommendation'=>"Set WP_DEBUG to false in wp-config.php",
                'risk_deduction'=>10,'grade'=>'F','impact'=>'High'];
            $riskScore -= 10;
        }
    }

    // ─── AI ANALYSIS ───
    if (in_array($type, ['full_scan','ai_audit']) && function_exists('callAI')) {
        $p('Running AI-powered deep analysis...', 92);
        $critCount = count(array_filter($findings, fn($f) => $f['severity'] === 'Critical'));
        $highCount = count(array_filter($findings, fn($f) => $f['severity'] === 'High'));
        $aiPrompt = "Perform expert security analysis for: {$url}\n\n";
        $aiPrompt .= "HTTP Status: {$httpCode} | Response Time: {$responseTime}ms\n";
        $aiPrompt .= "Technologies: ".implode(', ', $technologies)."\n";
        $aiPrompt .= "Server Info: ".json_encode($serverInfo)."\n";
        $aiPrompt .= "Current Risk Score: {$riskScore}/100\n";
        $aiPrompt .= "Critical Findings: {$critCount} | High: {$highCount}\n";
        $aiPrompt .= "Total Issues: ".count($findings)."\n\n";
        $aiPrompt .= "Provide:\n1. Executive Summary (2-3 sentences)\n2. Top 3 critical attack vectors with exploitation scenarios\n3. Prioritized remediation roadmap (immediate/short-term/long-term)\n4. Compliance implications (GDPR, PCI-DSS, ISO27001, HIPAA if applicable)\n5. Overall security posture rating with justification\n";
        $aiAnalysis = callAI($aiPrompt, "You are a CISO-level application security expert. Provide detailed, actionable security assessments with real-world attack context. Be specific about exploitation impact.");
        if ($aiAnalysis && strpos($aiAnalysis,'ERROR') === false) {
            $details['ai_analysis'] = $aiAnalysis;
        }
    }

    $p('Calculating final risk score...', 98);
    $riskScore = max(0, min(100, $riskScore));
    $grade = 'A+';
    if ($riskScore < 20)      $grade = 'A+';
    elseif ($riskScore < 35)  $grade = 'A';
    elseif ($riskScore < 50)  $grade = 'B';
    elseif ($riskScore < 65)  $grade = 'C';
    elseif ($riskScore < 80)  $grade = 'D';
    else                       $grade = 'F';

    $sevCount = ['Critical'=>0,'High'=>0,'Medium'=>0,'Low'=>0,'Info'=>0];
    foreach ($findings as $f) { $sev = $f['severity']??'Info'; if(isset($sevCount[$sev])) $sevCount[$sev]++; }

    // Recommendations
    $recs = [];
    foreach ($findings as $f) {
        if (!empty($f['recommendation']) && $f['recommendation'] !== 'No action needed' && !in_array($f['recommendation'],$recs))
            $recs[] = $f['recommendation'];
    }

    $p('Done!', 100);

    return [
        'findings'         => $findings,
        'recommendations'  => array_values($recs),
        'risk_score'       => $riskScore,
        'security_grade'   => $grade,
        'severity_summary' => $sevCount,
        'ai_analysis'      => $details['ai_analysis'] ?? null,
        'target'           => $url,
        'scan_type'        => $type,
        'timestamp'        => date('Y-m-d H:i:s'),
        'http_code'        => $httpCode,
        'response_size'    => strlen($body),
        'response_time'    => $responseTime,
        'total_findings'   => count($findings),
        'technologies'     => array_values($technologies),
        'server_info'      => $serverInfo,
        'subdomains'       => $details['subdomains'] ?? [],
        'ssl_days'         => $details['ssl_days'] ?? null,
        'ssl_issuer'       => $details['ssl_issuer'] ?? null,
        'headers_score'    => $details['headers_score'] ?? null,
    ];
}

function makeSecureRequest($url, $method='GET', $data=[], $extraHeaders=[], $timeout=15) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_TIMEOUT        => $timeout,
        CURLOPT_CONNECTTIMEOUT => min(8, $timeout),
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS      => 3,
        CURLOPT_HEADER         => true,
        CURLOPT_USERAGENT      => 'Mozilla/5.0 (Security-Scanner/4.0; +https://securityscanner.io)',
    ]);
    if ($method === 'POST') { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); }
    if (!empty($extraHeaders)) curl_setopt($ch, CURLOPT_HTTPHEADER, $extraHeaders);
    $t0 = microtime(true);
    $res = curl_exec($ch);
    $t1 = microtime(true);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $hs   = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
    $err  = curl_error($ch);
    curl_close($ch);
    if ($res === false) return ['headers'=>'','body'=>'','http_code'=>0,'error'=>$err,'time'=>0];
    return ['headers'=>substr($res,0,$hs),'body'=>substr($res,$hs),'http_code'=>$code,'error'=>$err,'time'=>round(($t1-$t0)*1000)];
}

function checkDetailedSSL($host) {
    $r = ['error'=>null,'days_remaining'=>0,'issuer'=>''];
    $ch = curl_init("https://{$host}");
    curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true,CURLOPT_SSL_VERIFYPEER=>true,CURLOPT_TIMEOUT=>10,CURLOPT_CERTINFO=>true,CURLOPT_NOBODY=>true]);
    curl_exec($ch);
    $info = curl_getinfo($ch, CURLINFO_CERTINFO);
    $err  = curl_error($ch);
    curl_close($ch);
    if ($err) { $r['error']=$err; return $r; }
    if (!empty($info)) {
        foreach ($info as $cert) {
            if (isset($cert['Expire date'])) $r['days_remaining'] = ceil((strtotime($cert['Expire date']) - time()) / 86400);
            if (isset($cert['Issuer'])) $r['issuer'] = $cert['Issuer'];
        }
    }
    return $r;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SENTINEL — Defense Platform</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=DM+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
<style>
:root {
    --bg:       #050508;
    --bg1:      #0c0c14;
    --bg2:      #12121e;
    --bg3:      #1a1a2a;
    --border:   rgba(255,255,255,0.06);
    --border2:  rgba(255,255,255,0.1);
    --text:     #d4d4e8;
    --muted:    #6b6b8a;
    --green:    #00ff88;
    --cyan:     #00cfff;
    --purple:   #a78bfa;
    --orange:   #ff8c42;
    --red:      #ff4757;
    --yellow:   #ffd32a;
    --pink:     #ff6b9d;
    --mono:     'Space Mono', monospace;
    --sans:     'DM Sans', sans-serif;
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{font-family:var(--sans);background:var(--bg);color:var(--text);min-height:100vh;overflow-x:hidden}

/* ── SCAN LINE BG ── */
body::before{content:'';position:fixed;inset:0;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,255,136,0.012) 2px,rgba(0,255,136,0.012) 4px);pointer-events:none;z-index:0}

.wrap{max-width:1600px;margin:0 auto;padding:20px 24px;position:relative;z-index:1}

/* ── NAV ── */
nav{display:flex;justify-content:space-between;align-items:center;padding:14px 22px;background:var(--bg1);border:1px solid var(--border);border-radius:10px;margin-bottom:28px;flex-wrap:wrap;gap:12px}
.nav-brand{font-family:var(--mono);font-size:14px;letter-spacing:2px;color:var(--green);display:flex;align-items:center;gap:10px}
.nav-brand .dot{width:8px;height:8px;border-radius:50%;background:var(--green);box-shadow:0 0 10px var(--green);animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.5;transform:scale(1.3)}}
.nav-links{display:flex;gap:4px;flex-wrap:wrap}
.nav-links a{color:var(--muted);text-decoration:none;padding:7px 14px;border-radius:6px;font-size:12px;font-weight:500;letter-spacing:.3px;transition:all .2s}
.nav-links a:hover{color:var(--text);background:var(--bg3)}
.nav-links a.active{color:var(--green);background:rgba(0,255,136,.08);border:1px solid rgba(0,255,136,.2)}
.nav-links a.danger{color:var(--red);background:rgba(255,71,87,.06)}
.nav-links a.danger:hover{background:rgba(255,71,87,.12)}

/* ── LAYOUT ── */
.main-grid{display:grid;grid-template-columns:400px 1fr;gap:24px;align-items:start}
@media(max-width:1100px){.main-grid{grid-template-columns:1fr}}

/* ── PANEL ── */
.panel{background:var(--bg1);border:1px solid var(--border);border-radius:12px;overflow:hidden}
.panel-head{padding:16px 20px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px}
.panel-head h3{font-family:var(--mono);font-size:11px;letter-spacing:2px;text-transform:uppercase;color:var(--green)}
.panel-body{padding:20px}
.panel + .panel{margin-top:20px}

/* ── FORM ── */
.form-field{margin-bottom:16px}
.form-field label{display:block;font-size:10px;font-family:var(--mono);letter-spacing:1.5px;color:var(--muted);margin-bottom:7px;text-transform:uppercase}
.form-field input{width:100%;padding:11px 14px;background:var(--bg2);border:1px solid var(--border2);border-radius:8px;color:var(--text);font-size:13px;font-family:var(--mono);transition:border .2s}
.form-field input:focus{outline:none;border-color:var(--green);box-shadow:0 0 0 3px rgba(0,255,136,.08)}
.form-field input::placeholder{color:var(--muted)}

/* ── SCAN TYPE GRID ── */
.scan-types{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:18px}
.scan-type-btn{padding:10px 12px;background:var(--bg2);border:1px solid var(--border);border-radius:8px;cursor:pointer;transition:all .2s;text-align:left}
.scan-type-btn:hover,.scan-type-btn.selected{border-color:var(--green);background:rgba(0,255,136,.05)}
.scan-type-btn input{display:none}
.scan-type-btn .st-name{font-size:11px;font-weight:600;color:var(--text);display:block;margin-bottom:2px}
.scan-type-btn .st-desc{font-size:9px;color:var(--muted);line-height:1.4}
.scan-type-btn .st-icon{font-size:16px;margin-bottom:4px;display:block}
.scan-type-btn.selected .st-name{color:var(--green)}

/* ── LAUNCH BTN ── */
.btn-launch{width:100%;padding:14px;background:linear-gradient(135deg,rgba(0,255,136,.15),rgba(0,207,255,.1));border:1px solid rgba(0,255,136,.4);border-radius:8px;color:var(--green);font-family:var(--mono);font-size:13px;letter-spacing:2px;font-weight:700;cursor:pointer;transition:all .3s;text-transform:uppercase;position:relative;overflow:hidden}
.btn-launch::before{content:'';position:absolute;inset:0;background:linear-gradient(135deg,rgba(0,255,136,.2),transparent);opacity:0;transition:opacity .3s}
.btn-launch:hover::before{opacity:1}
.btn-launch:hover{box-shadow:0 0 30px rgba(0,255,136,.2),0 0 60px rgba(0,255,136,.05);transform:translateY(-1px)}
.btn-launch:active{transform:translateY(0)}
.btn-launch:disabled{opacity:.4;cursor:not-allowed;transform:none}

/* ── PROGRESS ── */
#progress-wrap{display:none;margin-bottom:20px}
.progress-bar-outer{height:3px;background:var(--bg3);border-radius:2px;overflow:hidden}
.progress-bar-inner{height:100%;background:linear-gradient(90deg,var(--green),var(--cyan));border-radius:2px;transition:width .4s ease;width:0%}
.progress-label{font-family:var(--mono);font-size:10px;color:var(--cyan);margin-bottom:6px;letter-spacing:1px}
.progress-steps{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.step-item{font-size:9px;padding:3px 8px;background:var(--bg2);border:1px solid var(--border);border-radius:4px;color:var(--muted);transition:all .3s}
.step-item.active{border-color:var(--cyan);color:var(--cyan);background:rgba(0,207,255,.06)}
.step-item.done{border-color:rgba(0,255,136,.3);color:var(--green)}

/* ── RESULTS ── */
#results-wrap{display:none}

/* ── SCORE CARD ── */
.score-card{background:var(--bg2);border-radius:12px;padding:24px;margin-bottom:20px;position:relative;overflow:hidden}
.score-card::before{content:'';position:absolute;top:-40px;right:-40px;width:200px;height:200px;border-radius:50%;background:radial-gradient(circle,rgba(0,255,136,.08),transparent 70%);pointer-events:none}
.score-top{display:flex;align-items:center;gap:24px;margin-bottom:20px}
.score-ring{position:relative;width:110px;height:110px;flex-shrink:0}
.score-ring svg{transform:rotate(-90deg)}
.score-ring .ring-bg{fill:none;stroke:var(--bg3);stroke-width:8}
.score-ring .ring-fg{fill:none;stroke-width:8;stroke-linecap:round;transition:stroke-dashoffset 1.5s ease}
.score-center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.score-grade{font-family:var(--mono);font-size:28px;font-weight:700;line-height:1}
.score-num{font-family:var(--mono);font-size:11px;color:var(--muted)}
.score-info{flex:1}
.score-title{font-size:20px;font-weight:600;margin-bottom:4px}
.score-sub{font-size:12px;color:var(--muted)}
.score-meta{display:flex;gap:16px;flex-wrap:wrap}
.score-meta-item{font-size:11px;font-family:var(--mono);color:var(--muted)}
.score-meta-item span{color:var(--text)}

/* ── SEV STATS ── */
.sev-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin-bottom:20px}
@media(max-width:700px){.sev-grid{grid-template-columns:repeat(3,1fr)}}
.sev-card{background:var(--bg2);border-radius:8px;padding:12px;text-align:center;border:1px solid var(--border);position:relative;overflow:hidden}
.sev-card::after{content:'';position:absolute;bottom:0;left:0;right:0;height:2px}
.sev-card.crit::after{background:var(--red)}.sev-card.high::after{background:var(--orange)}
.sev-card.med::after{background:var(--yellow)}.sev-card.low::after{background:var(--cyan)}.sev-card.info::after{background:var(--green)}
.sev-num{font-family:var(--mono);font-size:24px;font-weight:700;line-height:1;display:block}
.sev-lbl{font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--muted);margin-top:3px;display:block}
.sev-card.crit .sev-num{color:var(--red)}.sev-card.high .sev-num{color:var(--orange)}
.sev-card.med .sev-num{color:var(--yellow)}.sev-card.low .sev-num{color:var(--cyan)}.sev-card.info .sev-num{color:var(--green)}

/* ── FILTERS ── */
.filter-bar{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px}
.filter-btn{padding:5px 12px;border-radius:20px;font-size:10px;font-family:var(--mono);letter-spacing:.8px;cursor:pointer;border:1px solid var(--border);background:var(--bg2);color:var(--muted);transition:all .2s}
.filter-btn:hover,.filter-btn.active{border-color:var(--green);color:var(--green);background:rgba(0,255,136,.06)}

/* ── FINDINGS ── */
.finding{border-left:3px solid;border-radius:0 8px 8px 0;padding:14px;margin-bottom:8px;background:var(--bg2);transition:background .2s;cursor:pointer}
.finding:hover{background:var(--bg3)}
.finding.sev-Critical{border-color:var(--red)}.finding.sev-High{border-color:var(--orange)}
.finding.sev-Medium{border-color:var(--yellow)}.finding.sev-Low{border-color:var(--cyan)}.finding.sev-Info{border-color:var(--green)}
.finding-top{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:6px}
.finding-name{font-weight:600;font-size:13px;color:var(--text)}
.finding-badges{display:flex;gap:6px;flex-shrink:0;flex-wrap:wrap}
.finding-detail{font-size:11px;color:var(--muted);margin-bottom:8px;line-height:1.5}
.finding-rec{font-size:11px;color:#86efac;padding:6px 10px;background:rgba(0,255,136,.04);border-radius:4px;border-left:2px solid rgba(0,255,136,.3);display:none}
.finding:hover .finding-rec,.finding.open .finding-rec{display:block}
.finding-url{font-size:10px;font-family:var(--mono);color:var(--cyan);margin-top:4px}

/* ── BADGES ── */
.badge{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:9px;font-weight:700;letter-spacing:.8px;text-transform:uppercase;font-family:var(--mono)}
.b-Critical{background:rgba(255,71,87,.15);color:#ff8fa3;border:1px solid rgba(255,71,87,.3)}
.b-High{background:rgba(255,140,66,.15);color:#ffb347;border:1px solid rgba(255,140,66,.3)}
.b-Medium{background:rgba(255,211,42,.15);color:#ffe066;border:1px solid rgba(255,211,42,.3)}
.b-Low{background:rgba(0,207,255,.15);color:#7dd3fc;border:1px solid rgba(0,207,255,.3)}
.b-Info{background:rgba(0,255,136,.1);color:#86efac;border:1px solid rgba(0,255,136,.2)}
.b-grade{padding:2px 7px;border-radius:4px;font-size:9px;font-family:var(--mono);font-weight:700}
.g-A{background:rgba(0,255,136,.1);color:var(--green)}.g-B{background:rgba(59,130,246,.15);color:#93c5fd}
.g-C{background:rgba(255,211,42,.12);color:#fde047}.g-D{background:rgba(255,140,66,.15);color:#fdba74}
.g-F{background:rgba(255,71,87,.15);color:#fca5a5}
.b-cat{font-size:9px;padding:2px 8px;border-radius:10px;background:var(--bg3);color:var(--muted);font-family:var(--mono);letter-spacing:.5px;border:1px solid var(--border)}

/* ── TECH TAGS ── */
.tech-tags{display:flex;flex-wrap:wrap;gap:5px;margin:10px 0}
.tech-tag{padding:3px 10px;border-radius:12px;font-size:10px;font-family:var(--mono);border:1px solid;letter-spacing:.5px}

/* ── AI BOX ── */
.ai-box{background:linear-gradient(135deg,rgba(167,139,250,.06),rgba(0,207,255,.04));border:1px solid rgba(167,139,250,.2);border-radius:10px;padding:20px;margin-top:20px}
.ai-box h4{font-family:var(--mono);font-size:10px;letter-spacing:2px;color:var(--purple);margin-bottom:12px}
.ai-content{font-size:12px;line-height:1.8;color:var(--text);white-space:pre-wrap}

/* ── HISTORY ── */
.history-item{padding:10px 14px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center;gap:10px;transition:background .15s}
.history-item:hover{background:var(--bg2)}
.history-item:last-child{border-bottom:none}
.hist-url{font-size:11px;font-family:var(--mono);color:var(--cyan);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:200px}
.hist-meta{font-size:10px;color:var(--muted)}
.hist-score{font-family:var(--mono);font-size:12px;font-weight:700;padding:2px 8px;border-radius:4px}
.s-good{background:rgba(0,255,136,.1);color:var(--green)}.s-med{background:rgba(255,211,42,.1);color:var(--yellow)}.s-bad{background:rgba(255,71,87,.1);color:var(--red)}

/* ── EXPORT ── */
.btn-export{padding:10px 18px;border-radius:6px;font-size:11px;font-family:var(--mono);letter-spacing:1px;font-weight:700;cursor:pointer;border:1px solid;transition:all .2s;text-decoration:none;display:inline-block}
.btn-export-green{border-color:rgba(0,255,136,.4);color:var(--green);background:rgba(0,255,136,.06)}
.btn-export-green:hover{background:rgba(0,255,136,.12);box-shadow:0 0 20px rgba(0,255,136,.1)}
.btn-export-blue{border-color:rgba(0,207,255,.4);color:var(--cyan);background:rgba(0,207,255,.06)}
.btn-export-blue:hover{background:rgba(0,207,255,.12)}

/* ── RADAR CHART ── */
.radar-wrap{display:flex;align-items:center;justify-content:center;padding:10px}

/* ── EMPTY STATE ── */
.empty-state{text-align:center;padding:60px 20px;color:var(--muted)}
.empty-icon{font-size:48px;margin-bottom:16px;opacity:.3}
.empty-text{font-family:var(--mono);font-size:12px;letter-spacing:1px}

/* ── TOAST ── */
#toast{position:fixed;bottom:24px;right:24px;background:var(--bg1);border:1px solid var(--green);border-radius:8px;padding:12px 18px;font-family:var(--mono);font-size:11px;color:var(--green);letter-spacing:.8px;transform:translateY(100px);transition:transform .3s;z-index:999}
#toast.show{transform:translateY(0)}

/* ── TABS ── */
.tabs{display:flex;gap:4px;border-bottom:1px solid var(--border);margin-bottom:16px;overflow-x:auto}
.tab{padding:10px 14px;font-size:11px;font-family:var(--mono);letter-spacing:.8px;cursor:pointer;color:var(--muted);border-bottom:2px solid transparent;margin-bottom:-1px;white-space:nowrap;transition:all .2s}
.tab:hover{color:var(--text)}
.tab.active{color:var(--green);border-bottom-color:var(--green)}
.tab-panel{display:none}.tab-panel.active{display:block}

/* ── TIMELINE ── */
.timeline{position:relative;padding-left:24px}
.timeline::before{content:'';position:absolute;left:8px;top:0;bottom:0;width:1px;background:var(--border)}
.tl-item{position:relative;margin-bottom:12px}
.tl-item::before{content:'';position:absolute;left:-20px;top:4px;width:8px;height:8px;border-radius:50%;background:var(--bg3);border:2px solid var(--muted)}
.tl-item.Critical::before{border-color:var(--red);background:rgba(255,71,87,.3)}
.tl-item.High::before{border-color:var(--orange);background:rgba(255,140,66,.3)}
.tl-item.Info::before,.tl-item.ok::before{border-color:var(--green);background:rgba(0,255,136,.3)}
.tl-name{font-size:11px;font-weight:600;color:var(--text)}
.tl-rec{font-size:10px;color:var(--muted);margin-top:2px;line-height:1.5}

/* ── RESPONSIVE ── */
@media(max-width:700px){.sev-grid{grid-template-columns:repeat(2,1fr)}.scan-types{grid-template-columns:1fr}.score-top{flex-direction:column}}

/* ── ANIM ── */
@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
.fade-in{animation:fadeIn .4s ease forwards}
@keyframes scanLine{from{transform:translateY(-100%)}to{transform:translateY(100vh)}}
</style>
</head>
<body>
<div class="wrap">

<!-- ── NAV ── -->
<nav>
    <div class="nav-brand">
        <span class="dot"></span>
        SENTINEL // DEFENSE
    </div>
    <div class="nav-links">
        <a href="index.php">Dashboard</a>
        <a href="attack.php">Attack</a>
        <a href="defense.php" class="active">Defense</a>
        <a href="malware_analysis.php">Malware</a>
        <a href="cupp.php">CUPP</a>
        <a href="reports.php">Reports</a>
        <a href="index.php?logout=1" class="danger">Logout</a>
    </div>
</nav>

<div class="main-grid">

    <!-- ── LEFT COLUMN ── -->
    <div>
        <!-- SCAN FORM -->
        <div class="panel">
            <div class="panel-head">
                <span style="color:var(--green)">◈</span>
                <h3>Security Assessment</h3>
            </div>
            <div class="panel-body">
                <div class="form-field">
                    <label>Target URL</label>
                    <input type="text" id="target_url" placeholder="https://example.com" autocomplete="off">
                </div>
                <div class="form-field">
                    <label>Assessment Module</label>
                </div>
                <div class="scan-types" id="scanTypes">
                    <?php foreach($defenseTypes as $key => $d): ?>
                    <label class="scan-type-btn <?php echo $key==='full_scan'?'selected':''; ?>">
                        <input type="radio" name="defense_type" value="<?php echo $key; ?>" <?php echo $key==='full_scan'?'checked':''; ?>>
                        <span class="st-name"><?php echo htmlspecialchars($d['name']); ?></span>
                        <span class="st-desc"><?php echo htmlspecialchars($d['desc']); ?></span>
                    </label>
                    <?php endforeach; ?>
                </div>

                <!-- PROGRESS -->
                <div id="progress-wrap">
                    <div class="progress-label" id="progress-label">Initializing...</div>
                    <div class="progress-bar-outer">
                        <div class="progress-bar-inner" id="progress-bar"></div>
                    </div>
                    <div class="progress-steps" id="progress-steps">
                        <?php $steps = ['Resolve','Headers','SSL','Exposure','Cookies','CORS','DNS','WAF','Subdomains','AI']; foreach($steps as $s): ?>
                        <div class="step-item" data-step="<?php echo $s; ?>"><?php echo $s; ?></div>
                        <?php endforeach; ?>
                    </div>
                </div>

                <button class="btn-launch" id="launchBtn" onclick="runScan()">
                    ▶&nbsp; LAUNCH ASSESSMENT
                </button>
            </div>
        </div>

        <!-- HISTORY -->
        <?php if(!empty($defenseHistory)): ?>
        <div class="panel" style="margin-top:20px">
            <div class="panel-head">
                <span style="color:var(--cyan)">◈</span>
                <h3>Scan History</h3>
            </div>
            <div>
                <?php foreach(array_slice($defenseHistory,0,8) as $h):
                    $sc = intval($h['risk_score']);
                    $cls = $sc < 40 ? 's-good' : ($sc < 70 ? 's-med' : 's-bad');
                ?>
                <div class="history-item">
                    <div>
                        <div class="hist-url"><?php echo htmlspecialchars(substr($h['target_url'],0,35)); ?></div>
                        <div class="hist-meta"><?php echo htmlspecialchars($h['defense_type']); ?> · <?php echo date('M d H:i',strtotime($h['timestamp'])); ?></div>
                    </div>
                    <div class="hist-score <?php echo $cls; ?>"><?php echo $sc; ?></div>
                </div>
                <?php endforeach; ?>
            </div>
        </div>
        <?php endif; ?>
    </div>

    <!-- ── RIGHT COLUMN ── -->
    <div>
        <!-- EMPTY STATE -->
        <div id="empty-state" class="panel">
            <div class="panel-body empty-state">
                <div class="empty-icon">⬡</div>
                <div class="empty-text">AWAITING TARGET</div>
                <div style="font-size:11px;color:var(--muted);margin-top:8px">Enter a URL and launch an assessment</div>
            </div>
        </div>

        <!-- RESULTS -->
        <div id="results-wrap">
            <!-- SCORE CARD -->
            <div class="panel score-card" id="score-card" style="padding:24px">
                <div class="score-top">
                    <div class="score-ring">
                        <svg width="110" height="110" viewBox="0 0 110 110">
                            <circle class="ring-bg" cx="55" cy="55" r="46"/>
                            <circle class="ring-fg" id="ring-fg" cx="55" cy="55" r="46" stroke-dasharray="289" stroke-dashoffset="289"/>
                        </svg>
                        <div class="score-center">
                            <div class="score-grade" id="score-grade">-</div>
                            <div class="score-num" id="score-num">-/100</div>
                        </div>
                    </div>
                    <div class="score-info">
                        <div class="score-title" id="score-title">-</div>
                        <div class="score-sub" id="score-sub">-</div>
                        <div class="tech-tags" id="tech-tags"></div>
                        <div class="score-meta" id="score-meta"></div>
                    </div>
                </div>
                <div class="sev-grid" id="sev-grid"></div>
                <div style="display:flex;gap:10px;flex-wrap:wrap" id="export-btns">
                    <button class="btn-export btn-export-green" onclick="exportJSON()">↓ Export JSON</button>
                    <button class="btn-export btn-export-blue" onclick="exportCSV()">↓ Export CSV</button>
                    <button class="btn-export btn-export-green" onclick="window.print()">⎙ Print Report</button>
                </div>
            </div>

            <!-- FINDINGS TABS -->
            <div class="panel" style="margin-top:20px">
                <div class="panel-head">
                    <span style="color:var(--orange)">◈</span>
                    <h3>Findings & Analysis</h3>
                </div>
                <div class="panel-body">
                    <div class="tabs">
                        <div class="tab active" onclick="showTab('all')">All Findings</div>
                        <div class="tab" onclick="showTab('critical')">Critical/High</div>
                        <div class="tab" onclick="showTab('recs')">Remediation</div>
                        <div class="tab" onclick="showTab('ai')">AI Analysis</div>
                        <div class="tab" onclick="showTab('timeline')">Timeline</div>
                    </div>

                    <!-- ALL FINDINGS -->
                    <div class="tab-panel active" id="tab-all">
                        <div class="filter-bar" id="filter-bar">
                            <div class="filter-btn active" onclick="filterFindings('all',this)">ALL</div>
                            <div class="filter-btn" onclick="filterFindings('Critical',this)">CRITICAL</div>
                            <div class="filter-btn" onclick="filterFindings('High',this)">HIGH</div>
                            <div class="filter-btn" onclick="filterFindings('Medium',this)">MEDIUM</div>
                            <div class="filter-btn" onclick="filterFindings('Low',this)">LOW</div>
                            <div class="filter-btn" onclick="filterFindings('Info',this)">INFO</div>
                        </div>
                        <div id="findings-list"></div>
                    </div>

                    <!-- CRITICAL/HIGH ONLY -->
                    <div class="tab-panel" id="tab-critical">
                        <div id="critical-list"></div>
                    </div>

                    <!-- RECOMMENDATIONS -->
                    <div class="tab-panel" id="tab-recs">
                        <div id="recs-list"></div>
                    </div>

                    <!-- AI -->
                    <div class="tab-panel" id="tab-ai">
                        <div id="ai-content"></div>
                    </div>

                    <!-- TIMELINE -->
                    <div class="tab-panel" id="tab-timeline">
                        <div class="timeline" id="timeline-list"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</div>

<div id="toast">✓ Copied to clipboard</div>

<script>
let scanData = null;

// ── SCAN TYPE SELECTION ──
document.querySelectorAll('.scan-type-btn').forEach(btn => {
    btn.addEventListener('click', () => {
        document.querySelectorAll('.scan-type-btn').forEach(b => b.classList.remove('selected'));
        btn.classList.add('selected');
    });
});

// ── RUN SCAN via SSE ──
function runScan() {
    const url = document.getElementById('target_url').value.trim();
    const type = document.querySelector('input[name="defense_type"]:checked')?.value || 'full_scan';
    if (!url) { showToast('⚠ Enter a target URL'); return; }

    const btn = document.getElementById('launchBtn');
    btn.disabled = true;
    btn.textContent = '◌  SCANNING...';

    document.getElementById('empty-state').style.display = 'none';
    document.getElementById('results-wrap').style.display = 'none';
    const pw = document.getElementById('progress-wrap');
    pw.style.display = 'block';
    resetProgress();

    const evtSrc = new EventSource(`defense.php?stream=1&url=${encodeURIComponent(url)}&type=${encodeURIComponent(type)}`);

    evtSrc.addEventListener('status', e => {
        const d = JSON.parse(e.data);
        updateProgress(d.msg, d.pct);
    });

    evtSrc.addEventListener('result', e => {
        scanData = JSON.parse(e.data);
        renderResults(scanData);
    });

    evtSrc.addEventListener('done', e => {
        evtSrc.close();
        pw.style.display = 'none';
        document.getElementById('results-wrap').style.display = 'block';
        btn.disabled = false;
        btn.innerHTML = '▶&nbsp; LAUNCH ASSESSMENT';
        document.getElementById('results-wrap').scrollIntoView({behavior:'smooth'});
        showToast('✓ Assessment complete');
    });

    evtSrc.onerror = () => {
        evtSrc.close();
        btn.disabled = false;
        btn.innerHTML = '▶&nbsp; LAUNCH ASSESSMENT';
        pw.style.display = 'none';
        showToast('✗ Scan error — check connectivity');
    };
}

function resetProgress() {
    document.getElementById('progress-bar').style.width = '0%';
    document.getElementById('progress-label').textContent = 'Initializing...';
    document.querySelectorAll('.step-item').forEach(s => s.className = 'step-item');
}

function updateProgress(msg, pct) {
    document.getElementById('progress-bar').style.width = pct + '%';
    document.getElementById('progress-label').textContent = msg;
    // Activate steps
    const map = {'Resolve':5,'Headers':18,'SSL':32,'Exposure':44,'Cookies':58,'CORS':65,'DNS':70,'WAF':76,'Subdomains':82,'AI':92};
    document.querySelectorAll('.step-item').forEach(s => {
        const threshold = map[s.dataset.step] || 999;
        if (pct >= threshold + 10) s.className = 'step-item done';
        else if (pct >= threshold) s.className = 'step-item active';
    });
}

// ── RENDER RESULTS ──
function renderResults(data) {
    // Score ring
    const score = data.risk_score;
    const grade = data.security_grade;
    const circumference = 289;
    const offset = circumference - (score / 100 * circumference);
    const ringEl = document.getElementById('ring-fg');
    const color = score < 35 ? '#00ff88' : score < 60 ? '#ffd32a' : score < 80 ? '#ff8c42' : '#ff4757';
    ringEl.style.stroke = color;
    setTimeout(() => { ringEl.style.strokeDashoffset = offset; }, 100);

    document.getElementById('score-grade').textContent = grade;
    document.getElementById('score-grade').style.color = color;
    document.getElementById('score-num').textContent = score + '/100';
    document.getElementById('score-title').textContent = score < 35 ? 'Strong Security Posture' : score < 60 ? 'Moderate Risk Detected' : score < 80 ? 'Significant Vulnerabilities' : 'Critical Security Risk';
    document.getElementById('score-title').style.color = color;
    document.getElementById('score-sub').textContent = `${data.total_findings} findings · ${data.scan_type} · ${data.timestamp}`;

    // Tech tags
    const techColors = ['var(--cyan)','var(--purple)','var(--green)','var(--orange)','var(--pink)'];
    const tagEl = document.getElementById('tech-tags');
    tagEl.innerHTML = data.technologies.map((t,i) =>
        `<span class="tech-tag" style="color:${techColors[i%techColors.length]};border-color:${techColors[i%techColors.length]}33">${t}</span>`
    ).join('');

    // Meta
    document.getElementById('score-meta').innerHTML = `
        <span class="score-meta-item">HTTP <span>${data.http_code}</span></span>
        <span class="score-meta-item">Response <span>${data.response_time}ms</span></span>
        <span class="score-meta-item">Size <span>${(data.response_size/1024).toFixed(1)}KB</span></span>
        ${data.ssl_days ? `<span class="score-meta-item">SSL <span>${data.ssl_days}d</span></span>` : ''}
    `;

    // Severity grid
    const ss = data.severity_summary;
    document.getElementById('sev-grid').innerHTML = `
        <div class="sev-card crit"><span class="sev-num">${ss.Critical||0}</span><span class="sev-lbl">Critical</span></div>
        <div class="sev-card high"><span class="sev-num">${ss.High||0}</span><span class="sev-lbl">High</span></div>
        <div class="sev-card med"><span class="sev-num">${ss.Medium||0}</span><span class="sev-lbl">Medium</span></div>
        <div class="sev-card low"><span class="sev-num">${ss.Low||0}</span><span class="sev-lbl">Low</span></div>
        <div class="sev-card info"><span class="sev-num">${ss.Info||0}</span><span class="sev-lbl">Info</span></div>
    `;

    // Findings
    renderFindings(data.findings);

    // Critical tab
    const criticals = data.findings.filter(f => f.severity==='Critical'||f.severity==='High');
    document.getElementById('critical-list').innerHTML = criticals.length
        ? criticals.map(f => findingHTML(f)).join('')
        : '<div style="text-align:center;padding:40px;color:var(--green);font-family:var(--mono);font-size:12px">✓ No critical or high severity findings</div>';

    // Recommendations
    const recs = data.recommendations.filter(Boolean);
    document.getElementById('recs-list').innerHTML = recs.length
        ? recs.map((r,i) => `
            <div class="finding" style="border-color:var(--cyan);margin-bottom:8px" onclick="this.classList.toggle('open')">
                <div class="finding-top">
                    <span class="finding-name">${i+1}. Remediation Action</span>
                    <span class="badge b-Info">ACTION</span>
                </div>
                <div class="finding-rec" style="display:block">${escHtml(r)}</div>
            </div>`).join('')
        : '<div style="text-align:center;padding:40px;color:var(--muted)">No recommendations</div>';

    // AI
    if (data.ai_analysis) {
        document.getElementById('ai-content').innerHTML = `
            <div class="ai-box">
                <h4>◈ AI SECURITY ANALYSIS</h4>
                <div class="ai-content">${escHtml(data.ai_analysis)}</div>
            </div>`;
    } else {
        document.getElementById('ai-content').innerHTML = `<div style="text-align:center;padding:40px;color:var(--muted);font-size:12px">AI analysis not available for this scan type</div>`;
    }

    // Timeline
    const timeline = data.findings.filter(f=>f.severity!=='Info'&&f.status!=='OK').slice(0,20);
    document.getElementById('timeline-list').innerHTML = timeline.map(f => `
        <div class="tl-item ${f.severity}">
            <div class="tl-name">${escHtml(f.type)}</div>
            <div class="tl-rec">${escHtml(f.recommendation||'')}</div>
        </div>`).join('') || '<div style="color:var(--muted);font-size:12px;padding:20px">No actionable findings</div>';

    // Animate in
    document.querySelectorAll('.panel').forEach((p,i) => {
        p.style.opacity = '0';
        p.style.transform = 'translateY(10px)';
        setTimeout(() => {
            p.style.transition = 'all .3s ease';
            p.style.opacity = '1';
            p.style.transform = 'translateY(0)';
        }, i*60);
    });
}

function renderFindings(findings, filter='all') {
    const filtered = filter==='all' ? findings : findings.filter(f=>f.severity===filter);
    document.getElementById('findings-list').innerHTML = filtered.map(f=>findingHTML(f)).join('');
}

function findingHTML(f) {
    const sev = f.severity || 'Info';
    const grade = f.grade || 'A';
    const gc = grade.startsWith('A') ? 'g-A' : grade.startsWith('B') ? 'g-B' : grade.startsWith('C') ? 'g-C' : grade.startsWith('D') ? 'g-D' : 'g-F';
    return `<div class="finding sev-${sev}" onclick="this.classList.toggle('open')">
        <div class="finding-top">
            <span class="finding-name">${escHtml(f.type)}</span>
            <span class="finding-badges">
                ${f.category?`<span class="b-cat">${escHtml(f.category)}</span>`:''}
                <span class="badge b-${sev}">${sev}</span>
                ${grade&&grade!=='N/A'?`<span class="b-grade ${gc}">${grade}</span>`:''}
            </span>
        </div>
        <div class="finding-detail">${escHtml(f.detail||'')}</div>
        ${f.url?`<div class="finding-url">⚑ ${escHtml(f.url)}</div>`:''}
        ${f.recommendation&&f.recommendation!=='No action needed'?`<div class="finding-rec">💡 ${escHtml(f.recommendation)}</div>`:''}
    </div>`;
}

function filterFindings(val, btn) {
    document.querySelectorAll('.filter-btn').forEach(b=>b.classList.remove('active'));
    btn.classList.add('active');
    if (scanData) renderFindings(scanData.findings, val);
}

// ── TABS ──
function showTab(name) {
    document.querySelectorAll('.tab').forEach(t=>t.classList.remove('active'));
    document.querySelectorAll('.tab-panel').forEach(p=>p.classList.remove('active'));
    event.target.classList.add('active');
    document.getElementById('tab-'+name).classList.add('active');
}

// ── EXPORT ──
function exportJSON() {
    if (!scanData) return;
    const blob = new Blob([JSON.stringify(scanData,null,2)],{type:'application/json'});
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = 'security-report-'+(new Date().toISOString().slice(0,10))+'.json';
    a.click();
}

function exportCSV() {
    if (!scanData) return;
    const rows = [['Category','Type','Severity','Grade','Detail','Recommendation','Status']];
    scanData.findings.forEach(f => {
        rows.push([f.category||'',f.type||'',f.severity||'',f.grade||'',f.detail||'',f.recommendation||'',f.status||'']);
    });
    const csv = rows.map(r=>r.map(c=>'"'+String(c).replace(/"/g,'""')+'"').join(',')).join('\n');
    const blob = new Blob([csv],{type:'text/csv'});
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = 'security-report-'+(new Date().toISOString().slice(0,10))+'.csv';
    a.click();
}

// ── HELPERS ──
function escHtml(str) {
    return String(str||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}
function showToast(msg) {
    const t = document.getElementById('toast');
    t.textContent = msg;
    t.classList.add('show');
    setTimeout(()=>t.classList.remove('show'),3000);
}

// Enter key shortcut
document.getElementById('target_url').addEventListener('keydown', e => {
    if (e.key === 'Enter') runScan();
});
</script>
</body>
</html>