import { useEffect, useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { pdfTemplateApi, contractApi, authApi } from '../../services/api';
import type { PdfTemplate, CrmField, Contract } from '../../types';
import { buildContractLabelParts } from '../../utils/contractLabel';
import Card from '../../components/ui/Card';
import Button from '../../components/ui/Button';
import Input from '../../components/ui/Input';
import Badge from '../../components/ui/Badge';
import Modal from '../../components/ui/Modal';
import { ArrowLeft, Plus, Edit, Trash2, FileText, Upload, Link2, Eye, Play } from 'lucide-react';
import { viewUrl } from '../../utils/fileUrl';

export default function PdfTemplates() {
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const [showCreateModal, setShowCreateModal] = useState(false);
  const [editingTemplate, setEditingTemplate] = useState<PdfTemplate | null>(null);
  const [mappingTemplate, setMappingTemplate] = useState<PdfTemplate | null>(null);
  const [testTemplate, setTestTemplate] = useState<PdfTemplate | null>(null);

  const { data: templatesData, isLoading } = useQuery({
    queryKey: ['pdf-templates'],
    queryFn: () => pdfTemplateApi.getAll(),
  });

  const deleteMutation = useMutation({
    mutationFn: (id: number) => pdfTemplateApi.delete(id),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['pdf-templates'] }),
  });

  const templates = templatesData?.data || [];

  return (
    <div>
      <div className="flex items-center gap-4 mb-6">
        <Button variant="ghost" onClick={() => navigate('/settings')}>
          <ArrowLeft className="w-4 h-4" />
        </Button>
        <h1 className="text-2xl font-bold flex-1">Auftragsvorlagen</h1>
        <Button onClick={() => setShowCreateModal(true)}>
          <Plus className="w-4 h-4 mr-2" />
          Vorlage hochladen
        </Button>
      </div>

      <Card className="mb-6">
        <p className="text-sm text-gray-600">
          Laden Sie PDF-Formulare hoch (z.B. EWE Auftragsformular) und verknüpfen Sie die Formularfelder mit CRM-Daten.
          Beim Erstellen eines Auftrags werden die Felder automatisch mit den Kundendaten befüllt.
        </p>
      </Card>

      {isLoading ? (
        <div className="text-center py-8 text-gray-500">Laden...</div>
      ) : templates.length === 0 ? (
        <Card>
          <div className="text-center py-8 text-gray-500">
            Noch keine Vorlagen vorhanden. Laden Sie eine PDF-Vorlage hoch.
          </div>
        </Card>
      ) : (
        <div className="space-y-4">
          {templates.map((t) => (
            <Card key={t.id}>
              <div className="flex items-start justify-between">
                <div className="flex items-start gap-3">
                  <FileText className="w-5 h-5 text-blue-500 mt-0.5" />
                  <div>
                    <div className="flex items-center gap-2">
                      <h3 className="font-semibold">{t.name}</h3>
                      {t.providerName && <Badge variant="info">{t.providerName}</Badge>}
                      {!t.isActive && <Badge variant="danger">Inaktiv</Badge>}
                    </div>
                    {t.description && <p className="text-sm text-gray-500 mt-1">{t.description}</p>}
                    <p className="text-xs text-gray-400 mt-1">
                      Datei: {t.originalName}
                      {t.maxPhoneFields && ` · Max. ${t.maxPhoneFields} Rufnummern`}
                    </p>
                    {(() => {
                      const mapping = JSON.parse(t.fieldMapping || '{}');
                      const count = Object.keys(mapping).length;
                      return (
                        <p className="text-xs text-gray-400">
                          {count > 0 ? `${count} Felder verknüpft` : 'Noch keine Felder verknüpft'}
                        </p>
                      );
                    })()}
                  </div>
                </div>
                <div className="flex gap-2">
                  <Button variant="secondary" size="sm" onClick={() => setMappingTemplate(t)}>
                    <Link2 className="w-4 h-4 mr-1" />
                    Felder zuordnen
                  </Button>
                  <Button variant="ghost" size="sm" onClick={() => setTestTemplate(t)} title="Testvorschau mit Vertragsdaten">
                    <Play className="w-4 h-4 text-green-500" />
                  </Button>
                  <a href={viewUrl(t.templatePath)} target="_blank" rel="noopener noreferrer">
                    <Button variant="ghost" size="sm" title="Leere Vorlage anzeigen">
                      <Eye className="w-4 h-4" />
                    </Button>
                  </a>
                  <Button variant="ghost" size="sm" onClick={() => setEditingTemplate(t)} title="Bearbeiten">
                    <Edit className="w-4 h-4" />
                  </Button>
                  <Button variant="ghost" size="sm" onClick={() => {
                    if (confirm(`Vorlage "${t.name}" wirklich löschen?`)) deleteMutation.mutate(t.id);
                  }} title="Löschen">
                    <Trash2 className="w-4 h-4 text-red-500" />
                  </Button>
                </div>
              </div>
            </Card>
          ))}
        </div>
      )}

      {/* Erstellen Modal */}
      {showCreateModal && (
        <CreateTemplateModal onClose={() => { setShowCreateModal(false); queryClient.invalidateQueries({ queryKey: ['pdf-templates'] }); }} />
      )}

      {/* Bearbeiten Modal */}
      {editingTemplate && (
        <EditTemplateModal template={editingTemplate} onClose={() => { setEditingTemplate(null); queryClient.invalidateQueries({ queryKey: ['pdf-templates'] }); }} />
      )}

      {/* Feld-Mapping Modal */}
      {mappingTemplate && (
        <FieldMappingModal template={mappingTemplate} onClose={() => { setMappingTemplate(null); queryClient.invalidateQueries({ queryKey: ['pdf-templates'] }); }} />
      )}

      {/* Test-Vorschau Modal */}
      {testTemplate && (
        <TestPreviewModal template={testTemplate} onClose={() => setTestTemplate(null)} />
      )}
    </div>
  );
}

