import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import toast from 'react-hot-toast';
import { monitoringApi, type SecurityEventType, type SecuritySeverity } from '../../services/api';
import Card from '../../components/ui/Card';
import Button from '../../components/ui/Button';
import Input from '../../components/ui/Input';
import Select from '../../components/ui/Select';
import Modal from '../../components/ui/Modal';
import { ArrowLeft, Send, RefreshCw, Mail, ShieldAlert, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Trash2 } from 'lucide-react';

/**
 * Liefert die anzuzeigenden Seitenzahlen für die Pagination.
 * Bis zu 10 Seitenzahlen, current möglichst mittig.
 */
function paginationWindow(current: number, total: number, size = 10): number[] {
  if (total <= size) return Array.from({ length: total }, (_, i) => i + 1);
  let start = Math.max(1, current - Math.floor(size / 2));
  let end = start + size - 1;
  if (end > total) {
    end = total;
    start = end - size + 1;
  }
  return Array.from({ length: end - start + 1 }, (_, i) => start + i);
}

const TYPE_OPTIONS: { value: SecurityEventType | ''; label: string }[] = [
  { value: '', label: 'Alle Typen' },
  { value: 'LOGIN_FAILED', label: 'Login fehlgeschlagen' },
  { value: 'LOGIN_SUCCESS', label: 'Login erfolgreich' },
  { value: 'RATE_LIMIT_HIT', label: 'Rate-Limit greift' },
  { value: 'ACCESS_DENIED', label: 'Zugriff verweigert (IDOR)' },
  { value: 'SSRF_BLOCKED', label: 'SSRF blockiert' },
  { value: 'PASSWORD_RESET_REQUEST', label: 'Passwort-Reset angefordert' },
  { value: 'PASSWORD_RESET_CONFIRM', label: 'Passwort-Reset bestätigt' },
  { value: 'LOGOUT', label: 'Logout' },
  { value: 'TOKEN_REJECTED', label: 'Token abgelehnt' },
  { value: 'PERMISSION_CHANGED', label: 'Berechtigung geändert' },
  { value: 'AUDIT_SEAL_CHANGED', label: 'Bestandssiegel gesetzt/ersetzt' },
  { value: 'SUSPICIOUS', label: 'Verdächtig (Threshold)' },
];

const SEVERITY_OPTIONS: { value: SecuritySeverity | ''; label: string }[] = [
  { value: '', label: 'Alle Stufen' },
  { value: 'INFO', label: 'Info' },
  { value: 'LOW', label: 'Niedrig' },
  { value: 'MEDIUM', label: 'Mittel' },
  { value: 'HIGH', label: 'Hoch' },
  { value: 'CRITICAL', label: 'Kritisch' },
];

function severityClass(s: SecuritySeverity): string {
  switch (s) {
    case 'CRITICAL': return 'bg-red-100 text-red-800 border border-red-300';
    case 'HIGH': return 'bg-orange-100 text-orange-800 border border-orange-300';
    case 'MEDIUM': return 'bg-yellow-100 text-yellow-800 border border-yellow-300';
    case 'LOW': return 'bg-blue-100 text-blue-800 border border-blue-300';
    default: return 'bg-gray-100 text-gray-700 border border-gray-300';
  }
}

function severityIcon(s: SecuritySeverity): string {
  switch (s) {
    case 'CRITICAL': return '🚨';
    case 'HIGH': return '⚠️';
    case 'MEDIUM': return '🟡';
    case 'LOW': return '🟢';
    default: return 'ℹ️';
  }
}

