import { useState } from 'react';
import { useQuery, useMutation } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { auditLogApi, AuditLogSearchParams } from '../../services/api';
import type { AuditLog, AuditAction, AuditSensitivity } from '../../types';
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 { ArrowLeft, Download, Eye, Shield, ShieldCheck, ShieldAlert, RefreshCw, ChevronLeft, ChevronRight, X } from 'lucide-react';

const ACTION_OPTIONS = [
  { value: '', label: 'Alle Aktionen' },
  { value: 'CREATE', label: 'Erstellt' },
  { value: 'READ', label: 'Gelesen' },
  { value: 'UPDATE', label: 'Aktualisiert' },
  { value: 'DELETE', label: 'Gelöscht' },
  { value: 'EXPORT', label: 'Exportiert' },
  { value: 'ANONYMIZE', label: 'Anonymisiert' },
  { value: 'LOGIN', label: 'Login' },
  { value: 'LOGOUT', label: 'Logout' },
  { value: 'LOGIN_FAILED', label: 'Login fehlgeschlagen' },
];

const SENSITIVITY_OPTIONS = [
  { value: '', label: 'Alle Stufen' },
  { value: 'LOW', label: 'Niedrig' },
  { value: 'MEDIUM', label: 'Mittel' },
  { value: 'HIGH', label: 'Hoch' },
  { value: 'CRITICAL', label: 'Kritisch' },
];

const RESOURCE_OPTIONS = [
  { value: '', label: 'Alle Ressourcen' },
  { value: 'Customer', label: 'Kunden' },
  { value: 'Contract', label: 'Verträge' },
  { value: 'User', label: 'Benutzer' },
  { value: 'BankCard', label: 'Bankdaten' },
  { value: 'IdentityDocument', label: 'Ausweisdokumente' },
  { value: 'Authentication', label: 'Authentifizierung' },
  { value: 'CustomerConsent', label: 'Einwilligungen' },
  { value: 'GDPR', label: 'DSGVO' },
];