// ==================== CREATE MODAL ====================

function CreateTemplateModal({ onClose }: { onClose: () => void }) {
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [providerName, setProviderName] = useState('');
  const [maxPhoneFields, setMaxPhoneFields] = useState('8');
  const [file, setFile] = useState<File | null>(null);

  const createMutation = useMutation({
    mutationFn: async () => {
      const formData = new FormData();
      formData.append('name', name);
      if (description) formData.append('description', description);
      if (providerName) formData.append('providerName', providerName);
      formData.append('maxPhoneFields', maxPhoneFields);
      formData.append('template', file!);
      return pdfTemplateApi.create(formData);
    },
    onSuccess: () => onClose(),
  });

  return (
    <Modal isOpen={true} onClose={onClose} title="Neue Auftragsvorlage">
      <div className="space-y-4">
        <Input label="Name *" value={name} onChange={(e) => setName(e.target.value)} placeholder="z.B. EWE Auftragsformular" required />
        <Input label="Anbieter" value={providerName} onChange={(e) => setProviderName(e.target.value)} placeholder="z.B. EWE" />
        <Input label="Beschreibung" value={description} onChange={(e) => setDescription(e.target.value)} placeholder="Optionale Beschreibung" />
        <Input label="Max. Rufnummern-Felder" type="number" value={maxPhoneFields} onChange={(e) => setMaxPhoneFields(e.target.value)} />

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">PDF-Vorlage *</label>
          <label className="flex items-center justify-center gap-2 p-4 border-2 border-dashed rounded-lg cursor-pointer hover:bg-gray-50">
            <Upload className="w-5 h-5 text-gray-400" />
            <span className="text-sm text-gray-600">{file ? file.name : 'PDF-Datei auswählen'}</span>
            <input type="file" accept=".pdf" className="hidden" onChange={(e) => setFile(e.target.files?.[0] || null)} />
          </label>
          <p className="text-xs text-gray-500 mt-1">
            Die PDF muss Formularfelder enthalten. Diese werden nach dem Hochladen automatisch erkannt.
          </p>
        </div>

        {createMutation.isError && (
          <div className="p-3 bg-red-50 text-red-700 text-sm rounded-lg">
            {createMutation.error instanceof Error ? createMutation.error.message : 'Fehler beim Erstellen'}
          </div>
        )}

        <div className="flex justify-end gap-3">
          <Button variant="secondary" onClick={onClose}>Abbrechen</Button>
          <Button onClick={() => createMutation.mutate()} disabled={!name || !file || createMutation.isPending}>
            {createMutation.isPending ? 'Hochladen...' : 'Hochladen'}
          </Button>
        </div>
      </div>
    </Modal>
  );
}

// ==================== EDIT MODAL ====================