export default function Monitoring() {
  const navigate = useNavigate();
  const queryClient = useQueryClient();

  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(50);
  const [filters, setFilters] = useState({
    type: '' as SecurityEventType | '',
    severity: '' as SecuritySeverity | '',
    search: '',
    ip: '',
  });
  const [showClearConfirm, setShowClearConfirm] = useState(false);
  const [clearOlderThanDays, setClearOlderThanDays] = useState<number | ''>('');

  const [alertEmail, setAlertEmail] = useState('');
  const [digestEnabled, setDigestEnabled] = useState(false);

  // Settings laden
  const { data: settingsData } = useQuery({
    queryKey: ['monitoring-settings'],
    queryFn: monitoringApi.getSettings,
  });

  // States nach Laden synchronisieren (nur initial)
  if (settingsData?.data && alertEmail === '' && settingsData.data.alertEmail !== '') {
    setAlertEmail(settingsData.data.alertEmail);
    setDigestEnabled(settingsData.data.digestEnabled);
  }

  // Events laden
  const { data: eventsData, isLoading: eventsLoading } = useQuery({
    queryKey: ['monitoring-events', page, pageSize, filters],
    queryFn: () => monitoringApi.getEvents({ page, limit: pageSize, ...filters }),
    refetchInterval: 30_000,  // alle 30s neu laden
  });

  const clearEvents = useMutation({
    mutationFn: (olderThanDays?: number) => monitoringApi.clearEvents(olderThanDays),
    onSuccess: (res) => {
      toast.success(res.message || 'Events gelöscht');
      setShowClearConfirm(false);
      setClearOlderThanDays('');
      queryClient.invalidateQueries({ queryKey: ['monitoring-events'] });
    },
    onError: (e: Error) => toast.error(e.message || 'Löschen fehlgeschlagen'),
  });

  const saveSettings = useMutation({
    mutationFn: () => monitoringApi.updateSettings({ alertEmail, digestEnabled }),
    onSuccess: () => {
      toast.success('Einstellungen gespeichert');
      queryClient.invalidateQueries({ queryKey: ['monitoring-settings'] });
    },
    onError: (e: Error) => toast.error(e.message || 'Speichern fehlgeschlagen'),
  });

  const testAlert = useMutation({
    mutationFn: () => monitoringApi.testAlert(),
    onSuccess: (res) => toast.success(res.message || 'Test-Alert versendet'),
    onError: (e: Error) => toast.error(e.message || 'Test fehlgeschlagen'),
  });

  const runDigest = useMutation({
    mutationFn: () => monitoringApi.runDigest(),
    onSuccess: (res) => {
      const r = res.data;
      if (r?.sent) toast.success(`Digest mit ${r.eventCount} Events versendet`);
      else toast(r?.reason || 'Kein Digest versendet', { icon: 'ℹ️' });
    },
    onError: (e: Error) => toast.error(e.message || 'Digest fehlgeschlagen'),
  });

  const events = eventsData?.data || [];
  const stats = eventsData?.stats;
  const pagination = eventsData?.pagination;

  return (
    <div className="container mx-auto px-4 py-6 max-w-7xl">
      <div className="mb-6">
        <Button variant="ghost" onClick={() => navigate('/settings')} className="mb-2">
          <ArrowLeft className="w-4 h-4 mr-1" /> Zurück zu Einstellungen
        </Button>
        <h1 className="text-2xl font-bold flex items-center gap-2">
          <ShieldAlert className="w-6 h-6 text-orange-500" /> Sicherheits-Monitoring
        </h1>
        <p className="text-gray-600 text-sm mt-1">
          Sicherheitsrelevante Ereignisse + Alert-Einstellungen.
        </p>
      </div>

      {/* Settings */}
      <Card className="mb-6">
        <h2 className="text-lg font-semibold mb-3 flex items-center gap-2">
          <Mail className="w-5 h-5" /> Alert-Empfänger
        </h2>
        <div className="grid sm:grid-cols-2 gap-4 mb-4">
          <div>
            <Input
              label="E-Mail-Adresse für Alerts"
              type="email"
              value={alertEmail}
              onChange={(e) => setAlertEmail(e.target.value)}
              placeholder="security@deine-firma.de"
            />
            <p className="text-xs text-gray-500 mt-1">Leer lassen, um Alerts zu deaktivieren.</p>
          </div>
          <div className="flex items-end gap-3">
            <label className="flex items-center gap-2 mb-2">
              <input
                type="checkbox"
                checked={digestEnabled}
                onChange={(e) => setDigestEnabled(e.target.checked)}
                className="w-4 h-4"
              />
              <span className="text-sm">Stündlicher Digest (HIGH+MEDIUM Events)</span>
            </label>
          </div>
        </div>
        <div className="flex gap-3 flex-wrap">
          <Button onClick={() => saveSettings.mutate()} disabled={saveSettings.isPending}>
            Speichern
          </Button>
          <Button variant="secondary" onClick={() => testAlert.mutate()} disabled={!alertEmail || testAlert.isPending}>
            <Send className="w-4 h-4 mr-1" /> Test-Alert senden
          </Button>
          <Button variant="secondary" onClick={() => runDigest.mutate()} disabled={!alertEmail || runDigest.isPending}>
            <RefreshCw className="w-4 h-4 mr-1" /> Digest jetzt ausführen
          </Button>
          {settingsData?.data?.lastDigestAt && (
            <span className="text-xs text-gray-500 self-center">
              Letzter Digest: {new Date(settingsData.data.lastDigestAt).toLocaleString('de-DE')}
            </span>
          )}
        </div>
        <div className="mt-3 text-xs text-gray-600">
          <strong>Sofort-Alert:</strong> CRITICAL-Events (z.B. Brute-Force-Verdacht) werden binnen 1 Minute per
          E-Mail versendet.<br />
          <strong>Digest:</strong> HIGH+MEDIUM-Events werden zur vollen Stunde gesammelt verschickt (wenn aktiviert).
        </div>
      </Card>

      {/* Stats-Cards */}
      {stats && (
        <div className="grid grid-cols-2 md:grid-cols-5 gap-3 mb-6">
          {(['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO'] as SecuritySeverity[]).map((sev) => (
            <Card key={sev}>
              <div className={`text-xs font-semibold ${severityClass(sev).split(' ').filter((c) => c.startsWith('text-'))[0]}`}>
                {severityIcon(sev)} {sev}
              </div>
              <div className="text-2xl font-bold mt-1">{stats.bySeverity[sev] || 0}</div>
            </Card>
          ))}
        </div>
      )}

      {/* Filter */}
      <Card className="mb-4">
        <div className="grid sm:grid-cols-4 gap-3">
          <Select
            label="Typ"
            value={filters.type}
            onChange={(e) => { setFilters((f) => ({ ...f, type: e.target.value as any })); setPage(1); }}
            options={TYPE_OPTIONS}
          />
          <Select
            label="Severity"
            value={filters.severity}
            onChange={(e) => { setFilters((f) => ({ ...f, severity: e.target.value as any })); setPage(1); }}
            options={SEVERITY_OPTIONS}
          />
          <Input
            label="Suche (Nachricht/User/Endpoint)"
            value={filters.search}
            onChange={(e) => { setFilters((f) => ({ ...f, search: e.target.value })); setPage(1); }}
            placeholder="z.B. admin@admin.com"
          />
          <Input
            label="IP-Adresse"
            value={filters.ip}
            onChange={(e) => { setFilters((f) => ({ ...f, ip: e.target.value })); setPage(1); }}
            placeholder="z.B. 1.2.3.4"
          />
        </div>
      </Card>

      {/* Tabelle */}
      <Card>
        <div className="flex items-center justify-between mb-3 flex-wrap gap-2">
          <h2 className="text-lg font-semibold">Events</h2>
          <div className="flex items-center gap-2">
            <label className="text-sm text-gray-600">Pro Seite:</label>
            <select
              value={pageSize}
              onChange={(e) => { setPageSize(parseInt(e.target.value)); setPage(1); }}
              className="px-2 py-1 border border-gray-300 rounded text-sm"
            >
              <option value={10}>10</option>
              <option value={25}>25</option>
              <option value={50}>50</option>
              <option value={100}>100</option>
              <option value={200}>200</option>
            </select>
            <Button
              variant="secondary"
              size="sm"
              onClick={() => queryClient.invalidateQueries({ queryKey: ['monitoring-events'] })}
              disabled={eventsLoading}
              title="Events jetzt neu laden. Auto-Refresh läuft sonst alle 30 s im Hintergrund."
            >
              <RefreshCw className={`w-4 h-4 mr-1 ${eventsLoading ? 'animate-spin' : ''}`} />
              Aktualisieren
            </Button>
            <Button variant="secondary" size="sm" onClick={() => setShowClearConfirm(true)}>
              <Trash2 className="w-4 h-4 mr-1" /> Log leeren
            </Button>
          </div>
        </div>
        {eventsLoading ? (
          <div className="text-gray-500 py-4">Lade…</div>
        ) : events.length === 0 ? (
          <div className="text-gray-500 py-8 text-center">Keine Events für diese Filter.</div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead className="bg-gray-50 text-left">
                <tr>
                  <th className="px-3 py-2 whitespace-nowrap">Zeit</th>
                  <th className="px-3 py-2">Severity</th>
                  <th className="px-3 py-2">Typ</th>
                  <th className="px-3 py-2">Nachricht</th>
                  <th className="px-3 py-2">Wer</th>
                  <th className="px-3 py-2">IP</th>
                  <th className="px-3 py-2">Endpoint</th>
                  <th className="px-3 py-2">Alert</th>
                </tr>
              </thead>
              <tbody>
                {events.map((e) => (
                  <tr key={e.id} className="border-t hover:bg-gray-50">
                    <td className="px-3 py-2 font-mono text-xs whitespace-nowrap">
                      {new Date(e.createdAt).toLocaleString('de-DE', { dateStyle: 'short', timeStyle: 'medium' })}
                    </td>
                    <td className="px-3 py-2">
                      <span className={`inline-block px-2 py-0.5 rounded text-xs font-semibold ${severityClass(e.severity)}`}>
                        {severityIcon(e.severity)} {e.severity}
                      </span>
                    </td>
                    <td className="px-3 py-2 font-mono text-xs">{e.type}</td>
                    <td className="px-3 py-2">{e.message}</td>
                    <td className="px-3 py-2 text-xs">{e.userEmail || (e.userId ? `User #${e.userId}` : e.customerId ? `Kunde #${e.customerId}` : '–')}</td>
                    <td className="px-3 py-2 font-mono text-xs">{e.ipAddress || '–'}</td>
                    <td className="px-3 py-2 font-mono text-xs">{e.endpoint || '–'}</td>
                    <td className="px-3 py-2 text-xs">{e.alerted ? '✉️ ja' : '–'}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
        {pagination && pagination.totalPages > 1 && (
          <div className="flex flex-wrap items-center justify-between gap-3 mt-4 text-sm">
            <span className="text-gray-600">
              Seite {pagination.page} von {pagination.totalPages} ({pagination.total} Einträge)
            </span>
            <div className="flex items-center gap-1">
              <button
                onClick={() => setPage(1)}
                disabled={page <= 1}
                title="Erste Seite"
                className="px-2 py-1 rounded border border-gray-300 disabled:opacity-40 hover:bg-gray-100"
              >
                <ChevronsLeft className="w-4 h-4" />
              </button>
              <button
                onClick={() => setPage((p) => Math.max(1, p - 1))}
                disabled={page <= 1}
                title="Vorherige Seite"
                className="px-2 py-1 rounded border border-gray-300 disabled:opacity-40 hover:bg-gray-100"
              >
                <ChevronLeft className="w-4 h-4" />
              </button>
              {paginationWindow(page, pagination.totalPages, 10).map((p) => (
                <button
                  key={p}
                  onClick={() => setPage(p)}
                  className={`min-w-[32px] px-2 py-1 rounded border text-sm ${
                    p === page
                      ? 'bg-blue-600 text-white border-blue-600'
                      : 'border-gray-300 hover:bg-gray-100'
                  }`}
                >
                  {p}
                </button>
              ))}
              <button
                onClick={() => setPage((p) => Math.min(pagination.totalPages, p + 1))}
                disabled={page >= pagination.totalPages}
                title="Nächste Seite"
                className="px-2 py-1 rounded border border-gray-300 disabled:opacity-40 hover:bg-gray-100"
              >
                <ChevronRight className="w-4 h-4" />
              </button>
              <button
                onClick={() => setPage(pagination.totalPages)}
                disabled={page >= pagination.totalPages}
                title="Letzte Seite"
                className="px-2 py-1 rounded border border-gray-300 disabled:opacity-40 hover:bg-gray-100"
              >
                <ChevronsRight className="w-4 h-4" />
              </button>
            </div>
          </div>
        )}
      </Card>

      {/* Clear-Confirm-Modal */}
      <Modal
        isOpen={showClearConfirm}
        onClose={() => setShowClearConfirm(false)}
        title="Security-Log leeren"
        size="sm"
      >
        <div className="space-y-4">
          <p className="text-sm text-gray-700">
            Sicher? Alle Events werden aus der Datenbank entfernt. Ein
            Audit-Log-Eintrag mit deinem Namen bleibt erhalten.
          </p>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">
              Nur Events älter als (Tage)
            </label>
            <input
              type="number"
              min="0"
              value={clearOlderThanDays}
              onChange={(e) => setClearOlderThanDays(e.target.value === '' ? '' : parseInt(e.target.value))}
              placeholder="leer = alle löschen"
              className="block w-full max-w-[200px] px-3 py-2 border border-gray-300 rounded text-sm"
            />
            <p className="text-xs text-gray-500 mt-1">
              Beispiel: 30 = nur Events älter als 30 Tage löschen.
            </p>
          </div>
          <div className="flex justify-end gap-2 pt-2">
            <Button variant="secondary" onClick={() => setShowClearConfirm(false)}>
              Abbrechen
            </Button>
            <Button
              onClick={() => clearEvents.mutate(clearOlderThanDays === '' ? undefined : Number(clearOlderThanDays))}
              disabled={clearEvents.isPending}
              className="!bg-red-600 hover:!bg-red-700"
            >
              <Trash2 className="w-4 h-4 mr-1" />
              {clearOlderThanDays === '' ? 'Alle löschen' : `Älter als ${clearOlderThanDays} Tage löschen`}
            </Button>
          </div>
        </div>
      </Modal>
    </div>
  );
}
