'use client';

import { useState, useEffect, useCallback } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
  Shield, ShieldAlert, ShieldCheck, AlertTriangle, CheckCircle, XCircle,
  RefreshCw, Clock, FileSearch, Bug, ChevronDown, ChevronRight,
  Loader2, Database, Scan, Activity, Eye, Lock, Zap,
} from 'lucide-react';

interface DashboardStats {
  lastScanAt: string | null;
  lastScanStatus: string;
  lastScanSummary: string;
  openFindings: {
    critical: number;
    high: number;
    medium: number;
    low: number;
    total: number;
  };
  recentScans: Array<{
    id: string;
    createdAt: string;
    findingsCount: number;
    criticalCount: number;
    highCount: number;
  }>;
  threatDatabase: {
    totalCategories: number;
    totalPatterns: number;
    critical: number;
    high: number;
    medium: number;
    low: number;
    version: string;
    lastUpdated: string;
  };
}

interface ScanRecord {
  id: string;
  scanType: string;
  target: string;
  status: string;
  findingsCount: number;
  criticalCount: number;
  highCount: number;
  mediumCount: number;
  lowCount: number;
  summary: string;
  createdAt: string;
  completedAt: string | null;
  _count: { findings: number };
}

interface Finding {
  id: string;
  filePath: string;
  lineNumber: number | null;
  codeSnippet: string | null;
  vulnerability: string;
  severity: string;
  confidence: number;
  status: string;
  remediation: string | null;
  createdAt: string;
}

const severityConfig: Record<string, { color: string; bg: string; icon: typeof ShieldAlert }> = {
  critical: { color: 'text-red-400', bg: 'bg-red-500/20 border-red-500/30', icon: XCircle },
  high: { color: 'text-orange-400', bg: 'bg-orange-500/20 border-orange-500/30', icon: AlertTriangle },
  medium: { color: 'text-yellow-400', bg: 'bg-yellow-500/20 border-yellow-500/30', icon: Bug },
  low: { color: 'text-blue-400', bg: 'bg-blue-500/20 border-blue-500/30', icon: Eye },
};