function EditTemplateModal({ template, onClose }: { template: PdfTemplate; onClose: () => void }) {
  const [name, setName] = useState(template.name);
  const [description, setDescription] = useState(template.description || '');
  const [providerName, setProviderName] = useState(template.providerName || '');
  const [maxPhoneFields, setMaxPhoneFields] = useState(template.maxPhoneFields?.toString() || '8');
  const [isActive, setIsActive] = useState(template.isActive);

  const updateMutation = useMutation({
    mutationFn: () => pdfTemplateApi.update(template.id, { name, description, providerName, maxPhoneFields: parseInt(maxPhoneFields), isActive }),
    onSuccess: () => onClose(),
  });

  return (
    <Modal isOpen={true} onClose={onClose} title="Vorlage bearbeiten">
      <div className="space-y-4">
        <Input label="Name" value={name} onChange={(e) => setName(e.target.value)} required />
        <Input label="Anbieter" value={providerName} onChange={(e) => setProviderName(e.target.value)} />
        <Input label="Beschreibung" value={description} onChange={(e) => setDescription(e.target.value)} />
        <Input label="Max. Rufnummern-Felder" type="number" value={maxPhoneFields} onChange={(e) => setMaxPhoneFields(e.target.value)} />
        <label className="flex items-center gap-2">
          <input type="checkbox" checked={isActive} onChange={(e) => setIsActive(e.target.checked)} className="rounded" />
          <span className="text-sm">Aktiv</span>
        </label>
        <div className="flex justify-end gap-3">
          <Button variant="secondary" onClick={onClose}>Abbrechen</Button>
          <Button onClick={() => updateMutation.mutate()} disabled={updateMutation.isPending}>
            {updateMutation.isPending ? 'Speichern...' : 'Speichern'}
          </Button>
        </div>
      </div>
    </Modal>
  );
}

// ==================== FIELD MAPPING MODAL ====================

