import { useRef, useState } from 'react';
import { Link } from 'react-router-dom';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import Card from '../../components/ui/Card';
import Button from '../../components/ui/Button';
import {
  ArrowLeft,
  Download,
  Upload,
  Package,
  Info,
  Loader2,
  Check,
  AlertCircle,
  Building2,
  Tag,
  Clock,
  Calendar,
  FileType,
  FileText,
  FileCode,
} from 'lucide-react';
import api from '../../services/api';

interface PreviewCounts {
  providers: number;
  tariffs: number;
  cancellationPeriods: number;
  contractDurations: number;
  contractCategories: number;
  pdfTemplates: number;
  appSettings: number;
}

interface ImportResult {
  providers: number;
  tariffs: number;
  cancellationPeriods: number;
  contractDurations: number;
  contractCategories: number;
  pdfTemplates: number;
  pdfTemplatesSkipped: number;
  appSettings: number;
  warnings: string[];
}

export default function FactoryDefaults() {
  const [downloading, setDownloading] = useState(false);
  const [downloadError, setDownloadError] = useState<string | null>(null);
  const [downloadDone, setDownloadDone] = useState(false);

  const fileInputRef = useRef<HTMLInputElement>(null);
  const [importing, setImporting] = useState(false);
  const [importError, setImportError] = useState<string | null>(null);
  const [importResult, setImportResult] = useState<ImportResult | null>(null);
  const queryClient = useQueryClient();

  const { data: previewData, isLoading } = useQuery({
    queryKey: ['factory-defaults-preview'],
    queryFn: async () => {
      const res = await api.get<{ success: boolean; data: { counts: PreviewCounts } }>(
        '/factory-defaults/preview',
      );
      return res.data;
    },
  });

  const counts = previewData?.data?.counts;

  const handleExport = async () => {
    setDownloading(true);
    setDownloadError(null);
    setDownloadDone(false);

    try {
      const res = await api.get('/factory-defaults/export', {
        responseType: 'blob',
      });

      const blob = new Blob([res.data as BlobPart], { type: 'application/zip' });
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      const dateStr = new Date().toISOString().split('T')[0];
      a.href = url;
      a.download = `factory-defaults-${dateStr}.zip`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      window.URL.revokeObjectURL(url);

      setDownloadDone(true);
      setTimeout(() => setDownloadDone(false), 3000);
    } catch (err) {
      setDownloadError(
        err instanceof Error ? err.message : 'Fehler beim Export',
      );
    } finally {
      setDownloading(false);
    }
  };

  const sections = counts
    ? [
        { icon: Building2, label: 'Anbieter', count: counts.providers, color: 'text-blue-600' },
        { icon: Tag, label: 'Tarife', count: counts.tariffs, color: 'text-indigo-600' },
        { icon: Clock, label: 'Kündigungsfristen', count: counts.cancellationPeriods, color: 'text-purple-600' },
        { icon: Calendar, label: 'Laufzeiten', count: counts.contractDurations, color: 'text-pink-600' },
        { icon: FileType, label: 'Vertragskategorien', count: counts.contractCategories, color: 'text-orange-600' },
        { icon: FileText, label: 'PDF-Auftragsvorlagen', count: counts.pdfTemplates, color: 'text-green-600' },
        { icon: FileCode, label: 'HTML-Templates', count: counts.appSettings ?? 0, color: 'text-teal-600' },
      ]
    : [];

  const handleImport = async (file: File) => {
    setImporting(true);
    setImportError(null);
    setImportResult(null);
    try {
      const formData = new FormData();
      formData.append('zip', file);
      const res = await api.post<{ success: boolean; data: ImportResult; error?: string }>(
        '/factory-defaults/import',
        formData,
        { headers: { 'Content-Type': 'multipart/form-data' } },
      );
      if (!res.data.success) {
        throw new Error(res.data.error || 'Fehler beim Import');
      }
      setImportResult(res.data.data);
      // Caches invalidieren – neue Anbieter, Tarife, Vorlagen tauchen sofort
      // an anderer Stelle (Provider-Liste, Vertrag-Anlage, …) auf.
      queryClient.invalidateQueries();
    } catch (err: any) {
      setImportError(
        err?.response?.data?.error || err?.message || 'Fehler beim Import',
      );
    } finally {
      setImporting(false);
      if (fileInputRef.current) fileInputRef.current.value = '';
    }
  };

  return (
    <div>
      <div className="flex items-center gap-4 mb-6">
        <Link to="/settings">
          <Button variant="ghost" size="sm">
            <ArrowLeft className="w-4 h-4" />
          </Button>
        </Link>
        <div className="flex items-center gap-3">
          <Package className="w-6 h-6 text-blue-600" />
          <h1 className="text-2xl font-bold">Factory-Defaults</h1>
        </div>
      </div>

      {/* Info-Box */}
      <div className="mb-6 bg-blue-50 border border-blue-200 rounded-lg p-4 flex items-start gap-3">
        <Info className="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5" />
        <div className="text-sm text-blue-900 space-y-1">
          <p className="font-medium">Was sind Factory-Defaults?</p>
          <p>
            Das sind <strong>Stammdaten-Kataloge</strong> wie Anbieter, Tarife,
            Kündigungsfristen, Vertragskategorien, PDF-Auftragsvorlagen und die
            HTML-Standardtexte (Datenschutzerklärung, Impressum, Vollmacht-Vorlage,
            Website-Datenschutz). Du kannst sie exportieren, um sie in anderen
            OpenCRM-Installationen als Startpunkt zu verwenden.
          </p>
          <p className="pt-1">
            <strong>Nicht enthalten</strong> sind Kundendaten, Verträge, Dokumente, E-Mails
            oder Konfigurationen (SMTP, Secrets) – dafür gibt es den separaten{' '}
            <Link to="/settings/database-backup" className="underline">
              Datenbank-Backup
            </Link>
            .
          </p>
        </div>
      </div>

      <Card title="Export" className="mb-6">
        <p className="text-sm text-gray-600 mb-4">
          Erstellt ein ZIP mit allen Kataloge-Daten, PDF-Auftragsvorlagen und den
          HTML-Standardtexten (Datenschutz / Impressum / Vollmacht). In einer anderen
          OpenCRM-Installation kannst du es dann unten unter <strong>Import</strong> wieder
          einspielen.
        </p>

        {isLoading ? (
          <div className="flex items-center gap-2 text-gray-500 py-4">
            <Loader2 className="w-4 h-4 animate-spin" />
            <span className="text-sm">Lade Übersicht…</span>
          </div>
        ) : counts ? (
          <div className="grid grid-cols-2 md:grid-cols-3 gap-3 mb-6">
            {sections.map((s) => (
              <div
                key={s.label}
                className="border border-gray-200 rounded-lg p-3 flex items-center gap-3"
              >
                <s.icon className={`w-5 h-5 ${s.color}`} />
                <div>
                  <div className="text-sm text-gray-500">{s.label}</div>
                  <div className="text-xl font-bold">{s.count}</div>
                </div>
              </div>
            ))}
          </div>
        ) : null}

        <div className="flex items-center gap-3">
          <Button onClick={handleExport} disabled={downloading}>
            {downloading ? (
              <>
                <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                ZIP wird erstellt…
              </>
            ) : downloadDone ? (
              <>
                <Check className="w-4 h-4 mr-2" />
                Heruntergeladen
              </>
            ) : (
              <>
                <Download className="w-4 h-4 mr-2" />
                Factory-Defaults exportieren
              </>
            )}
          </Button>
        </div>

        {downloadError && (
          <div className="mt-3 p-3 bg-red-50 border border-red-200 rounded-lg flex items-start gap-2 text-sm text-red-700">
            <AlertCircle className="w-4 h-4 flex-shrink-0 mt-0.5" />
            <span>{downloadError}</span>
          </div>
        )}
      </Card>

      <Card title="Import">
        <p className="text-sm text-gray-600 mb-4">
          Lade hier eine zuvor exportierte Factory-Defaults-ZIP hoch. Bestehende Einträge
          werden anhand des Unique-Keys (Name / Code) <strong>aktualisiert</strong>, neue
          werden angelegt. Es wird nichts gelöscht – der Vorgang ist idempotent.
        </p>

        <input
          ref={fileInputRef}
          type="file"
          accept=".zip,application/zip,application/x-zip-compressed"
          className="hidden"
          onChange={(e) => {
            const f = e.target.files?.[0];
            if (f) handleImport(f);
          }}
        />

        <div className="flex items-center gap-3">
          <Button
            onClick={() => fileInputRef.current?.click()}
            disabled={importing}
            variant="secondary"
          >
            {importing ? (
              <>
                <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                Import läuft…
              </>
            ) : (
              <>
                <Upload className="w-4 h-4 mr-2" />
                ZIP hochladen
              </>
            )}
          </Button>
          <span className="text-xs text-gray-500">
            Alternativ:{' '}
            <code className="bg-gray-100 px-1.5 py-0.5 rounded">
              npm run seed:defaults
            </code>{' '}
            im Backend
          </span>
        </div>

        {importResult && (
          <div className="mt-4 p-3 bg-green-50 border border-green-200 rounded-lg text-sm text-green-800">
            <div className="flex items-center gap-2 font-medium mb-2">
              <Check className="w-4 h-4" />
              Import erfolgreich
            </div>
            <ul className="list-disc list-inside space-y-0.5 text-xs">
              <li>Anbieter: {importResult.providers}</li>
              <li>Tarife: {importResult.tariffs}</li>
              <li>Kündigungsfristen: {importResult.cancellationPeriods}</li>
              <li>Laufzeiten: {importResult.contractDurations}</li>
              <li>Vertragskategorien: {importResult.contractCategories}</li>
              <li>
                PDF-Vorlagen: {importResult.pdfTemplates}
                {importResult.pdfTemplatesSkipped > 0 &&
                  ` (${importResult.pdfTemplatesSkipped} übersprungen)`}
              </li>
              <li>HTML-Templates: {importResult.appSettings}</li>
            </ul>
            {importResult.warnings.length > 0 && (
              <div className="mt-2 pt-2 border-t border-green-200 text-amber-700 text-xs">
                <div className="font-medium mb-1">Hinweise:</div>
                <ul className="list-disc list-inside space-y-0.5">
                  {importResult.warnings.map((w, i) => (
                    <li key={i}>{w}</li>
                  ))}
                </ul>
              </div>
            )}
          </div>
        )}

        {importError && (
          <div className="mt-3 p-3 bg-red-50 border border-red-200 rounded-lg flex items-start gap-2 text-sm text-red-700">
            <AlertCircle className="w-4 h-4 flex-shrink-0 mt-0.5" />
            <span>{importError}</span>
          </div>
        )}
      </Card>
    </div>
  );
}