export default function SentinelPage() {
  const [stats, setStats] = useState<DashboardStats | null>(null);
  const [scans, setScans] = useState<ScanRecord[]>([]);
  const [findings, setFindings] = useState<Finding[]>([]);
  const [selectedScan, setSelectedScan] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [scanning, setScanning] = useState(false);
  const [syncing, setSyncing] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const fetchStats = useCallback(async () => {
    try {
      const res = await fetch('/api/dark-factory/sentinel');
      if (res.ok) {
        const data = await res.json();
        setStats(data);
      }
    } catch (e) {
      console.error('Failed to fetch sentinel stats:', e);
    }
  }, []);

  const fetchScans = useCallback(async () => {
    try {
      const res = await fetch('/api/dark-factory/sentinel/scans?limit=10');
      if (res.ok) {
        const data = await res.json();
        setScans(data);
      }
    } catch (e) {
      console.error('Failed to fetch scans:', e);
    }
  }, []);

  const fetchFindings = useCallback(async (scanId: string) => {
    try {
      const res = await fetch(`/api/dark-factory/sentinel/findings?scanId=${scanId}`);
      if (res.ok) {
        const data = await res.json();
        setFindings(data);
      }
    } catch (e) {
      console.error('Failed to fetch findings:', e);
    }
  }, []);

  useEffect(() => {
    Promise.all([fetchStats(), fetchScans()]).finally(() => setLoading(false));
  }, [fetchStats, fetchScans]);

  const runScan = async () => {
    setScanning(true);
    setError(null);
    try {
      const res = await fetch('/api/dark-factory/sentinel', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ target: 'all' }),
      });
      if (res.ok) {
        await Promise.all([fetchStats(), fetchScans()]);
      } else {
        setError('Scan failed');
      }
    } catch {
      setError('Network error during scan');
    } finally {
      setScanning(false);
    }
  };

  const syncThreatDb = async () => {
    setSyncing(true);
    try {
      await fetch('/api/dark-factory/sentinel/sync', { method: 'POST' });
      await fetchStats();
    } catch {
      setError('Threat DB sync failed');
    } finally {
      setSyncing(false);
    }
  };

  const handleFindingAction = async (findingId: string, action: 'remediate' | 'false_positive') => {
    try {
      await fetch('/api/dark-factory/sentinel/findings', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ findingId, action }),
      });
      if (selectedScan) await fetchFindings(selectedScan);
      await fetchStats();
    } catch {
      setError('Failed to update finding');
    }
  };

  if (loading) {
    return (
      <div className="min-h-screen bg-brand-bg flex items-center justify-center">
        <Loader2 className="w-8 h-8 text-brand animate-spin" />
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-brand-bg p-6">
      <div className="max-w-7xl mx-auto space-y-6">
        {/* Header */}
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <div className="p-3 rounded-xl bg-red-500/20 border border-red-500/30">
              <Shield className="w-7 h-7 text-red-400" />
            </div>
            <div>
              <h1 className="text-2xl font-bold text-white">The Hearth Sentinel</h1>
              <p className="text-sm text-gray-400">OWASP Threat Monitor &middot; Code Security Scanner</p>
            </div>
          </div>
          <div className="flex items-center gap-3">
            <button
              onClick={syncThreatDb}
              disabled={syncing}
              className="flex items-center gap-2 px-4 py-2 text-sm bg-white/5 hover:bg-white/10 border border-white/10 rounded-lg text-gray-300 transition-colors disabled:opacity-50"
            >
              {syncing ? <Loader2 className="w-4 h-4 animate-spin" /> : <Database className="w-4 h-4" />}
              Sync Threat DB
            </button>
            <button
              onClick={runScan}
              disabled={scanning}
              className="flex items-center gap-2 px-4 py-2 text-sm bg-red-500/20 hover:bg-red-500/30 border border-red-500/30 rounded-lg text-red-300 font-medium transition-colors disabled:opacity-50"
            >
              {scanning ? <Loader2 className="w-4 h-4 animate-spin" /> : <Scan className="w-4 h-4" />}
              {scanning ? 'Scanning...' : 'Run OWASP Scan'}
            </button>
          </div>
        </div>

        {error && (
          <div className="p-3 bg-red-500/10 border border-red-500/30 rounded-lg text-red-300 text-sm">
            {error}
          </div>
        )}

        {/* Security Posture Cards */}
        <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
          {/* Open Findings */}
          <motion.div
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            className="glass-card p-5 rounded-xl border border-white/10"
          >
            <div className="flex items-center gap-2 mb-3">
              <ShieldAlert className="w-5 h-5 text-red-400" />
              <span className="text-sm text-gray-400">Open Findings</span>
            </div>
            <div className="text-3xl font-bold text-white mb-2">
              {stats?.openFindings.total || 0}
            </div>
            <div className="flex items-center gap-3 text-xs">
              <span className="text-red-400">{stats?.openFindings.critical || 0} critical</span>
              <span className="text-orange-400">{stats?.openFindings.high || 0} high</span>
              <span className="text-yellow-400">{stats?.openFindings.medium || 0} med</span>
            </div>
          </motion.div>

          {/* Last Scan */}
          <motion.div
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ delay: 0.05 }}
            className="glass-card p-5 rounded-xl border border-white/10"
          >
            <div className="flex items-center gap-2 mb-3">
              <Clock className="w-5 h-5 text-sky-400" />
              <span className="text-sm text-gray-400">Last Scan</span>
            </div>
            <div className="text-lg font-semibold text-white mb-1">
              {stats?.lastScanAt
                ? new Date(stats.lastScanAt).toLocaleDateString()
                : 'Never'}
            </div>
            <div className="text-xs text-gray-500">
              {stats?.lastScanStatus === 'completed' ? (
                <span className="text-green-400 flex items-center gap-1">
                  <CheckCircle className="w-3 h-3" /> Passed
                </span>
              ) : stats?.lastScanAt ? (
                <span className="text-yellow-400">{stats.lastScanStatus}</span>
              ) : (
                'No scans yet'
              )}
            </div>
          </motion.div>

          {/* Threat DB */}
          <motion.div
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ delay: 0.1 }}
            className="glass-card p-5 rounded-xl border border-white/10"
          >
            <div className="flex items-center gap-2 mb-3">
              <Database className="w-5 h-5 text-orange-400" />
              <span className="text-sm text-gray-400">Threat Database</span>
            </div>
            <div className="text-lg font-semibold text-white mb-1">
              {stats?.threatDatabase.totalPatterns || 0} patterns
            </div>
            <div className="text-xs text-gray-500">
              {stats?.threatDatabase.version || 'OWASP Top 10'}
            </div>
          </motion.div>

          {/* Security Score */}
          <motion.div
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ delay: 0.15 }}
            className="glass-card p-5 rounded-xl border border-white/10"
          >
            <div className="flex items-center gap-2 mb-3">
              <ShieldCheck className="w-5 h-5 text-green-400" />
              <span className="text-sm text-gray-400">Posture</span>
            </div>
            <div className="text-lg font-semibold mb-1">
              {(stats?.openFindings.critical || 0) === 0 && (stats?.openFindings.high || 0) === 0 ? (
                <span className="text-green-400">Secure</span>
              ) : (stats?.openFindings.critical || 0) > 0 ? (
                <span className="text-red-400">Critical</span>
              ) : (
                <span className="text-yellow-400">Needs Attention</span>
              )}
            </div>
            <div className="text-xs text-gray-500">
              {(stats?.openFindings.critical || 0) === 0
                ? 'No critical vulnerabilities'
                : `${stats?.openFindings.critical} critical issues`}
            </div>
          </motion.div>
        </div>

        {/* OWASP Coverage */}
        <motion.div
          initial={{ opacity: 0, y: 10 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.2 }}
          className="glass-card p-6 rounded-xl border border-white/10"
        >
          <h2 className="text-lg font-semibold text-white mb-4 flex items-center gap-2">
            <Lock className="w-5 h-5 text-red-400" />
            OWASP Top 10 Coverage (2021)
          </h2>
          <div className="grid grid-cols-2 md:grid-cols-5 gap-3">
            {[
              { id: 'A01', name: 'Broken Access Control', icon: Lock },
              { id: 'A02', name: 'Cryptographic Failures', icon: Lock },
              { id: 'A03', name: 'Injection', icon: Zap },
              { id: 'A04', name: 'Insecure Design', icon: AlertTriangle },
              { id: 'A05', name: 'Security Misconfig', icon: Bug },
              { id: 'A06', name: 'Vulnerable Components', icon: AlertTriangle },
              { id: 'A07', name: 'Auth Failures', icon: Lock },
              { id: 'A08', name: 'Data Integrity', icon: Shield },
              { id: 'A09', name: 'Logging Failures', icon: Activity },
              { id: 'A10', name: 'SSRF', icon: Zap },
            ].map(cat => {
              const CatIcon = cat.icon;
              return (
                <div key={cat.id} className="p-3 bg-white/5 rounded-lg border border-white/5">
                  <div className="flex items-center gap-2 mb-1">
                    <CatIcon className="w-3.5 h-3.5 text-red-400" />
                    <span className="text-xs font-mono text-gray-500">{cat.id}</span>
                  </div>
                  <p className="text-xs text-gray-300 leading-tight">{cat.name}</p>
                  <div className="mt-1">
                    <span className="text-[10px] text-green-400 bg-green-500/10 px-1.5 py-0.5 rounded">monitored</span>
                  </div>
                </div>
              );
            })}
          </div>
        </motion.div>

        {/* Scan History */}
        <motion.div
          initial={{ opacity: 0, y: 10 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.25 }}
          className="glass-card p-6 rounded-xl border border-white/10"
        >
          <h2 className="text-lg font-semibold text-white mb-4 flex items-center gap-2">
            <FileSearch className="w-5 h-5 text-sky-400" />
            Scan History
          </h2>
          {scans.length === 0 ? (
            <div className="text-center py-8">
              <Scan className="w-12 h-12 text-gray-600 mx-auto mb-3" />
              <p className="text-gray-400">No scans yet</p>
              <p className="text-sm text-gray-500 mt-1">Run your first OWASP scan to see results here</p>
            </div>
          ) : (
            <div className="space-y-2">
              {scans.map(scan => (
                <div key={scan.id}>
                  <button
                    onClick={() => {
                      if (selectedScan === scan.id) {
                        setSelectedScan(null);
                        setFindings([]);
                      } else {
                        setSelectedScan(scan.id);
                        fetchFindings(scan.id);
                      }
                    }}
                    className="w-full flex items-center justify-between p-3 bg-white/5 hover:bg-white/10 rounded-lg border border-white/5 transition-colors text-left"
                  >
                    <div className="flex items-center gap-3">
                      {scan.status === 'completed' ? (
                        scan.criticalCount > 0 ? (
                          <XCircle className="w-5 h-5 text-red-400" />
                        ) : scan.highCount > 0 ? (
                          <AlertTriangle className="w-5 h-5 text-orange-400" />
                        ) : (
                          <CheckCircle className="w-5 h-5 text-green-400" />
                        )
                      ) : (
                        <Loader2 className="w-5 h-5 text-gray-400 animate-spin" />
                      )}
                      <div>
                        <div className="text-sm text-white">
                          {scan.scanType} scan &middot; {scan.target}
                        </div>
                        <div className="text-xs text-gray-500">
                          {new Date(scan.createdAt).toLocaleString()}
                        </div>
                      </div>
                    </div>
                    <div className="flex items-center gap-4">
                      <div className="flex items-center gap-2 text-xs">
                        {scan.criticalCount > 0 && <span className="text-red-400">{scan.criticalCount}C</span>}
                        {scan.highCount > 0 && <span className="text-orange-400">{scan.highCount}H</span>}
                        {scan.mediumCount > 0 && <span className="text-yellow-400">{scan.mediumCount}M</span>}
                        {scan.lowCount > 0 && <span className="text-blue-400">{scan.lowCount}L</span>}
                        {scan.findingsCount === 0 && <span className="text-green-400">Clean</span>}
                      </div>
                      {selectedScan === scan.id ? (
                        <ChevronDown className="w-4 h-4 text-gray-500" />
                      ) : (
                        <ChevronRight className="w-4 h-4 text-gray-500" />
                      )}
                    </div>
                  </button>

                  {/* Findings Dropdown */}
                  <AnimatePresence>
                    {selectedScan === scan.id && (
                      <motion.div
                        initial={{ height: 0, opacity: 0 }}
                        animate={{ height: 'auto', opacity: 1 }}
                        exit={{ height: 0, opacity: 0 }}
                        className="overflow-hidden"
                      >
                        <div className="p-3 space-y-2 border-l-2 border-red-500/20 ml-6 mt-1">
                          {scan.summary && (
                            <p className="text-xs text-gray-400 mb-3">{scan.summary}</p>
                          )}
                          {findings.length === 0 ? (
                            <p className="text-sm text-gray-500 py-2">No findings for this scan</p>
                          ) : (
                            findings.map(finding => {
                              const sev = severityConfig[finding.severity] || severityConfig.medium;
                              const SevIcon = sev.icon;
                              return (
                                <div
                                  key={finding.id}
                                  className={`p-3 rounded-lg border ${sev.bg}`}
                                >
                                  <div className="flex items-start justify-between gap-3">
                                    <div className="flex items-start gap-2 flex-1">
                                      <SevIcon className={`w-4 h-4 mt-0.5 ${sev.color}`} />
                                      <div>
                                        <div className="text-sm font-medium text-white">
                                          {finding.vulnerability}
                                        </div>
                                        <div className="text-xs text-gray-400 mt-1">
                                          {finding.filePath}
                                          {finding.lineNumber && `:${finding.lineNumber}`}
                                        </div>
                                        {finding.codeSnippet && (
                                          <code className="block mt-2 text-xs text-gray-300 bg-black/30 p-2 rounded font-mono overflow-x-auto">
                                            {finding.codeSnippet}
                                          </code>
                                        )}
                                        {finding.remediation && (
                                          <p className="text-xs text-green-400/80 mt-2">
                                            → {finding.remediation}
                                          </p>
                                        )}
                                      </div>
                                    </div>
                                    {finding.status === 'open' && (
                                      <div className="flex items-center gap-1 shrink-0">
                                        <button
                                          onClick={() => handleFindingAction(finding.id, 'remediate')}
                                          className="p-1.5 text-green-400 hover:bg-green-500/20 rounded transition-colors"
                                          title="Mark as remediated"
                                        >
                                          <CheckCircle className="w-4 h-4" />
                                        </button>
                                        <button
                                          onClick={() => handleFindingAction(finding.id, 'false_positive')}
                                          className="p-1.5 text-gray-400 hover:bg-white/10 rounded transition-colors"
                                          title="Mark as false positive"
                                        >
                                          <XCircle className="w-4 h-4" />
                                        </button>
                                      </div>
                                    )}
                                    {finding.status !== 'open' && (
                                      <span className={`text-xs px-2 py-0.5 rounded ${
                                        finding.status === 'remediated'
                                          ? 'bg-green-500/20 text-green-400'
                                          : 'bg-gray-500/20 text-gray-400'
                                      }`}>
                                        {finding.status}
                                      </span>
                                    )}
                                  </div>
                                </div>
                              );
                            })
                          )}
                        </div>
                      </motion.div>
                    )}
                  </AnimatePresence>
                </div>
              ))}
            </div>
          )}
        </motion.div>
      </div>
    </div>
  );
}