function formatDate(date: string): string {
  return new Date(date).toLocaleString('de-DE', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
}

function getActionColor(action: AuditAction): string {
  switch (action) {
    case 'CREATE': return 'bg-green-100 text-green-800';
    case 'READ': return 'bg-blue-100 text-blue-800';
    case 'UPDATE': return 'bg-yellow-100 text-yellow-800';
    case 'DELETE': return 'bg-red-100 text-red-800';
    case 'EXPORT': return 'bg-purple-100 text-purple-800';
    case 'ANONYMIZE': return 'bg-orange-100 text-orange-800';
    case 'LOGIN': return 'bg-teal-100 text-teal-800';
    case 'LOGOUT': return 'bg-gray-100 text-gray-800';
    case 'LOGIN_FAILED': return 'bg-red-200 text-red-900';
    default: return 'bg-gray-100 text-gray-800';
  }
}

function getSensitivityIcon(sensitivity: AuditSensitivity) {
  switch (sensitivity) {
    case 'LOW': return <Shield className="w-4 h-4 text-gray-400" />;
    case 'MEDIUM': return <Shield className="w-4 h-4 text-blue-500" />;
    case 'HIGH': return <ShieldAlert className="w-4 h-4 text-orange-500" />;
    case 'CRITICAL': return <ShieldAlert className="w-4 h-4 text-red-500" />;
    default: return <Shield className="w-4 h-4 text-gray-400" />;
  }
}

interface DetailModalProps {
  log: AuditLog;
  onClose: () => void;
}

function DetailModal({ log, onClose }: DetailModalProps) {
  const parseChanges = (changes: string | undefined): Record<string, unknown> | null => {
    if (!changes) return null;
    try {
      return JSON.parse(changes);
    } catch {
      return null;
    }
  };

  const before = parseChanges(log.changesBefore);
  const after = parseChanges(log.changesAfter);

  return (
    <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
      <div className="bg-white rounded-lg shadow-xl w-full max-w-3xl mx-4 max-h-[90vh] overflow-y-auto">
        <div className="p-6">
          <div className="flex items-center justify-between mb-4">
            <h2 className="text-xl font-semibold">Audit-Log Details</h2>
            <button onClick={onClose} className="text-gray-400 hover:text-gray-600">
              <X className="w-5 h-5" />
            </button>
          </div>

          <div className="grid grid-cols-2 gap-4 mb-6">
            <div>
              <dt className="text-sm text-gray-500">Zeitpunkt</dt>
              <dd className="font-medium">{formatDate(log.createdAt)}</dd>
            </div>
            <div>
              <dt className="text-sm text-gray-500">Benutzer</dt>
              <dd className="font-medium">{log.userEmail}</dd>
            </div>
            <div>
              <dt className="text-sm text-gray-500">Aktion</dt>
              <dd><span className={`px-2 py-1 rounded text-xs font-medium ${getActionColor(log.action)}`}>{log.action}</span></dd>
            </div>
            <div>
              <dt className="text-sm text-gray-500">Ressource</dt>
              <dd className="font-medium">{log.resourceType} {log.resourceId && `#${log.resourceId}`}</dd>
            </div>
            <div>
              <dt className="text-sm text-gray-500">Endpoint</dt>
              <dd className="font-mono text-sm">{log.httpMethod} {log.endpoint}</dd>
            </div>
            <div>
              <dt className="text-sm text-gray-500">IP-Adresse</dt>
              <dd className="font-mono text-sm">{log.ipAddress}</dd>
            </div>
            <div>
              <dt className="text-sm text-gray-500">Sensitivität</dt>
              <dd className="flex items-center gap-2">{getSensitivityIcon(log.sensitivity)} {log.sensitivity}</dd>
            </div>
            <div>
              <dt className="text-sm text-gray-500">Dauer</dt>
              <dd>{log.durationMs ? `${log.durationMs}ms` : '-'}</dd>
            </div>
            {log.resourceLabel && (
              <div className="col-span-2">
                <dt className="text-sm text-gray-500">Ressource-Bezeichnung</dt>
                <dd className="font-medium">{log.resourceLabel}</dd>
              </div>
            )}
          </div>

          {log.changesEncrypted && (
            <div className="mb-4 p-3 bg-yellow-50 text-yellow-800 rounded-lg text-sm">
              Die Änderungsdaten sind verschlüsselt und können nur mit dem Encryption-Key eingesehen werden.
            </div>
          )}

          {(before || after) && !log.changesEncrypted && (
            <div className="border-t pt-4">
              <h3 className="font-medium mb-3">Änderungen</h3>
              <div className="grid grid-cols-2 gap-4">
                {before && (
                  <div>
                    <h4 className="text-sm font-medium text-gray-500 mb-2">Vorher</h4>
                    <pre className="bg-gray-50 p-3 rounded text-xs overflow-auto max-h-64">
                      {JSON.stringify(before, null, 2)}
                    </pre>
                  </div>
                )}
                {after && (
                  <div>
                    <h4 className="text-sm font-medium text-gray-500 mb-2">Nachher</h4>
                    <pre className="bg-gray-50 p-3 rounded text-xs overflow-auto max-h-64">
                      {JSON.stringify(after, null, 2)}
                    </pre>
                  </div>
                )}
              </div>
            </div>
          )}

          {log.hash && (
            <div className="border-t pt-4 mt-4">
              <h3 className="font-medium mb-2">Integrität</h3>
              <div className="text-xs font-mono bg-gray-50 p-2 rounded break-all">
                <div><span className="text-gray-500">Hash:</span> {log.hash}</div>
                {log.previousHash && <div className="mt-1"><span className="text-gray-500">Vorheriger:</span> {log.previousHash}</div>}
              </div>
            </div>
          )}

          <div className="flex justify-end mt-6 pt-4 border-t">
            <Button variant="secondary" onClick={onClose}>Schließen</Button>
          </div>
        </div>
      </div>
    </div>
  );
}

export default function AuditLogs() {
  const navigate = useNavigate();
  const [page, setPage] = useState(1);
  const [filters, setFilters] = useState<AuditLogSearchParams>({
    page: 1,
    limit: 50,
  });
  const [selectedLog, setSelectedLog] = useState<AuditLog | null>(null);

  const { data: logsData, isLoading, refetch } = useQuery({
    queryKey: ['audit-logs', { ...filters, page }],
    queryFn: () => auditLogApi.search({ ...filters, page }),
  });

  const verifyMutation = useMutation({
    mutationFn: () => auditLogApi.verifyIntegrity(),
    onSuccess: (result) => {
      if (result.data?.valid) {
        alert('Hash-Kette ist intakt. Keine Manipulationen festgestellt.');
      } else {
        alert(`Integritätsfehler gefunden:\n${result.data?.errors?.join('\n')}`);
      }
    },
    onError: (error) => {
      alert(`Fehler bei der Integritätsprüfung: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}`);
    },
  });

  const logs = logsData?.data || [];
  const pagination = logsData?.pagination;

  const handleFilterChange = (key: keyof AuditLogSearchParams, value: string) => {
    setFilters(prev => ({ ...prev, [key]: value || undefined }));
    setPage(1);
  };

  const handleExport = async (format: 'json' | 'csv') => {
    try {
      const result = await auditLogApi.export({ ...filters, format });
      const data = result.data;
      const blob = new Blob(
        [format === 'json' ? JSON.stringify(data, null, 2) : ''],
        { type: format === 'json' ? 'application/json' : 'text/csv' }
      );
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `audit-logs-${new Date().toISOString().split('T')[0]}.${format}`;
      a.click();
      URL.revokeObjectURL(url);
    } catch (error) {
      alert(`Export fehlgeschlagen: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}`);
    }
  };

  return (
    <div>
      <div className="flex items-center gap-4 mb-6">
        <Button variant="ghost" onClick={() => navigate('/settings')}>
          <ArrowLeft className="w-4 h-4 mr-2" />
          Zurück
        </Button>
        <h1 className="text-2xl font-bold">Audit-Protokoll</h1>
      </div>

      {/* Filter */}
      <Card className="mb-6">
        <div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-4">
          <Input
            placeholder="Suche..."
            value={filters.search || ''}
            onChange={(e) => handleFilterChange('search', e.target.value)}
            className="w-full"
          />
          <Select
            value={filters.action || ''}
            onChange={(e) => handleFilterChange('action', e.target.value)}
            options={ACTION_OPTIONS}
          />
          <Select
            value={filters.resourceType || ''}
            onChange={(e) => handleFilterChange('resourceType', e.target.value)}
            options={RESOURCE_OPTIONS}
          />
          <Select
            value={filters.sensitivity || ''}
            onChange={(e) => handleFilterChange('sensitivity', e.target.value as AuditSensitivity)}
            options={SENSITIVITY_OPTIONS}
          />
        </div>
        <div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-4">
          <Input
            type="date"
            label="Von"
            value={filters.startDate || ''}
            onChange={(e) => handleFilterChange('startDate', e.target.value)}
          />
          <Input
            type="date"
            label="Bis"
            value={filters.endDate || ''}
            onChange={(e) => handleFilterChange('endDate', e.target.value)}
          />
          <div></div>
          <div className="flex gap-2 justify-end items-end">
            <Button variant="secondary" onClick={() => refetch()}>
              <RefreshCw className="w-4 h-4 mr-2" />
              Aktualisieren
            </Button>
            <Button variant="secondary" onClick={() => handleExport('json')}>
              <Download className="w-4 h-4 mr-2" />
              Export
            </Button>
            <Button variant="secondary" onClick={() => verifyMutation.mutate()} disabled={verifyMutation.isPending}>
              <ShieldCheck className="w-4 h-4 mr-2" />
              {verifyMutation.isPending ? 'Prüfe...' : 'Integrität'}
            </Button>
          </div>
        </div>
      </Card>

      {/* Tabelle */}
      <Card>
        {isLoading ? (
          <div className="text-center py-8">Laden...</div>
        ) : logs.length === 0 ? (
          <div className="text-center py-8 text-gray-500">Keine Audit-Logs gefunden.</div>
        ) : (
          <>
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b">
                    <th className="text-left py-3 px-4">Zeitpunkt</th>
                    <th className="text-left py-3 px-4">Benutzer</th>
                    <th className="text-left py-3 px-4">Aktion</th>
                    <th className="text-left py-3 px-4">Ressource</th>
                    <th className="text-left py-3 px-4">IP</th>
                    <th className="text-center py-3 px-4"></th>
                    <th className="text-center py-3 px-4"></th>
                  </tr>
                </thead>
                <tbody>
                  {logs.map((log) => (
                    <tr key={log.id} className="border-b hover:bg-gray-50">
                      <td className="py-3 px-4 whitespace-nowrap">{formatDate(log.createdAt)}</td>
                      <td className="py-3 px-4">
                        <div className="truncate max-w-[200px]" title={log.userEmail}>
                          {log.userEmail}
                        </div>
                        {log.userRole && <div className="text-xs text-gray-500">{log.userRole}</div>}
                      </td>
                      <td className="py-3 px-4">
                        <span className={`px-2 py-1 rounded text-xs font-medium ${getActionColor(log.action)}`}>
                          {log.action}
                        </span>
                      </td>
                      <td className="py-3 px-4">
                        <div>{log.resourceType}</div>
                        {log.resourceLabel && (
                          <div className="text-xs text-gray-500 truncate max-w-[200px]" title={log.resourceLabel}>
                            {log.resourceLabel}
                          </div>
                        )}
                      </td>
                      <td className="py-3 px-4 font-mono text-xs">{log.ipAddress}</td>
                      <td className="py-3 px-4 text-center">{getSensitivityIcon(log.sensitivity)}</td>
                      <td className="py-3 px-4 text-center">
                        <Button variant="ghost" size="sm" onClick={() => setSelectedLog(log)}>
                          <Eye className="w-4 h-4" />
                        </Button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>

            {/* Pagination */}
            {pagination && pagination.totalPages > 1 && (
              <div className="flex items-center justify-between mt-4 pt-4 border-t">
                <div className="text-sm text-gray-500">
                  Seite {pagination.page} von {pagination.totalPages} ({pagination.total} Einträge)
                </div>
                <div className="flex gap-2">
                  <Button
                    variant="secondary"
                    size="sm"
                    onClick={() => setPage(p => Math.max(1, p - 1))}
                    disabled={page === 1}
                  >
                    <ChevronLeft className="w-4 h-4" />
                  </Button>
                  <Button
                    variant="secondary"
                    size="sm"
                    onClick={() => setPage(p => Math.min(pagination.totalPages, p + 1))}
                    disabled={page === pagination.totalPages}
                  >
                    <ChevronRight className="w-4 h-4" />
                  </Button>
                </div>
              </div>
            )}
          </>
        )}
      </Card>

      {/* Detail Modal */}
      {selectedLog && (
        <DetailModal log={selectedLog} onClose={() => setSelectedLog(null)} />
      )}
    </div>
  );
}