function FieldMappingModal({ template, onClose }: { template: PdfTemplate; onClose: () => void }) {
  const [mapping, setMapping] = useState<Record<string, string>>(JSON.parse(template.fieldMapping || '{}'));

  const { data: fieldsData } = useQuery({
    queryKey: ['pdf-fields', template.id],
    queryFn: () => pdfTemplateApi.getFields(template.id),
  });

  const { data: crmFieldsData } = useQuery({
    queryKey: ['crm-fields', template.maxPhoneFields],
    queryFn: () => pdfTemplateApi.getCrmFields(template.maxPhoneFields || 8),
  });

  const saveMutation = useMutation({
    mutationFn: () => pdfTemplateApi.update(template.id, { fieldMapping: mapping }),
    onSuccess: () => onClose(),
  });

  const pdfFields = fieldsData?.data || [];
  const totalPages = (fieldsData as any)?.totalPages || 1;
  const crmFields = crmFieldsData?.data || [];

  // CRM-Felder nach Gruppe
  const crmGroups = crmFields.reduce((acc, f) => {
    if (!acc[f.group]) acc[f.group] = [];
    acc[f.group].push(f);
    return acc;
  }, {} as Record<string, CrmField[]>);

  const [highlightedField, setHighlightedField] = useState<string | null>(null);
  // Kurzlebigen Download-Token (60s) für die iframe-URL holen, damit das
  // langlebige Access-JWT nicht in Browser-History/Referer landet.
  const [previewToken, setPreviewToken] = useState<string | null>(null);
  useEffect(() => {
    let cancelled = false;
    authApi.getDownloadToken().then((t) => {
      if (!cancelled) setPreviewToken(t);
    });
    return () => { cancelled = true; };
  }, [template.id]);

  return (
    <div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex">
      {/* PDF-Vorschau links (nur zur Ansicht, nicht interaktiv) */}
      <div className="w-1/2 bg-gray-800 flex flex-col">
        <div className="p-3 bg-gray-900 text-white text-sm flex items-center justify-between">
          <span>PDF-Vorschau mit Feldnamen</span>
          <span className="text-gray-400 text-xs">[Feldname] zeigt wo das Feld in der PDF liegt</span>
        </div>
        {previewToken && (
          <iframe
            src={`/api/pdf-templates/${template.id}/preview?token=${previewToken}`}
            className="flex-1 w-full bg-white"
            title="PDF Vorschau mit Feldnamen"
          />
        )}
      </div>

      {/* Zuordnung rechts */}
      <div className="w-1/2 bg-white flex flex-col">
        <div className="p-4 border-b flex items-center justify-between">
          <div>
            <h2 className="text-lg font-semibold">Felder zuordnen</h2>
            <p className="text-xs text-gray-500">
              PDF-Feld links in der Vorschau finden, dann rechts das CRM-Feld zuordnen
            </p>
          </div>
          <Badge>{Object.keys(mapping).length} / {pdfFields.length}</Badge>
        </div>

        <div className="flex-1 overflow-y-auto p-4">
          {pdfFields.length === 0 ? (
            <div className="text-center py-8 text-amber-600 bg-amber-50 rounded-lg">
              <p className="font-medium">Keine Formularfelder gefunden.</p>
              <p className="text-sm mt-1">Die PDF muss interaktive Formularfelder enthalten.</p>
            </div>
          ) : (
            <>
            <div className="flex gap-2 mb-3">
              <button
                onClick={() => setHighlightedField('all')}
                className={`px-3 py-1 rounded text-xs font-medium ${highlightedField === 'all' || !highlightedField ? 'bg-gray-200 text-gray-800' : 'text-gray-500 hover:bg-gray-100'}`}
              >
                Alle ({pdfFields.length})
              </button>
              <button
                onClick={() => setHighlightedField('open')}
                className={`px-3 py-1 rounded text-xs font-medium ${highlightedField === 'open' ? 'bg-amber-100 text-amber-800' : 'text-gray-500 hover:bg-gray-100'}`}
              >
                Offen ({pdfFields.filter(f => !mapping[f.name]).length})
              </button>
              <button
                onClick={() => setHighlightedField('done')}
                className={`px-3 py-1 rounded text-xs font-medium ${highlightedField === 'done' ? 'bg-green-100 text-green-800' : 'text-gray-500 hover:bg-gray-100'}`}
              >
                Zugeordnet ({pdfFields.filter(f => !!mapping[f.name]).length})
              </button>
            </div>

            <div className="space-y-2">
              {(() => {
                const filtered = pdfFields.filter((f: any) => {
                  if (highlightedField === 'open') return !mapping[f.name];
                  if (highlightedField === 'done') return !!mapping[f.name];
                  return true;
                });

                let lastPage = -1;
                let fieldNum = 0;

                return filtered.map((pdfField: any) => {
                  fieldNum++;
                  const isAssigned = !!mapping[pdfField.name];
                  const assignedLabel = isAssigned
                    ? crmFields.find(c => c.path === mapping[pdfField.name])?.label
                    : null;
                  const showPageHeader = totalPages > 1 && pdfField.page !== lastPage;
                  lastPage = pdfField.page;

                  return (
                    <div key={pdfField.name}>
                      {showPageHeader && (
                        <div className="flex items-center gap-2 py-2 mt-2 first:mt-0">
                          <div className="flex-1 border-t border-blue-200" />
                          <span className="text-xs font-medium text-blue-600 px-2 bg-blue-50 rounded-full">
                            Seite {pdfField.page + 1}
                          </span>
                          <div className="flex-1 border-t border-blue-200" />
                        </div>
                      )}
                      <div
                        className={`p-3 rounded-lg border transition-colors ${
                          isAssigned ? 'border-green-200 bg-green-50' : 'border-gray-200 bg-gray-50'
                        }`}
                      >
                        <div className="flex items-center gap-2 mb-2">
                          <span className="text-xs text-gray-400 w-5">{fieldNum}.</span>
                          <span className={`w-2 h-2 rounded-full flex-shrink-0 ${isAssigned ? 'bg-green-500' : 'bg-amber-400'}`} />
                          <span className="font-mono text-sm font-medium truncate" title={pdfField.name}>{pdfField.name}</span>
                          <Badge variant="default">{pdfField.type}</Badge>
                          {assignedLabel && (
                            <span className="text-xs text-green-700 ml-auto flex-shrink-0">→ {assignedLabel}</span>
                          )}
                        </div>
                        <select
                          value={mapping[pdfField.name] || ''}
                          onChange={(e) => {
                            const newMapping = { ...mapping };
                            if (e.target.value) newMapping[pdfField.name] = e.target.value;
                            else delete newMapping[pdfField.name];
                            setMapping(newMapping);
                          }}
                          className={`block w-full px-3 py-1.5 border rounded text-sm ${
                            isAssigned ? 'border-green-300 bg-white' : 'border-gray-300'
                          }`}
                        >
                          <option value="">-- Nicht zuordnen --</option>
                          {Object.entries(crmGroups).map(([group, fields]) => (
                            <optgroup key={group} label={group}>
                              {fields.map((f) => (
                                <option key={f.path} value={f.path}>{f.label}</option>
                              ))}
                            </optgroup>
                          ))}
                        </select>
                      </div>
                    </div>
                  );
                });
              })()}
            </div>
            </>
          )}
        </div>

        <div className="p-4 border-t flex justify-between items-center">
          <p className="text-xs text-gray-500">
            {Object.keys(mapping).length} von {pdfFields.length} zugeordnet
          </p>
          <div className="flex gap-3">
            <Button variant="secondary" onClick={onClose}>Abbrechen</Button>
            <Button onClick={() => saveMutation.mutate()} disabled={saveMutation.isPending}>
              {saveMutation.isPending ? 'Speichern...' : 'Speichern'}
            </Button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ==================== TEST PREVIEW MODAL ====================

function TestPreviewModal({ template, onClose }: { template: PdfTemplate; onClose: () => void }) {
  const [search, setSearch] = useState('');
  const [selectedContractId, setSelectedContractId] = useState<number | null>(null);

  const { data: contractsData, isLoading } = useQuery({
    queryKey: ['contracts-search', search],
    queryFn: () => contractApi.getAll({ search: search || undefined, limit: 10 }),
    enabled: search.length >= 2,
  });

  const contracts: Contract[] = contractsData?.data || [];

  const handleGenerate = async () => {
    if (!selectedContractId) return;
    // Kurzlebigen Download-Token (60s) statt langlebigem Access-JWT in der URL.
    const downloadToken = await authApi.getDownloadToken();
    const url = `${pdfTemplateApi.generateUrl(template.id, selectedContractId)}?token=${downloadToken ?? ''}`;
    window.open(url, '_blank');
  };

  return (
    <Modal isOpen={true} onClose={onClose} title={`Testvorschau: ${template.name}`}>
      <div className="space-y-4">
        <p className="text-sm text-gray-600">
          Wählen Sie einen Vertrag aus, um die Vorlage mit echten Daten zu testen.
        </p>

        <Input
          label="Vertrag suchen (Vertragsnr., Kunde, Kundennr.)"
          value={search}
          onChange={(e) => { setSearch(e.target.value); setSelectedContractId(null); }}
          placeholder="z.B. ELE-ML9U66 oder Robbers"
        />

        {isLoading && <p className="text-sm text-gray-500">Suche...</p>}

        {contracts.length > 0 && (
          <div className="max-h-48 overflow-y-auto border rounded-lg">
            {contracts.map((c) => (
              <button
                key={c.id}
                onClick={() => setSelectedContractId(c.id)}
                className={`w-full text-left px-4 py-2 text-sm hover:bg-gray-50 flex items-center justify-between border-b last:border-0 ${
                  selectedContractId === c.id ? 'bg-blue-50 border-blue-200' : ''
                }`}
              >
                <div className="flex-1 min-w-0">
                  <div>
                    <span className="font-mono font-medium">{c.contractNumber}</span>
                    {c.customer && (
                      <span className="text-gray-500 ml-2">
                        {c.customer.companyName || `${c.customer.firstName} ${c.customer.lastName}`}
                      </span>
                    )}
                  </div>
                  {(() => {
                    const parts = buildContractLabelParts(c);
                    return parts.extras.length > 0 ? (
                      <div className="text-xs text-gray-400 truncate">
                        {parts.extras.join(' · ')}
                      </div>
                    ) : null;
                  })()}
                </div>
                <Badge variant="default">{c.type}</Badge>
              </button>
            ))}
          </div>
        )}

        {search.length >= 2 && !isLoading && contracts.length === 0 && (
          <p className="text-sm text-gray-500">Keine Verträge gefunden.</p>
        )}

        {selectedContractId && (
          <div className="p-3 bg-green-50 border border-green-200 rounded-lg text-sm text-green-800">
            Vertrag ausgewählt. Klicken Sie auf "PDF generieren" um die befüllte Vorlage zu öffnen.
          </div>
        )}

        <div className="flex justify-end gap-3">
          <Button variant="secondary" onClick={onClose}>Schließen</Button>
          <Button onClick={handleGenerate} disabled={!selectedContractId}>
            <Play className="w-4 h-4 mr-2" />
            PDF generieren
          </Button>
        </div>
      </div>
    </Modal>
  );
}
