import { useState, useRef } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Database, Download, Upload, Trash2, RefreshCw, HardDrive, Clock, FileText, FolderOpen, Archive, AlertTriangle, Bomb } from 'lucide-react';
import { backupApi, BackupInfo, getAccessToken } from '../../services/api';
import { useAuth } from '../../context/AuthContext';
import Button from '../../components/ui/Button';

export default function DatabaseBackup() {
  const [showRestoreConfirm, setShowRestoreConfirm] = useState<string | null>(null);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState<string | null>(null);
  const [showFactoryResetConfirm, setShowFactoryResetConfirm] = useState(false);
  const [factoryResetConfirmText, setFactoryResetConfirmText] = useState('');
  const [uploadError, setUploadError] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const queryClient = useQueryClient();
  const { logout } = useAuth();

  // Backups laden
  const { data: backupsData, isLoading } = useQuery({
    queryKey: ['backups'],
    queryFn: () => backupApi.list(),
  });

  const backups = backupsData?.data || [];

  // Backup erstellen
  const createMutation = useMutation({
    mutationFn: () => backupApi.create(),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['backups'] });
    },
  });

  // Backup wiederherstellen
  const restoreMutation = useMutation({
    mutationFn: (name: string) => backupApi.restore(name),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['backups'] });
      setShowRestoreConfirm(null);
    },
  });

  // Backup löschen
  const deleteMutation = useMutation({
    mutationFn: (name: string) => backupApi.delete(name),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['backups'] });
      setShowDeleteConfirm(null);
    },
  });

  // Backup hochladen
  const uploadMutation = useMutation({
    mutationFn: (file: File) => backupApi.upload(file),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['backups'] });
      setUploadError(null);
      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
    },
    onError: (error: any) => {
      setUploadError(error.message || 'Upload fehlgeschlagen');
    },
  });

  // Werkseinstellungen
  const factoryResetMutation = useMutation({
    mutationFn: () => backupApi.factoryReset(),
    onSuccess: () => {
      setShowFactoryResetConfirm(false);
      setFactoryResetConfirmText('');
      // Nach Factory Reset ausloggen
      logout();
    },
  });

  // Datei-Upload Handler
  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      if (!file.name.endsWith('.zip')) {
        setUploadError('Nur ZIP-Dateien sind erlaubt');
        return;
      }
      setUploadError(null);
      uploadMutation.mutate(file);
    }
  };

  // Download mit Auth-Token
  const handleDownload = async (name: string) => {
    const token = getAccessToken();
    const url = backupApi.getDownloadUrl(name);

    try {
      const response = await fetch(url, {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });

      if (!response.ok) {
        throw new Error('Download fehlgeschlagen');
      }

      // Blob erstellen und herunterladen
      const blob = await response.blob();
      const downloadUrl = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = downloadUrl;
      a.download = `opencrm-backup-${name}.zip`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      window.URL.revokeObjectURL(downloadUrl);
    } catch (error: any) {
      console.error('Download error:', error);
    }
  };

  // Formatierung
  const formatDate = (timestamp: string) => {
    return new Date(timestamp).toLocaleString('de-DE', {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    });
  };

  const formatSize = (bytes: number) => {
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  };

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-lg font-semibold text-gray-900 flex items-center gap-2">
            <Database className="w-5 h-5" />
            Datenbank & Zurücksetzen
          </h2>
          <p className="text-sm text-gray-500 mt-1">
            Backups erstellen, wiederherstellen oder auf Werkseinstellungen zurücksetzen.
          </p>
        </div>
        <div className="flex items-center gap-2">
          {/* Upload Button */}
          <input
            type="file"
            ref={fileInputRef}
            accept=".zip"
            onChange={handleFileSelect}
            className="hidden"
          />
          <Button
            variant="secondary"
            onClick={() => fileInputRef.current?.click()}
            disabled={uploadMutation.isPending}
          >
            {uploadMutation.isPending ? (
              <>
                <RefreshCw className="w-4 h-4 mr-2 animate-spin" />
                Hochladen...
              </>
            ) : (
              <>
                <Upload className="w-4 h-4 mr-2" />
                Backup hochladen
              </>
            )}
          </Button>
          {/* Create Button */}
          <Button
            onClick={() => createMutation.mutate()}
            disabled={createMutation.isPending}
          >
            {createMutation.isPending ? (
              <>
                <RefreshCw className="w-4 h-4 mr-2 animate-spin" />
                Wird erstellt...
              </>
            ) : (
              <>
                <Download className="w-4 h-4 mr-2" />
                Neues Backup
              </>
            )}
          </Button>
        </div>
      </div>

      {/* Upload Error */}
      {uploadError && (
        <div className="bg-red-50 border border-red-200 rounded-lg p-4 text-red-700">
          {uploadError}
        </div>
      )}

      {/* Info-Box */}
      <div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
        <h4 className="text-sm font-medium text-blue-800 mb-2">Hinweise zur Datensicherung</h4>
        <ul className="text-sm text-blue-700 space-y-1 list-disc list-inside">
          <li>Backups enthalten alle Datenbankdaten und hochgeladene Dokumente</li>
          <li>Erstellen Sie vor Datenbankmigrationen immer ein Backup</li>
          <li>Backups können als ZIP heruntergeladen und auf einem anderen System wiederhergestellt werden</li>
          <li>Bei der Wiederherstellung werden bestehende Daten mit dem Backup-Stand überschrieben</li>
        </ul>
      </div>

      {/* Backup-Liste */}
      <div className="bg-white rounded-lg border border-gray-200 overflow-hidden">
        <div className="px-4 py-3 bg-gray-50 border-b border-gray-200">
          <h3 className="text-sm font-medium text-gray-700">Verfügbare Backups</h3>
        </div>

        {isLoading ? (
          <div className="flex items-center justify-center py-12">
            <RefreshCw className="w-6 h-6 animate-spin text-gray-400" />
          </div>
        ) : backups.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-12 text-gray-500">
            <HardDrive className="w-12 h-12 mb-2 opacity-30" />
            <p>Keine Backups vorhanden</p>
            <p className="text-sm mt-1">Erstellen Sie Ihr erstes Backup</p>
          </div>
        ) : (
          <div className="divide-y divide-gray-200">
            {backups.map((backup: BackupInfo) => (
              <div key={backup.name} className="p-4 hover:bg-gray-50">
                <div className="flex items-start justify-between">
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-3 mb-2">
                      <span className="font-mono text-sm bg-gray-100 px-2 py-1 rounded">
                        {backup.name}
                      </span>
                      <span className="text-sm text-gray-500 flex items-center gap-1">
                        <Clock className="w-4 h-4" />
                        {formatDate(backup.timestamp)}
                      </span>
                    </div>
                    <div className="flex items-center gap-4 text-sm text-gray-600">
                      <span className="flex items-center gap-1">
                        <FileText className="w-4 h-4" />
                        {backup.totalRecords.toLocaleString('de-DE')} Datensätze
                      </span>
                      <span className="flex items-center gap-1">
                        <HardDrive className="w-4 h-4" />
                        {formatSize(backup.sizeBytes)}
                      </span>
                      {backup.hasUploads && (
                        <span className="flex items-center gap-1 text-green-600">
                          <FolderOpen className="w-4 h-4" />
                          Dokumente ({formatSize(backup.uploadSizeBytes)})
                        </span>
                      )}
                    </div>
                    {/* Tabellen-Details (kollabiert) */}
                    <details className="mt-2">
                      <summary className="text-xs text-gray-500 cursor-pointer hover:text-gray-700">
                        Tabellen anzeigen ({backup.tables.filter(t => t.count > 0).length} mit Daten)
                      </summary>
                      <div className="mt-2 flex flex-wrap gap-1">
                        {backup.tables
                          .filter(t => t.count > 0)
                          .map(t => (
                            <span
                              key={t.table}
                              className="text-xs bg-gray-100 px-2 py-0.5 rounded"
                            >
                              {t.table}: {t.count}
                            </span>
                          ))}
                      </div>
                    </details>
                  </div>

                  {/* Aktionen */}
                  <div className="flex items-center gap-2 ml-4">
                    <Button
                      variant="secondary"
                      size="sm"
                      onClick={() => handleDownload(backup.name)}
                      title="Als ZIP herunterladen"
                    >
                      <Archive className="w-4 h-4" />
                    </Button>
                    <Button
                      variant="secondary"
                      size="sm"
                      onClick={() => setShowRestoreConfirm(backup.name)}
                      disabled={restoreMutation.isPending}
                    >
                      <Upload className="w-4 h-4 mr-1" />
                      Wiederherstellen
                    </Button>
                    <Button
                      variant="danger"
                      size="sm"
                      onClick={() => setShowDeleteConfirm(backup.name)}
                      disabled={deleteMutation.isPending}
                    >
                      <Trash2 className="w-4 h-4" />
                    </Button>
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* Wiederherstellungs-Bestätigung */}
      {showRestoreConfirm && (
        <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 p-6 max-w-md mx-4">
            <h3 className="text-lg font-semibold text-gray-900 mb-2">
              Backup wiederherstellen?
            </h3>
            <p className="text-gray-600 mb-4">
              Möchten Sie das Backup <strong>{showRestoreConfirm}</strong> wirklich wiederherstellen?
            </p>
            <p className="text-amber-600 text-sm mb-4 bg-amber-50 p-3 rounded-lg">
              <strong>Achtung:</strong> Bestehende Daten und Dokumente werden mit dem Backup-Stand überschrieben.
              Dies kann nicht rückgängig gemacht werden.
            </p>
            <div className="flex justify-end gap-3">
              <Button
                variant="secondary"
                onClick={() => setShowRestoreConfirm(null)}
                disabled={restoreMutation.isPending}
              >
                Abbrechen
              </Button>
              <Button
                variant="primary"
                onClick={() => restoreMutation.mutate(showRestoreConfirm)}
                disabled={restoreMutation.isPending}
              >
                {restoreMutation.isPending ? (
                  <>
                    <RefreshCw className="w-4 h-4 mr-2 animate-spin" />
                    Wird wiederhergestellt...
                  </>
                ) : (
                  'Ja, wiederherstellen'
                )}
              </Button>
            </div>
          </div>
        </div>
      )}

      {/* Lösch-Bestätigung */}
      {showDeleteConfirm && (
        <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 p-6 max-w-md mx-4">
            <h3 className="text-lg font-semibold text-gray-900 mb-2">
              Backup löschen?
            </h3>
            <p className="text-gray-600 mb-4">
              Möchten Sie das Backup <strong>{showDeleteConfirm}</strong> wirklich löschen?
              Dies kann nicht rückgängig gemacht werden.
            </p>
            <div className="flex justify-end gap-3">
              <Button
                variant="secondary"
                onClick={() => setShowDeleteConfirm(null)}
                disabled={deleteMutation.isPending}
              >
                Abbrechen
              </Button>
              <Button
                variant="danger"
                onClick={() => deleteMutation.mutate(showDeleteConfirm)}
                disabled={deleteMutation.isPending}
              >
                {deleteMutation.isPending ? 'Wird gelöscht...' : 'Ja, löschen'}
              </Button>
            </div>
          </div>
        </div>
      )}

      {/* Werkseinstellungen */}
      <div className="bg-red-50 border border-red-200 rounded-lg p-6 mt-8">
        <div className="flex items-start gap-4">
          <div className="p-2 bg-red-100 rounded-lg">
            <AlertTriangle className="w-6 h-6 text-red-600" />
          </div>
          <div className="flex-1">
            <h3 className="text-lg font-semibold text-red-800 mb-2">
              Werkseinstellungen
            </h3>
            <p className="text-sm text-red-700 mb-4">
              Setzt das System auf den Ausgangszustand zurück. <strong>Alle Daten werden unwiderruflich gelöscht</strong> -
              Kunden, Verträge, Benutzer, Dokumente und Einstellungen. Nur die hier gespeicherten Backups bleiben erhalten.
            </p>
            <ul className="text-sm text-red-700 mb-4 list-disc list-inside space-y-1">
              <li>Alle Kunden und Verträge werden gelöscht</li>
              <li>Alle Benutzer werden gelöscht</li>
              <li>Alle hochgeladenen Dokumente werden gelöscht</li>
              <li>Ein neuer Admin-Benutzer wird erstellt (admin@admin.com / admin)</li>
              <li><strong>Backups bleiben erhalten</strong> und können danach wiederhergestellt werden</li>
            </ul>
            <Button
              variant="danger"
              onClick={() => setShowFactoryResetConfirm(true)}
            >
              <Bomb className="w-4 h-4 mr-2" />
              Werkseinstellungen
            </Button>
          </div>
        </div>
      </div>

      {/* Werkseinstellungen-Bestätigung */}
      {showFactoryResetConfirm && (
        <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 p-6 max-w-lg mx-4">
            <div className="flex items-center gap-3 mb-4">
              <div className="p-2 bg-red-100 rounded-lg">
                <AlertTriangle className="w-6 h-6 text-red-600" />
              </div>
              <h3 className="text-lg font-semibold text-gray-900">
                Wirklich auf Werkseinstellungen zurücksetzen?
              </h3>
            </div>
            <p className="text-gray-600 mb-4">
              Diese Aktion löscht <strong>alle Daten unwiderruflich</strong>. Es gibt kein Zurück!
            </p>
            <p className="text-sm text-gray-600 mb-4">
              Geben Sie zur Bestätigung <strong className="font-mono bg-gray-100 px-1">LÖSCHEN</strong> ein:
            </p>
            <input
              type="text"
              value={factoryResetConfirmText}
              onChange={(e) => setFactoryResetConfirmText(e.target.value)}
              placeholder="LÖSCHEN"
              className="w-full px-3 py-2 border border-gray-300 rounded-lg mb-4 focus:ring-2 focus:ring-red-500 focus:border-red-500"
            />
            <div className="flex justify-end gap-3">
              <Button
                variant="secondary"
                onClick={() => {
                  setShowFactoryResetConfirm(false);
                  setFactoryResetConfirmText('');
                }}
                disabled={factoryResetMutation.isPending}
              >
                Abbrechen
              </Button>
              <Button
                variant="danger"
                onClick={() => factoryResetMutation.mutate()}
                disabled={factoryResetConfirmText !== 'LÖSCHEN' || factoryResetMutation.isPending}
              >
                {factoryResetMutation.isPending ? (
                  <>
                    <RefreshCw className="w-4 h-4 mr-2 animate-spin" />
                    Wird zurückgesetzt...
                  </>
                ) : (
                  'Ja, alles löschen'
                )}
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
