import { useState, useEffect } from 'react';
import { useParams, Link, useNavigate, useLocation } from 'react-router-dom';
import { pushHistory, popHistory } from '../../utils/navigation';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { contractApi, uploadApi, meterApi, contractTaskApi, appSettingsApi, gdprApi, pdfTemplateApi, authApi } from '../../services/api';
import { ContractEmailsSection } from '../../components/email';
import { ContractDetailModal, ContractHistorySection } from '../../components/contracts';
import InvoicesSection from '../../components/contracts/InvoicesSection';
import CreditNotesSection from '../../components/contracts/CreditNotesSection';
import CustomerInfoModal from '../../components/contracts/CustomerInfoModal';
import { useAuth } from '../../context/AuthContext';
import Card from '../../components/ui/Card';
import Button from '../../components/ui/Button';
import Badge from '../../components/ui/Badge';
import Input from '../../components/ui/Input';
import Modal from '../../components/ui/Modal';
import PdfViewerModal from '../../components/ui/PdfViewerModal';
import FileUpload from '../../components/ui/FileUpload';
import { Edit, Trash2, Copy, Eye, EyeOff, ArrowLeft, ArrowRight, Download, ExternalLink, Plus, ChevronDown, ChevronUp, Gauge, CheckCircle, Circle, ClipboardList, MessageSquare, Calculator, Info, X, BellOff, Lock, Shield, FileText, Images } from 'lucide-react';
import toast from 'react-hot-toast';
import JpgToPdfModal from '../../components/ui/JpgToPdfModal';
import { calculateConsumption, calculateCosts, calculateMultiMeterConsumption } from '../../utils/energyCalculations';
import CopyButton, { CopyableBlock } from '../../components/ui/CopyButton';
import AutosaveDateInput from '../../components/ui/AutosaveDateInput';
import { formatDate } from '../../utils/dateFormat';
import { useProviderSettings } from '../../hooks/useProviderSettings';
import type { ContractType, ContractStatus, SimCard, MeterReading, ContractTask, ContractTaskSubtask, ContractMeter, ContractDocument } from '../../types';
import { fileUrl, viewUrl } from '../../utils/fileUrl';
import { safeHttpUrl } from '../../utils/url';

const typeLabels: Record<ContractType, string> = {
  ELECTRICITY: 'Strom',
  GAS: 'Gas',
  DSL: 'DSL',
  CABLE: 'Kabelinternet',
  FIBER: 'Glasfaser',
  MOBILE: 'Mobilfunk',
  TV: 'TV',
  CAR_INSURANCE: 'KFZ-Versicherung',
};

const statusLabels: Record<ContractStatus, string> = {
  DRAFT: 'Entwurf',
  PENDING: 'Ausstehend',
  ACTIVE: 'Aktiv',
  CANCELLED: 'Gekündigt / Bestätigung abwarten',
  CANCELLED_CONFIRMED: 'Gekündigt / bestätigt',
  EXPIRED: 'Abgelaufen',
  DEACTIVATED: 'Deaktiviert',
  ONGOING: 'Läuft weiter (unbestimmt)',
};

const statusVariants: Record<ContractStatus, 'success' | 'warning' | 'danger' | 'default'> = {
  ACTIVE: 'success',
  PENDING: 'warning',
  CANCELLED: 'warning',
  CANCELLED_CONFIRMED: 'danger',
  EXPIRED: 'danger',
  DRAFT: 'default',
  DEACTIVATED: 'default',
  ONGOING: 'success',
};

// Status-Erklärungen für Info-Modal
const statusDescriptions = [
  { status: 'DRAFT', label: 'Entwurf', description: 'Vertrag wird noch vorbereitet', color: 'text-gray-600' },
  { status: 'PENDING', label: 'Ausstehend', description: 'Wartet auf Aktivierung', color: 'text-yellow-600' },
  { status: 'ACTIVE', label: 'Aktiv', description: 'Vertrag läuft normal', color: 'text-green-600' },
  { status: 'ONGOING', label: 'Läuft weiter (unbestimmt)', description: 'Vertrag läuft unbefristet – alle Fristen im Cockpit werden ignoriert', color: 'text-green-700' },
  { status: 'EXPIRED', label: 'Abgelaufen', description: 'Laufzeit vorbei, läuft aber ohne Kündigung weiter', color: 'text-orange-600' },
  { status: 'CANCELLED', label: 'Gekündigt / Bestätigung abwarten', description: 'Kündigungsschreiben raus – Bestätigung des Anbieters steht noch aus', color: 'text-orange-600' },
  { status: 'CANCELLED_CONFIRMED', label: 'Gekündigt / bestätigt', description: 'Kündigung vom Anbieter bestätigt, Vertrag endet', color: 'text-red-600' },
  { status: 'DEACTIVATED', label: 'Deaktiviert', description: 'Manuell beendet/archiviert', color: 'text-gray-500' },
];

function StatusInfoModal({ isOpen, onClose }: { isOpen: boolean; onClose: () => void }) {
  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="fixed inset-0 bg-black/20" onClick={onClose} />
      <div className="relative bg-white rounded-lg shadow-xl p-4 max-w-sm w-full mx-4">
        <div className="flex items-center justify-between mb-3">
          <h3 className="text-sm font-semibold text-gray-900">Vertragsstatus-Übersicht</h3>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600">
            <X className="w-4 h-4" />
          </button>
        </div>
        <div className="space-y-2">
          {statusDescriptions.map(({ status, label, description, color }) => (
            <div key={status} className="flex items-start gap-2">
              <span className={`font-medium text-sm min-w-[90px] ${color}`}>{label}</span>
              <span className="text-sm text-gray-600">{description}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// Prüft ob die Laufzeit als "unbefristet" gilt (≤ 4 Wochen / 1 Monat / 30 Tage)
function isUnlimitedDuration(durationCode: string): boolean {
  const match = durationCode.match(/^(\d+)([TMWJ])$/);
  if (!match) return false;

  const value = parseInt(match[1]);
  const unit = match[2];

  // Alles in Tage umrechnen (1 Monat ≈ 30 Tage, 1 Woche = 7 Tage)
  let days = 0;
  if (unit === 'T') days = value;
  else if (unit === 'W') days = value * 7;
  else if (unit === 'M') days = value * 30;
  else if (unit === 'J') days = value * 365;

  // ≤ 30 Tage (entspricht 4 Wochen = 28 Tage, 1 Monat = 30 Tage)
  return days <= 30;
}

// SimCard Display Component with PIN/PUK reveal
function SimCardDisplay({ simCard }: { simCard: SimCard }) {
  const [showCredentials, setShowCredentials] = useState(false);
  const [credentials, setCredentials] = useState<{ pin: string | null; puk: string | null } | null>(null);
  const [isLoading, setIsLoading] = useState(false);

  const handleShowCredentials = async () => {
    if (showCredentials) {
      setShowCredentials(false);
      setCredentials(null);
      return;
    }
    setIsLoading(true);
    try {
      const res = await contractApi.getSimCardCredentials(simCard.id);
      if (!res?.data) {
        toast.error('Backend lieferte keine PIN/PUK-Daten zurück');
        return;
      }
      if (!res.data.pin && !res.data.puk) {
        toast('Für diese SIM sind keine PIN/PUK hinterlegt', { icon: 'ℹ️' });
      }
      setCredentials(res.data);
      setShowCredentials(true);
    } catch (err) {
      const msg = err instanceof Error ? err.message : 'Unbekannter Fehler';
      // eslint-disable-next-line no-console
      console.error('[SimCardDisplay] getSimCardCredentials failed:', err);
      toast.error(`PIN/PUK konnte nicht geladen werden: ${msg}`);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <div className="p-3 bg-gray-50 rounded-lg border">
      <div className="flex items-center gap-2 mb-2 flex-wrap">
        {simCard.isMain && <Badge variant="success">Hauptkarte</Badge>}
        {simCard.isEsim && <Badge variant="info">eSIM</Badge>}
        {simCard.isMultisim && <Badge variant="warning">Multisim</Badge>}
        {simCard.cardUser && (
          <span className="text-sm text-gray-700">
            <span className="text-gray-500">Nutzer:</span>{' '}
            <span className="font-medium">{simCard.cardUser}</span>
          </span>
        )}
      </div>
      <dl className="grid grid-cols-2 md:grid-cols-4 gap-3 text-sm">
        {simCard.phoneNumber && (
          <div>
            <dt className="text-gray-500">Rufnummer</dt>
            <dd className="font-mono flex items-center gap-1">
              {simCard.phoneNumber}
              <CopyButton value={simCard.phoneNumber} />
            </dd>
          </div>
        )}
        {simCard.simCardNumber && (
          <div>
            <dt className="text-gray-500">SIM-Nr.</dt>
            <dd className="font-mono text-xs flex items-center gap-1">
              {simCard.simCardNumber}
              <CopyButton value={simCard.simCardNumber} />
            </dd>
          </div>
        )}
        <div>
          <dt className="text-gray-500">PIN</dt>
          <dd className="font-mono flex items-center gap-1">
            {showCredentials && credentials?.pin ? (
              <>
                {credentials.pin}
                <CopyButton value={credentials.pin} />
              </>
            ) : '••••'}
          </dd>
        </div>
        <div>
          <dt className="text-gray-500">PUK</dt>
          <dd className="font-mono flex items-center gap-1">
            {showCredentials && credentials?.puk ? (
              <>
                {credentials.puk}
                <CopyButton value={credentials.puk} />
              </>
            ) : '••••••••'}
          </dd>
        </div>
      </dl>
      <div className="mt-2">
        <Button
          variant="ghost"
          size="sm"
          onClick={handleShowCredentials}
          disabled={isLoading}
        >
          {isLoading ? 'Laden...' : showCredentials ? (
            <><EyeOff className="w-4 h-4 mr-1" /> PIN/PUK verbergen</>
          ) : (
            <><Eye className="w-4 h-4 mr-1" /> PIN/PUK anzeigen</>
          )}
        </Button>
      </div>
    </div>
  );
}

// Meter Readings Section Component
function MeterReadingsSection({
  meterId,
  meterType,
  tariffModel,
  readings,
  canEdit,
  label,
}: {
  meterId: number;
  meterType: 'ELECTRICITY' | 'GAS';
  tariffModel?: string;
  readings: MeterReading[];
  canEdit: boolean;
  label?: string;
}) {
  const isDualTariff = tariffModel === 'DUAL';
  const [isExpanded, setIsExpanded] = useState(false);
  const [showAddModal, setShowAddModal] = useState(false);
  const [editingReading, setEditingReading] = useState<MeterReading | null>(null);
  const queryClient = useQueryClient();

  const deleteReadingMutation = useMutation({
    mutationFn: (readingId: number) => meterApi.deleteReading(meterId, readingId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract'] });
    },
  });

  // Sort readings by date (newest first)
  const sortedReadings = [...readings].sort(
    (a, b) => new Date(b.readingDate).getTime() - new Date(a.readingDate).getTime()
  );

  const defaultUnit = meterType === 'ELECTRICITY' ? 'kWh' : 'm³';

  return (
    <div className="mt-4 pt-4 border-t">
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-center gap-2">
          <Gauge className="w-4 h-4 text-gray-500" />
          <h4 className="text-sm font-medium text-gray-700">{label || 'Zählerstände'}</h4>
          <Badge variant="default">{readings.length}</Badge>
        </div>
        <div className="flex items-center gap-2">
          {canEdit && (
            <Button
              variant="ghost"
              size="sm"
              onClick={() => setShowAddModal(true)}
              title="Zählerstand erfassen"
            >
              <Plus className="w-4 h-4" />
            </Button>
          )}
          {readings.length > 0 && (
            <Button
              variant="ghost"
              size="sm"
              onClick={() => setIsExpanded(!isExpanded)}
            >
              {isExpanded ? (
                <ChevronUp className="w-4 h-4" />
              ) : (
                <ChevronDown className="w-4 h-4" />
              )}
            </Button>
          )}
        </div>
      </div>

      {isExpanded && readings.length > 0 && (
        <div className="space-y-2 bg-gray-50 rounded-lg p-3">
          {sortedReadings.map((reading) => (
            <div
              key={reading.id}
              className="flex justify-between items-center text-sm group py-1 border-b border-gray-200 last:border-0"
            >
              <span className="text-gray-500 flex items-center gap-1">
                {formatDate(reading.readingDate)}
                <CopyButton value={formatDate(reading.readingDate)} />
              </span>
              <div className="flex items-center gap-2">
                <span className="font-mono flex items-center gap-1">
                  {isDualTariff && reading.valueNt != null ? (
                    <>HT: {reading.value.toLocaleString('de-DE')} / NT: {reading.valueNt.toLocaleString('de-DE')} {reading.unit}</>
                  ) : (
                    <>{reading.value.toLocaleString('de-DE')} {reading.unit}</>
                  )}
                  <CopyButton value={reading.value.toString()} title="Wert kopieren" />
                </span>
                {canEdit && (
                  <div className="opacity-0 group-hover:opacity-100 flex gap-1">
                    <button
                      onClick={() => setEditingReading(reading)}
                      className="text-gray-400 hover:text-blue-600"
                      title="Bearbeiten"
                    >
                      <Edit className="w-3 h-3" />
                    </button>
                    <button
                      onClick={() => {
                        if (confirm('Zählerstand wirklich löschen?')) {
                          deleteReadingMutation.mutate(reading.id);
                        }
                      }}
                      className="text-gray-400 hover:text-red-600"
                      title="Löschen"
                    >
                      <Trash2 className="w-3 h-3" />
                    </button>
                  </div>
                )}
              </div>
            </div>
          ))}
        </div>
      )}

      {!isExpanded && readings.length > 0 && (
        <p className="text-sm text-gray-500">
          Letzter Stand: {sortedReadings[0].value.toLocaleString('de-DE')} {sortedReadings[0].unit} ({formatDate(sortedReadings[0].readingDate)})
        </p>
      )}

      {readings.length === 0 && (
        <p className="text-sm text-gray-500">Keine Zählerstände vorhanden.</p>
      )}

      {/* Add/Edit Reading Modal */}
      {(showAddModal || editingReading) && (
        <MeterReadingModal
          isOpen={true}
          onClose={() => {
            setShowAddModal(false);
            setEditingReading(null);
          }}
          meterId={meterId}
          reading={editingReading}
          defaultUnit={defaultUnit}
          tariffModel={tariffModel}
        />
      )}
    </div>
  );
}

// Meter Reading Modal Component
function SuccessorMeterButton({
  contractId,
  customerId,
  meterType,
  existingMeterIds,
}: {
  contractId: number;
  customerId: number;
  meterType: string;
  existingMeterIds: number[];
}) {
  const [showForm, setShowForm] = useState(false);
  const [selectedMeterId, setSelectedMeterId] = useState('');
  const [installedAt, setInstalledAt] = useState(new Date().toISOString().split('T')[0]);
  const [finalReading, setFinalReading] = useState('');
  const [deactivatePredecessor, setDeactivatePredecessor] = useState(true);
  const queryClient = useQueryClient();

  const { data: metersData } = useQuery({
    queryKey: ['customer-meters', customerId],
    queryFn: () => meterApi.getByCustomer(customerId),
    enabled: showForm,
  });

  const addMutation = useMutation({
    mutationFn: (data: { meterId: number; installedAt?: string; finalReadingPrevious?: number; deactivatePredecessor?: boolean }) =>
      contractApi.addSuccessorMeter(contractId, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract'] });
      setShowForm(false);
      setSelectedMeterId('');
      setFinalReading('');
      setDeactivatePredecessor(true);
    },
  });

  // Nur Zähler gleichen Typs anzeigen die noch nicht am Vertrag sind
  const availableMeters = (metersData?.data || []).filter(
    (m) => m.type === meterType && !existingMeterIds.includes(m.id) && m.isActive
  );

  if (!showForm) {
    return (
      <div className="mt-3 pt-3 border-t">
        <Button variant="secondary" size="sm" onClick={() => setShowForm(true)}>
          <Plus className="w-4 h-4 mr-1" />
          Folgezähler hinzufügen
        </Button>
      </div>
    );
  }

  return (
    <div className="mt-3 pt-3 border-t bg-blue-50 rounded-lg p-4">
      <div className="flex items-center gap-3 mb-3">
        <h4 className="text-sm font-medium">Folgezähler hinzufügen (Zählerwechsel)</h4>
        <Link
          to={`/customers/${customerId}?tab=meters`}
          target="_blank"
          rel="noopener noreferrer"
          className="inline-flex items-center gap-1 text-xs text-blue-600 hover:text-blue-800 hover:underline font-normal"
          title="Zähler-Übersicht des Kunden in neuem Tab öffnen"
        >
          <ExternalLink className="w-3 h-3" />
          Zähler verwalten
        </Link>
      </div>
      <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Neuer Zähler *</label>
          <select
            value={selectedMeterId}
            onChange={(e) => setSelectedMeterId(e.target.value)}
            className="block w-full px-3 py-2 border border-gray-300 rounded-lg text-sm"
          >
            <option value="">Bitte wählen...</option>
            {availableMeters.map((m) => (
              <option key={m.id} value={m.id}>
                {m.meterNumber} {m.location ? `(${m.location})` : ''}
              </option>
            ))}
          </select>
          {availableMeters.length === 0 && (
            <p className="text-xs text-amber-600 mt-1">Kein passender Zähler verfügbar. Bitte zuerst beim Kunden anlegen.</p>
          )}
        </div>
        <Input
          label="Wechseldatum"
          type="date"
          value={installedAt}
          onChange={(e) => setInstalledAt(e.target.value)}
        />
        <Input
          label="Letzter Stand alter Zähler"
          type="number"
          step="0.01"
          value={finalReading}
          onChange={(e) => setFinalReading(e.target.value)}
          placeholder="Optional"
        />
      </div>
      {finalReading && (
        <p className="text-xs text-blue-700 mt-2">
          Wird automatisch als Zählerstand des alten Zählers zum Wechseldatum
          erfasst und fließt damit in die Verbrauchsberechnung ein.
        </p>
      )}
      <label className="flex items-center gap-2 mt-3 text-sm">
        <input
          type="checkbox"
          checked={deactivatePredecessor}
          onChange={(e) => setDeactivatePredecessor(e.target.checked)}
          className="rounded"
        />
        Alten Zähler deaktivieren
      </label>
      <div className="flex gap-2 mt-3">
        <Button
          size="sm"
          onClick={() => addMutation.mutate({
            meterId: parseInt(selectedMeterId),
            installedAt,
            finalReadingPrevious: finalReading ? parseFloat(finalReading) : undefined,
            deactivatePredecessor,
          })}
          disabled={!selectedMeterId || addMutation.isPending}
        >
          {addMutation.isPending ? 'Speichern...' : 'Hinzufügen'}
        </Button>
        <Button variant="secondary" size="sm" onClick={() => setShowForm(false)}>
          Abbrechen
        </Button>
      </div>
      {addMutation.isError && (
        <p className="text-xs text-red-600 mt-2">
          {addMutation.error instanceof Error ? addMutation.error.message : 'Fehler beim Hinzufügen'}
        </p>
      )}
    </div>
  );
}

function MeterReadingModal({
  isOpen,
  onClose,
  meterId,
  reading,
  defaultUnit,
  tariffModel,
}: {
  isOpen: boolean;
  onClose: () => void;
  meterId: number;
  reading?: MeterReading | null;
  defaultUnit: string;
  tariffModel?: string;
}) {
  const queryClient = useQueryClient();
  const isDualTariff = tariffModel === 'DUAL';
  const isEditing = !!reading;

  const [formData, setFormData] = useState({
    readingDate: reading?.readingDate
      ? new Date(reading.readingDate).toISOString().split('T')[0]
      : new Date().toISOString().split('T')[0],
    value: reading?.value?.toString() || '',
    valueNt: reading?.valueNt?.toString() || '',
    notes: reading?.notes || '',
  });

  const [error, setError] = useState<string | null>(null);

  const createMutation = useMutation({
    mutationFn: (data: Partial<MeterReading>) => meterApi.addReading(meterId, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract'] });
      setError(null);
      onClose();
    },
    onError: (err) => {
      setError(err instanceof Error ? err.message : 'Fehler beim Speichern');
    },
  });

  const updateMutation = useMutation({
    mutationFn: (data: Partial<MeterReading>) => meterApi.updateReading(meterId, reading!.id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract'] });
      setError(null);
      onClose();
    },
    onError: (err) => {
      setError(err instanceof Error ? err.message : 'Fehler beim Speichern');
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const data: Record<string, unknown> = {
      readingDate: new Date(formData.readingDate),
      value: parseFloat(formData.value),
      unit: defaultUnit,
      notes: formData.notes || undefined,
    };
    if (isDualTariff && formData.valueNt) {
      data.valueNt = parseFloat(formData.valueNt);
    }
    if (isEditing) {
      updateMutation.mutate(data as unknown as Partial<MeterReading>);
    } else {
      createMutation.mutate(data as unknown as Partial<MeterReading>);
    }
  };

  const isPending = createMutation.isPending || updateMutation.isPending;

  return (
    <Modal isOpen={isOpen} onClose={onClose} title={isEditing ? 'Zählerstand bearbeiten' : 'Zählerstand erfassen'}>
      <form onSubmit={handleSubmit} className="space-y-4">
        <Input
          label="Ablesedatum"
          type="date"
          value={formData.readingDate}
          onChange={(e) => setFormData({ ...formData, readingDate: e.target.value })}
          required
        />

        <div className={`grid ${isDualTariff ? 'grid-cols-2' : 'grid-cols-3'} gap-4`}>
          <div className={isDualTariff ? '' : 'col-span-2'}>
            <Input
              label={isDualTariff ? 'HT-Stand (Hochtarif)' : 'Zählerstand'}
              type="number"
              step="0.01"
              value={formData.value}
              onChange={(e) => setFormData({ ...formData, value: e.target.value })}
              required
            />
          </div>
          {isDualTariff && (
            <div>
              <Input
                label="NT-Stand (Niedertarif)"
                type="number"
                step="0.01"
                value={formData.valueNt}
                onChange={(e) => setFormData({ ...formData, valueNt: e.target.value })}
                required
              />
            </div>
          )}
          {!isDualTariff && (
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">Einheit</label>
              <div className="h-10 flex items-center px-3 bg-gray-100 border border-gray-300 rounded-md text-gray-700">
                {defaultUnit}
              </div>
            </div>
          )}
        </div>

        <Input
          label="Notizen (optional)"
          value={formData.notes}
          onChange={(e) => setFormData({ ...formData, notes: e.target.value })}
        />

        {error && (
          <div className="p-3 bg-red-50 border border-red-200 rounded-lg text-sm text-red-700">
            {error}
          </div>
        )}

        <div className="flex justify-end gap-2 pt-4">
          <Button type="button" variant="secondary" onClick={onClose}>
            Abbrechen
          </Button>
          <Button type="submit" disabled={isPending || !formData.value}>
            {isPending ? 'Speichern...' : isEditing ? 'Speichern' : 'Erfassen'}
          </Button>
        </div>
      </form>
    </Modal>
  );
}

// Energy Consumption and Cost Calculation Component
function EnergyConsumptionCalculation({
  contractType,
  readings,
  startDate,
  endDate,
  basePrice,
  unitPrice,
  unitPriceNt,
  instantBonus,
  newCustomerBonus,
  hasMeter,
  contractMeters,
}: {
  contractType: 'ELECTRICITY' | 'GAS';
  readings: MeterReading[];
  startDate?: string;
  endDate?: string;
  basePrice?: number;
  unitPrice?: number;
  instantBonus?: number;
  newCustomerBonus?: number;
  unitPriceNt?: number;
  hasMeter?: boolean;
  contractMeters?: ContractMeter[];
}) {
  // Fehlende Felder ermitteln
  const missingFields: string[] = [];
  if (!startDate) missingFields.push('Vertragsbeginn');
  if (!endDate) missingFields.push('Vertragsende');
  if (!hasMeter) missingFields.push('Zähler verknüpft');
  if (basePrice == null) missingFields.push('Grundpreis');
  if (unitPrice == null) missingFields.push('Arbeitspreis');

  const hasRequiredDates = !!startDate && !!endDate;

  // Alle Readings über alle Zähler zählen
  const allReadingsCount = contractMeters && contractMeters.length > 0
    ? contractMeters.reduce((sum, cm) => sum + (cm.meter?.readings?.length || 0), 0)
    : readings.length;

  if (hasRequiredDates && hasMeter && allReadingsCount < 2) {
    missingFields.push(`Mindestens 2 Zählerstände im Vertragszeitraum (${allReadingsCount} vorhanden)`);
  }

  // Berechnung: Multi-Zähler wenn vorhanden, sonst Single
  let consumption = null;
  if (hasRequiredDates) {
    if (contractMeters && contractMeters.length > 1) {
      consumption = calculateMultiMeterConsumption(contractMeters, startDate!, endDate!, contractType);
    } else {
      consumption = calculateConsumption(readings, startDate!, endDate!, contractType);
    }
  }

  const htKwh = consumption?.consumptionHt ?? consumption?.consumptionKwh ?? 0;
  const ntKwh = consumption?.consumptionNt;
  const costs = consumption && consumption.consumptionKwh > 0
    ? calculateCosts(htKwh, basePrice, unitPrice, instantBonus, ntKwh, unitPriceNt, newCustomerBonus)
    : null;

  const canCalculate = consumption && (consumption.type === 'exact' || consumption.type === 'projected');

  // Wenn Berechnung fehlschlägt aber keine Felder fehlen → Hinweis aus der Berechnung anzeigen
  if (!canCalculate && consumption && missingFields.length === 0) {
    if (consumption.type === 'insufficient' && consumption.message) {
      missingFields.push(consumption.message);
    } else if (consumption.type === 'none') {
      missingFields.push('Keine Zählerstände im Vertragszeitraum vorhanden');
    }
  }

  const formatNumber = (num: number, decimals: number = 2) =>
    num.toLocaleString('de-DE', { minimumFractionDigits: decimals, maximumFractionDigits: decimals });

  const formatDate = (dateStr: string) =>
    new Date(dateStr).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });

  return (
    <div className="mt-4 pt-4 border-t">
      {/* Header */}
      <div className="flex items-center gap-2 mb-3">
        <Calculator className="w-4 h-4 text-gray-500" />
        <h4 className="text-sm font-medium text-gray-700">Verbrauch & Kosten</h4>
        {canCalculate && consumption!.type === 'exact' && (
          <Badge variant="success">Exakt</Badge>
        )}
        {canCalculate && consumption!.type === 'projected' && (
          <Badge variant="warning">Hochrechnung</Badge>
        )}
      </div>

      {/* Fehlende Daten */}
      {!canCalculate ? (
        <div className="bg-gray-50 rounded-lg p-4">
          <p className="text-sm text-gray-600 mb-3">
            Für die Berechnung fehlen noch folgende Angaben:
          </p>
          <ul className="space-y-1.5">
            {missingFields.map((field) => (
              <li key={field} className="flex items-center gap-2 text-sm">
                <Circle className="w-3 h-3 text-gray-300 flex-shrink-0" />
                <span className="text-gray-500">{field}</span>
              </li>
            ))}
          </ul>
          {consumption?.type === 'insufficient' && (
            <p className="text-sm text-amber-600 mt-3 italic">{consumption.message}</p>
          )}
        </div>
      ) : (
        <div className="bg-gray-50 rounded-lg p-4 space-y-4">
          {/* Verbrauchsanzeige */}
          <div>
            <h5 className="text-sm font-medium text-gray-600 mb-2">
              Berechneter Verbrauch
              {consumption!.type === 'projected' && ' (hochgerechnet)'}
            </h5>
            <div className="text-lg font-semibold text-gray-900">
              {contractType === 'GAS' ? (
                <>
                  <span className="font-mono">{formatNumber(consumption!.consumptionM3 || 0)} m³</span>
                  <span className="text-gray-500 text-sm ml-2">
                    = {formatNumber(consumption!.consumptionKwh)} kWh
                  </span>
                </>
              ) : consumption!.consumptionHt !== undefined && consumption!.consumptionNt !== undefined ? (
                <div className="space-y-1">
                  <div><span className="text-sm text-gray-500">HT:</span> <span className="font-mono">{formatNumber(consumption!.consumptionHt)} kWh</span></div>
                  <div><span className="text-sm text-gray-500">NT:</span> <span className="font-mono">{formatNumber(consumption!.consumptionNt)} kWh</span></div>
                  <div className="text-sm text-gray-500">Gesamt: {formatNumber(consumption!.consumptionKwh)} kWh</div>
                </div>
              ) : (
                <span className="font-mono">{formatNumber(consumption!.consumptionKwh)} kWh</span>
              )}
            </div>
            {consumption!.startReading && consumption!.endReading && (
              <p className="text-xs text-gray-400 mt-1">
                Basierend auf Zählerständen vom {formatDate(consumption!.startReading.readingDate)} bis {formatDate(consumption!.endReading.readingDate)}
              </p>
            )}
          </div>

          {/* Kostenrechnung */}
          {costs && (
            <div className="border-t border-gray-200 pt-4">
              <h5 className="text-sm font-medium text-gray-600 mb-3">Kostenvorschau</h5>
              <div className="space-y-2 text-sm">
                {/* Grundpreis */}
                {basePrice != null && basePrice > 0 && (
                  <div className="flex justify-between">
                    <span className="text-gray-600">
                      Grundpreis: {formatNumber(basePrice)} €/Mon × 12
                    </span>
                    <span className="font-mono">{formatNumber(costs.annualBaseCost)} €</span>
                  </div>
                )}
                {/* Arbeitspreis HT */}
                {unitPrice != null && unitPrice > 0 && (
                  <div className="flex justify-between">
                    <span className="text-gray-600">
                      {costs.annualConsumptionCostNt ? 'HT-Arbeitspreis' : 'Arbeitspreis'}: {formatNumber(htKwh)} kWh × {formatNumber(unitPrice, 4)} €
                    </span>
                    <span className="font-mono">{formatNumber(costs.annualConsumptionCost)} €</span>
                  </div>
                )}
                {/* Arbeitspreis NT */}
                {costs.annualConsumptionCostNt != null && costs.annualConsumptionCostNt > 0 && unitPriceNt && (
                  <div className="flex justify-between">
                    <span className="text-gray-600">
                      NT-Arbeitspreis: {formatNumber(ntKwh || 0)} kWh × {formatNumber(unitPriceNt, 4)} €
                    </span>
                    <span className="font-mono">{formatNumber(costs.annualConsumptionCostNt)} €</span>
                  </div>
                )}
                {/* Trennlinie */}
                <div className="border-t border-gray-300 pt-2">
                  <div className="flex justify-between font-medium">
                    <span className="text-gray-700">Jahreskosten</span>
                    <span className="font-mono">{formatNumber(costs.annualTotalCost)} €</span>
                  </div>
                </div>
                {/* Bonus – Sofort + Neukunden einzeln, dann Gesamt */}
                {costs.totalBonus != null && costs.totalBonus > 0 && (
                  <>
                    {costs.instantBonus != null && costs.instantBonus > 0 && (
                      <div className="flex justify-between text-green-600">
                        <span>Sofort-Bonus</span>
                        <span className="font-mono">- {formatNumber(costs.instantBonus)} €</span>
                      </div>
                    )}
                    {costs.newCustomerBonus != null && costs.newCustomerBonus > 0 && (
                      <div className="flex justify-between text-green-600">
                        <span>Neukunden-Bonus</span>
                        <span className="font-mono">- {formatNumber(costs.newCustomerBonus)} €</span>
                      </div>
                    )}
                    <div className="flex justify-between text-green-700 font-medium">
                      <span>Gesamtbonus</span>
                      <span className="font-mono">- {formatNumber(costs.totalBonus)} €</span>
                    </div>
                    <div className="border-t border-gray-300 pt-2">
                      <div className="flex justify-between font-semibold">
                        <span className="text-gray-800">Effektive Jahreskosten</span>
                        <span className="font-mono">{formatNumber(costs.effectiveAnnualCost)} €</span>
                      </div>
                    </div>
                  </>
                )}
                {/* Monatlicher Abschlag */}
                <div className="border-t border-gray-300 pt-2 mt-2">
                  <div className="flex justify-between text-blue-700 font-semibold">
                    <span>Monatlicher Abschlag</span>
                    <span className="font-mono">{formatNumber(costs.monthlyPayment)} €</span>
                  </div>
                </div>
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// Contract Task Item Component (handles subtasks)
function ContractTaskItem({
  task,
  contractId,
  canEdit,
  isCustomerPortal,
  isCompleted,
  onEdit,
}: {
  task: ContractTask;
  contractId: number;
  canEdit: boolean;
  isCustomerPortal: boolean;
  isCompleted: boolean;
  onEdit: () => void;
}) {
  const [newSubtaskTitle, setNewSubtaskTitle] = useState('');
  const [showSubtaskInput, setShowSubtaskInput] = useState(false);
  const [editingSubtaskId, setEditingSubtaskId] = useState<number | null>(null);
  const [editSubtaskTitle, setEditSubtaskTitle] = useState('');
  const queryClient = useQueryClient();

  const completeMutation = useMutation({
    mutationFn: (taskId: number) => contractTaskApi.complete(taskId),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
    },
  });

  const reopenMutation = useMutation({
    mutationFn: (taskId: number) => contractTaskApi.reopen(taskId),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (taskId: number) => contractTaskApi.delete(taskId),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
    },
  });

  const createSubtaskMutation = useMutation({
    mutationFn: (title: string) => contractTaskApi.createSubtask(task.id, title),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
      setNewSubtaskTitle('');
      setShowSubtaskInput(false);
    },
    onError: (error) => {
      console.error('Fehler beim Erstellen der Unteraufgabe:', error);
      alert('Fehler beim Erstellen der Unteraufgabe. Bitte versuchen Sie es erneut.');
    },
  });

  // Kundenportal: Antwort auf eigenes Ticket
  const createReplyMutation = useMutation({
    mutationFn: (title: string) => contractTaskApi.createReply(task.id, title),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
      setNewSubtaskTitle('');
      setShowSubtaskInput(false);
    },
    onError: (error) => {
      console.error('Fehler beim Erstellen der Antwort:', error);
      alert('Fehler beim Erstellen der Antwort. Bitte versuchen Sie es erneut.');
    },
  });

  const updateSubtaskMutation = useMutation({
    mutationFn: ({ id, title }: { id: number; title: string }) => contractTaskApi.updateSubtask(id, title),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
      setEditingSubtaskId(null);
      setEditSubtaskTitle('');
    },
  });

  const completeSubtaskMutation = useMutation({
    mutationFn: (subtaskId: number) => contractTaskApi.completeSubtask(subtaskId),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
    },
  });

  const reopenSubtaskMutation = useMutation({
    mutationFn: (subtaskId: number) => contractTaskApi.reopenSubtask(subtaskId),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
    },
  });

  const deleteSubtaskMutation = useMutation({
    mutationFn: (subtaskId: number) => contractTaskApi.deleteSubtask(subtaskId),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
    },
  });

  const handleAddSubtask = (e: React.FormEvent) => {
    e.preventDefault();
    if (newSubtaskTitle.trim()) {
      if (isCustomerPortal) {
        createReplyMutation.mutate(newSubtaskTitle.trim());
      } else {
        createSubtaskMutation.mutate(newSubtaskTitle.trim());
      }
    }
  };

  const handleEditSubtask = (e: React.FormEvent) => {
    e.preventDefault();
    if (editSubtaskTitle.trim() && editingSubtaskId) {
      updateSubtaskMutation.mutate({ id: editingSubtaskId, title: editSubtaskTitle.trim() });
    }
  };

  const startEditingSubtask = (subtaskId: number, currentTitle: string) => {
    setEditingSubtaskId(subtaskId);
    setEditSubtaskTitle(currentTitle);
  };

  const cancelEditingSubtask = () => {
    setEditingSubtaskId(null);
    setEditSubtaskTitle('');
  };

  const subtasks = task.subtasks || [];
  const openSubtasks = subtasks.filter(s => s.status === 'OPEN');
  const completedSubtasks = subtasks.filter(s => s.status === 'COMPLETED');

  // Labels für Subtasks (Antwort im Portal, Unteraufgabe für Mitarbeiter)
  const subtaskLabels = isCustomerPortal
    ? { singular: 'Antwort', placeholder: 'Antwort...', deleteConfirm: 'Antwort löschen?' }
    : { singular: 'Unteraufgabe', placeholder: 'Unteraufgabe...', deleteConfirm: 'Unteraufgabe löschen?' };

  // Render a single subtask row
  const renderSubtask = (subtask: ContractTaskSubtask, isSubtaskCompleted: boolean) => {
    const isEditing = editingSubtaskId === subtask.id;

    if (isEditing) {
      return (
        <div key={subtask.id} className="py-1">
          <form onSubmit={handleEditSubtask} className="flex items-center gap-2">
            <Circle className="w-4 h-4 text-gray-300 flex-shrink-0" />
            <input
              type="text"
              value={editSubtaskTitle}
              onChange={(e) => setEditSubtaskTitle(e.target.value)}
              className="flex-1 text-sm px-2 py-1 border rounded focus:outline-none focus:ring-1 focus:ring-blue-500"
              autoFocus
            />
            <Button type="submit" size="sm" disabled={!editSubtaskTitle.trim() || updateSubtaskMutation.isPending}>
              ✓
            </Button>
            <Button type="button" variant="ghost" size="sm" onClick={cancelEditingSubtask}>
              ×
            </Button>
          </form>
        </div>
      );
    }

    return (
      <div key={subtask.id} className={`py-1 group/subtask ${isSubtaskCompleted ? 'opacity-60' : ''}`}>
        <div className="flex items-start gap-2">
          <button
            onClick={() => isSubtaskCompleted
              ? reopenSubtaskMutation.mutate(subtask.id)
              : completeSubtaskMutation.mutate(subtask.id)
            }
            disabled={completeSubtaskMutation.isPending || reopenSubtaskMutation.isPending || isCustomerPortal}
            className={`flex-shrink-0 mt-0.5 ${isCustomerPortal ? 'cursor-default' : isSubtaskCompleted ? 'hover:text-yellow-600' : 'hover:text-green-600'}`}
          >
            {isSubtaskCompleted ? (
              <CheckCircle className="w-4 h-4 text-green-500" />
            ) : (
              <Circle className="w-4 h-4 text-gray-400" />
            )}
          </button>
          <div className="flex-1 min-w-0">
            <div className="flex items-center gap-1">
              <span className={`text-sm ${isSubtaskCompleted ? 'line-through text-gray-500' : ''}`}>
                {subtask.title}
              </span>
              {canEdit && !isCustomerPortal && !isSubtaskCompleted && (
                <div className="flex items-center gap-0.5 opacity-0 group-hover/subtask:opacity-100">
                  <button
                    onClick={() => startEditingSubtask(subtask.id, subtask.title)}
                    className="text-gray-400 hover:text-blue-600 p-0.5"
                    title="Bearbeiten"
                  >
                    <Edit className="w-3 h-3" />
                  </button>
                  <button
                    onClick={() => {
                      if (confirm(subtaskLabels.deleteConfirm)) {
                        deleteSubtaskMutation.mutate(subtask.id);
                      }
                    }}
                    className="text-gray-400 hover:text-red-600 p-0.5"
                    title="Löschen"
                  >
                    <Trash2 className="w-3 h-3" />
                  </button>
                </div>
              )}
              {canEdit && !isCustomerPortal && isSubtaskCompleted && (
                <button
                  onClick={() => {
                    if (confirm(subtaskLabels.deleteConfirm)) {
                      deleteSubtaskMutation.mutate(subtask.id);
                    }
                  }}
                  className="text-gray-400 hover:text-red-600 p-0.5 opacity-0 group-hover/subtask:opacity-100"
                  title="Löschen"
                >
                  <Trash2 className="w-3 h-3" />
                </button>
              )}
            </div>
            <p className="text-xs text-gray-400">
              {subtask.createdBy && `${subtask.createdBy} • `}
              {isSubtaskCompleted
                ? `Erledigt am ${subtask.completedAt ? formatDate(subtask.completedAt) : formatDate(subtask.updatedAt)}`
                : formatDate(subtask.createdAt)}
            </p>
          </div>
        </div>
      </div>
    );
  };

  return (
    <div className={`p-3 bg-gray-50 rounded-lg group ${isCompleted ? 'bg-gray-50/50 opacity-70' : ''}`}>
      <div className="flex items-start gap-3">
        <button
          onClick={() => isCompleted ? reopenMutation.mutate(task.id) : completeMutation.mutate(task.id)}
          disabled={completeMutation.isPending || reopenMutation.isPending || isCustomerPortal}
          className={`mt-0.5 flex-shrink-0 ${isCustomerPortal ? 'cursor-default' : isCompleted ? 'hover:text-yellow-600' : 'hover:text-green-600'}`}
          title={isCustomerPortal ? undefined : isCompleted ? 'Wieder öffnen' : 'Als erledigt markieren'}
        >
          {isCompleted ? (
            <CheckCircle className="w-5 h-5 text-green-500" />
          ) : (
            <Circle className="w-5 h-5 text-gray-400" />
          )}
        </button>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <span className={`font-medium ${isCompleted ? 'line-through text-gray-500' : ''}`}>{task.title}</span>
            {task.visibleInPortal && (
              <Badge variant="default" className="text-xs">Portal</Badge>
            )}
            {subtasks.length > 0 && (
              <span className="text-xs text-gray-400">
                ({completedSubtasks.length}/{subtasks.length})
              </span>
            )}
          </div>
          {task.description && (
            <p className={`text-sm mt-1 whitespace-pre-wrap ${isCompleted ? 'text-gray-500' : 'text-gray-600'}`}>
              {task.description}
            </p>
          )}
          <p className="text-xs text-gray-400 mt-1">
            {task.createdBy && `${task.createdBy} • `}
            {isCompleted
              ? `Erledigt am ${task.completedAt ? formatDate(task.completedAt) : '-'}`
              : formatDate(task.createdAt)}
          </p>

          {/* Subtasks */}
          {subtasks.length > 0 && (
            <div className="mt-3 ml-2 space-y-0 border-l-2 border-gray-200 pl-3">
              {openSubtasks.map((subtask) => renderSubtask(subtask, false))}
              {completedSubtasks.map((subtask) => renderSubtask(subtask, true))}
            </div>
          )}

          {/* Add Subtask */}
          {/* Subtask/Antwort hinzufügen: Mitarbeiter mit Berechtigung ODER Kundenportal.
              2026-07-04: bewusst OHNE isCompleted-Guard – man soll auch
              zu erledigten Aufgaben Nachträge anlegen können, ohne die
              Aufgabe erst wieder auf offen zu setzen. */}
          {((canEdit && !isCustomerPortal) || isCustomerPortal) && (
            <div className="mt-2 ml-2">
              {showSubtaskInput ? (
                <form onSubmit={handleAddSubtask} className="flex items-center gap-2">
                  <input
                    type="text"
                    value={newSubtaskTitle}
                    onChange={(e) => setNewSubtaskTitle(e.target.value)}
                    placeholder={subtaskLabels.placeholder}
                    className="flex-1 text-sm px-2 py-1 border rounded focus:outline-none focus:ring-1 focus:ring-blue-500"
                    autoFocus
                  />
                  <Button type="submit" size="sm" disabled={!newSubtaskTitle.trim() || createSubtaskMutation.isPending || createReplyMutation.isPending}>
                    <Plus className="w-3 h-3" />
                  </Button>
                  <Button type="button" variant="ghost" size="sm" onClick={() => { setShowSubtaskInput(false); setNewSubtaskTitle(''); }}>
                    ×
                  </Button>
                </form>
              ) : (
                <button
                  onClick={() => setShowSubtaskInput(true)}
                  className="text-xs text-gray-400 hover:text-blue-600 flex items-center gap-1"
                >
                  <Plus className="w-3 h-3" />
                  {subtaskLabels.singular}
                </button>
              )}
            </div>
          )}
        </div>
        {canEdit && !isCustomerPortal && (
          <div className="flex gap-1 opacity-0 group-hover:opacity-100">
            {/* 2026-07-04: Edit auch bei erledigten Aufgaben verfügbar. */}
            <button
              onClick={onEdit}
              className="text-gray-400 hover:text-blue-600 p-1"
              title="Bearbeiten"
            >
              <Edit className="w-4 h-4" />
            </button>
            <button
              onClick={() => {
                if (confirm('Aufgabe wirklich löschen?')) {
                  deleteMutation.mutate(task.id);
                }
              }}
              className="text-gray-400 hover:text-red-600 p-1"
              title="Löschen"
            >
              <Trash2 className="w-4 h-4" />
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

// Contract Tasks Section Component
function ContractTasksSection({
  contractId,
  canEdit,
  isCustomerPortal,
}: {
  contractId: number;
  canEdit: boolean;
  isCustomerPortal: boolean;
}) {
  const [showAddModal, setShowAddModal] = useState(false);
  const [editingTask, setEditingTask] = useState<ContractTask | null>(null);

  const { data: tasksData, isLoading } = useQuery({
    queryKey: ['contract-tasks', contractId],
    queryFn: () => contractTaskApi.getByContract(contractId),
    staleTime: 0, // Immer als "stale" behandeln
    gcTime: 0, // Kein Caching
    refetchOnMount: 'always', // Immer neu laden beim Mounten
  });

  // Lade öffentliche Einstellungen (für Kundenportal)
  const { data: settingsData, isLoading: isSettingsLoading } = useQuery({
    queryKey: ['app-settings-public'],
    queryFn: () => appSettingsApi.getPublic(),
    enabled: isCustomerPortal,
    staleTime: 0, // Immer neu laden, damit Einstellungsänderungen sofort wirken
  });

  // Wichtig: Nur true wenn explizit aktiviert UND geladen
  const supportTicketsEnabled = !isSettingsLoading && settingsData?.data?.customerSupportTicketsEnabled === 'true';

  const tasks = tasksData?.data || [];
  const openTasks = tasks.filter(t => t.status === 'OPEN');
  const completedTasks = tasks.filter(t => t.status === 'COMPLETED');

  // Labels je nach Portal/Mitarbeiter
  const labels = isCustomerPortal
    ? { title: 'Support-Anfragen', singular: 'Support-Anfrage', button: 'Anfrage erstellen', empty: 'Keine Support-Anfragen vorhanden.' }
    : { title: 'Aufgaben', singular: 'Aufgabe', button: 'Aufgabe', empty: 'Keine Aufgaben vorhanden.' };

  const IconComponent = isCustomerPortal ? MessageSquare : ClipboardList;

  // Warte auf beide Queries bevor gerändert wird
  const stillLoading = isLoading || (isCustomerPortal && isSettingsLoading);

  if (stillLoading) {
    return (
      <Card className="mb-6" title={labels.title}>
        <div className="text-center py-4 text-gray-500">Laden...</div>
      </Card>
    );
  }

  // Zeige Button wenn: Mitarbeiter mit Berechtigung ODER Kundenportal mit aktivierten Support-Tickets
  const canCreateTask = (canEdit && !isCustomerPortal) || (isCustomerPortal && supportTicketsEnabled);

  return (
    <Card className="mb-6" title={labels.title}>
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center gap-2">
          <IconComponent className="w-5 h-5 text-gray-500" />
          <span className="text-sm text-gray-600">
            {openTasks.length} offen, {completedTasks.length} erledigt
          </span>
        </div>
        {canCreateTask && (
          <Button size="sm" onClick={() => setShowAddModal(true)}>
            <Plus className="w-4 h-4 mr-1" />
            {labels.button}
          </Button>
        )}
      </div>

      {tasks.length === 0 ? (
        <p className="text-center py-4 text-gray-500">{labels.empty}</p>
      ) : (
        <div className="space-y-2">
          {/* Open Tasks first */}
          {openTasks.map((task) => (
            <ContractTaskItem
              key={task.id}
              task={task}
              contractId={contractId}
              canEdit={canEdit}
              isCustomerPortal={isCustomerPortal}
              isCompleted={false}
              onEdit={() => setEditingTask(task)}
            />
          ))}

          {/* Completed Tasks */}
          {completedTasks.length > 0 && openTasks.length > 0 && (
            <div className="border-t my-3" />
          )}
          {completedTasks.map((task) => (
            <ContractTaskItem
              key={task.id}
              task={task}
              contractId={contractId}
              canEdit={canEdit}
              isCustomerPortal={isCustomerPortal}
              isCompleted={true}
              onEdit={() => {}}
            />
          ))}
        </div>
      )}

      {/* Add/Edit Task Modal */}
      {(showAddModal || editingTask) && (
        <ContractTaskModal
          isOpen={true}
          onClose={() => {
            setShowAddModal(false);
            setEditingTask(null);
          }}
          contractId={contractId}
          task={editingTask}
          isCustomerPortal={isCustomerPortal}
        />
      )}
    </Card>
  );
}

// Contract Task Modal Component
function ContractTaskModal({
  isOpen,
  onClose,
  contractId,
  task,
  isCustomerPortal = false,
}: {
  isOpen: boolean;
  onClose: () => void;
  contractId: number;
  task?: ContractTask | null;
  isCustomerPortal?: boolean;
}) {
  const queryClient = useQueryClient();
  const isEditing = !!task;

  const [formData, setFormData] = useState({
    title: task?.title || '',
    description: task?.description || '',
    visibleInPortal: task?.visibleInPortal || false,
  });

  // Reset formData when modal opens or task changes
  useEffect(() => {
    if (isOpen) {
      setFormData({
        title: task?.title || '',
        description: task?.description || '',
        visibleInPortal: task?.visibleInPortal || false,
      });
    }
  }, [isOpen, task]);

  // Für Mitarbeiter: normale Task-Erstellung
  const createMutation = useMutation({
    mutationFn: (data: { title: string; description?: string; visibleInPortal?: boolean }) =>
      contractTaskApi.create(contractId, data),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
      onClose();
    },
  });

  // Für Kundenportal: Support-Ticket-Erstellung
  const createSupportTicketMutation = useMutation({
    mutationFn: (data: { title: string; description?: string }) =>
      contractTaskApi.createSupportTicket(contractId, data),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
      onClose();
    },
  });

  const updateMutation = useMutation({
    mutationFn: (data: { title?: string; description?: string; visibleInPortal?: boolean }) =>
      contractTaskApi.update(task!.id, data),
    onSuccess: async () => {
      await queryClient.refetchQueries({ queryKey: ['contract-tasks', contractId] });
      onClose();
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (isEditing) {
      updateMutation.mutate({
        title: formData.title,
        description: formData.description || undefined,
        visibleInPortal: formData.visibleInPortal,
      });
    } else if (isCustomerPortal) {
      // Kundenportal: Support-Ticket erstellen
      createSupportTicketMutation.mutate({
        title: formData.title,
        description: formData.description || undefined,
      });
    } else {
      // Mitarbeiter: normale Aufgabe erstellen
      createMutation.mutate({
        title: formData.title,
        description: formData.description || undefined,
        visibleInPortal: formData.visibleInPortal,
      });
    }
  };

  const isPending = createMutation.isPending || createSupportTicketMutation.isPending || updateMutation.isPending;

  // Labels für Kundenportal vs. Mitarbeiter
  const labels = isCustomerPortal
    ? {
        modalTitle: isEditing ? 'Anfrage bearbeiten' : 'Neue Support-Anfrage',
        titleLabel: 'Betreff',
        titlePlaceholder: 'Kurze Beschreibung Ihrer Anfrage',
        descLabel: 'Ihre Nachricht',
        descPlaceholder: 'Beschreiben Sie Ihr Anliegen...',
        submitBtn: isEditing ? 'Speichern' : 'Anfrage senden',
      }
    : {
        modalTitle: isEditing ? 'Aufgabe bearbeiten' : 'Neue Aufgabe',
        titleLabel: 'Titel',
        titlePlaceholder: 'Kurze Beschreibung der Aufgabe',
        descLabel: 'Beschreibung (optional)',
        descPlaceholder: 'Details zur Aufgabe...',
        submitBtn: isEditing ? 'Speichern' : 'Erstellen',
      };

  return (
    <Modal isOpen={isOpen} onClose={onClose} title={labels.modalTitle}>
      <form onSubmit={handleSubmit} className="space-y-4">
        <Input
          label={labels.titleLabel}
          value={formData.title}
          onChange={(e) => setFormData({ ...formData, title: e.target.value })}
          required
          placeholder={labels.titlePlaceholder}
        />

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            {labels.descLabel}
          </label>
          <textarea
            value={formData.description}
            onChange={(e) => setFormData({ ...formData, description: e.target.value })}
            className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
            rows={isCustomerPortal ? 5 : 3}
            placeholder={labels.descPlaceholder}
          />
        </div>

        {/* Portal-Sichtbarkeit nur für Mitarbeiter anzeigen */}
        {!isCustomerPortal && (
          <label className="flex items-center gap-2 cursor-pointer">
            <input
              type="checkbox"
              checked={formData.visibleInPortal}
              onChange={(e) => setFormData({ ...formData, visibleInPortal: e.target.checked })}
              className="w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
            />
            <span className="text-sm text-gray-700">Im Kundenportal sichtbar</span>
          </label>
        )}

        <div className="flex justify-end gap-2 pt-4">
          <Button type="button" variant="secondary" onClick={onClose}>
            Abbrechen
          </Button>
          <Button type="submit" disabled={isPending || !formData.title.trim()}>
            {isPending ? 'Speichern...' : labels.submitBtn}
          </Button>
        </div>
      </form>
    </Modal>
  );
}

export default function ContractDetail() {
  const { id } = useParams();
  const navigate = useNavigate();
  const location = useLocation();
  const queryClient = useQueryClient();
  const currentPath = `/contracts/${id}`;
  const { hasPermission, isCustomer, isCustomerPortal } = useAuth();
  const contractId = parseInt(id!);
  const { customerEmailLabel } = useProviderSettings();

  const [showPassword, setShowPassword] = useState(false);
  const [decryptedPassword, setDecryptedPassword] = useState<string | null>(null);
  const [isAutoLoginLoading, setIsAutoLoginLoading] = useState(false);

  // Internet-Zugangsdaten
  const [showInternetPassword, setShowInternetPassword] = useState(false);
  const [decryptedInternetPassword, setDecryptedInternetPassword] = useState<string | null>(null);

  // SIP-Passwörter (Map mit phoneNumberId als Key)
  const [showSipPasswords, setShowSipPasswords] = useState<Record<number, boolean>>({});
  const [decryptedSipPasswords, setDecryptedSipPasswords] = useState<Record<number, string | null>>({});

  // Modal für Vorgängervertrag
  const [showPredecessorModal, setShowPredecessorModal] = useState(false);

  // Bestätigungsdialog für Folgevertrag
  const [showFollowUpConfirm, setShowFollowUpConfirm] = useState(false);

  // Status-Info Modal
  const [showStatusInfo, setShowStatusInfo] = useState(false);

  // Un-Snooze Bestätigungsmodal
  const [showUnsnoozeConfirm, setShowUnsnoozeConfirm] = useState(false);

  // Kündigungsbestätigung-Upload: File gepuffert, Datum-Modal offen
  const [pendingCancelFile, setPendingCancelFile] = useState<File | null>(null);
  const [cancelConfirmDate, setCancelConfirmDate] = useState<string>(
    () => new Date().toISOString().split('T')[0]
  );

  // Kunden-Schnellansicht-Modal
  const [showCustomerInfo, setShowCustomerInfo] = useState(false);

  // PDF-Viewer-Modal (Bankkarte-/Ausweis-Dokument)
  const [pdfModal, setPdfModal] = useState<{ title: string; path: string } | null>(null);

  const { data, isLoading } = useQuery({
    queryKey: ['contract', id],
    queryFn: () => contractApi.getById(contractId),
  });

  // Consent-Check für den Kunden des Vertrags (nur für Mitarbeiter relevant)
  const contractCustomerId = data?.data?.customerId;
  const { data: consentStatusData } = useQuery({
    queryKey: ['consent-status', contractCustomerId],
    queryFn: () => gdprApi.checkConsentStatus(contractCustomerId!),
    enabled: !!contractCustomerId && !isCustomerPortal,
  });
  const hasConsentApproval = isCustomerPortal || (consentStatusData?.data?.hasConsent ?? true);

  const deleteMutation = useMutation({
    mutationFn: () => contractApi.delete(contractId),
    onSuccess: () => {
      // Nach dem Löschen die zentralen Vertragslisten + den Kunden-
      // Vertragsbaum invalidieren – sonst zeigt die Liste danach den
      // gerade gelöschten Vertrag noch an, während der ans /contracts
      // navigierte User den Eindruck bekommt, der Vorgänger sei mitgelöscht
      // worden (siehe Bug „Vertrag löscht ganze Historie").
      queryClient.invalidateQueries({ queryKey: ['contracts'] });
      if (contractCustomerId) {
        queryClient.invalidateQueries({ queryKey: ['contract-tree', contractCustomerId] });
        queryClient.invalidateQueries({ queryKey: ['customer', contractCustomerId] });
      }
      navigate('/contracts');
    },
    onError: (err) => {
      const msg = err instanceof Error ? err.message : 'Unbekannter Fehler';
      toast.error(`Löschen fehlgeschlagen: ${msg}`);
    },
  });

  const followUpMutation = useMutation({
    mutationFn: () => contractApi.createFollowUp(contractId),
    onSuccess: (data) => {
      if (data.data) {
        navigate(`/contracts/${data.data.id}/edit`);
      } else {
        alert('Folgevertrag wurde erstellt, aber keine ID zurückgegeben');
      }
    },
    onError: (error) => {
      console.error('Folgevertrag Fehler:', error);
      alert(`Fehler beim Erstellen des Folgevertrags: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}`);
    },
  });

  // VVL = Vertragsverlängerung beim selben Anbieter (alle Daten 1:1 + Datum berechnet)
  const renewalMutation = useMutation({
    mutationFn: () => contractApi.createRenewal(contractId),
    onSuccess: (data) => {
      if (data.data) {
        navigate(`/contracts/${data.data.id}/edit`);
      } else {
        alert('VVL wurde erstellt, aber keine ID zurückgegeben');
      }
    },
    onError: (error) => {
      console.error('VVL Fehler:', error);
      alert(`Fehler beim Erstellen der VVL: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}`);
    },
  });

  // Dropdown-Toggle für VVL
  const [showFollowUpMenu, setShowFollowUpMenu] = useState(false);
  const [showVvlConfirm, setShowVvlConfirm] = useState(false);

  // Un-Snooze Mutation
  const unsnoozeMutation = useMutation({
    mutationFn: () => contractApi.snooze(contractId, {}),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract', id] });
      queryClient.invalidateQueries({ queryKey: ['contract-cockpit'] });
      setShowUnsnoozeConfirm(false);
    },
    onError: (error) => {
      console.error('Un-Snooze Fehler:', error);
      alert(`Fehler beim Aufheben der Zurückstellung: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}`);
    },
  });

  // Mutation für Kündigungsbestätigungsdatum
  const updateCancellationDateMutation = useMutation({
    mutationFn: (date: string | null) => {
      // Datum in ISO-Format konvertieren für Backend
      const isoDate = date ? new Date(date).toISOString() : null;
      const payload: Record<string, unknown> = { cancellationConfirmationDate: isoDate };
      return contractApi.update(contractId, payload);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract', id] });
      queryClient.invalidateQueries({ queryKey: ['contract-cockpit'] });
    },
    onError: (error) => {
      console.error('Fehler beim Speichern des Datums:', error);
      alert('Fehler beim Speichern des Datums');
    },
  });

  // Mutation für Kündigungsbestätigungsoptionendatum
  const updateCancellationOptionsDateMutation = useMutation({
    mutationFn: (date: string | null) => {
      // Datum in ISO-Format konvertieren für Backend
      const isoDate = date ? new Date(date).toISOString() : null;
      const payload: Record<string, unknown> = { cancellationConfirmationOptionsDate: isoDate };
      return contractApi.update(contractId, payload);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract', id] });
      queryClient.invalidateQueries({ queryKey: ['contract-cockpit'] });
    },
    onError: (error) => {
      console.error('Fehler beim Speichern des Datums:', error);
      alert('Fehler beim Speichern des Datums');
    },
  });

  const handleShowPassword = async () => {
    if (showPassword) {
      setShowPassword(false);
      setDecryptedPassword(null);
    } else {
      try {
        const res = await contractApi.getPassword(contractId);
        if (res.data?.password) {
          setDecryptedPassword(res.data.password);
          setShowPassword(true);
        }
      } catch (err) {
        alert('Passwort konnte nicht entschlüsselt werden');
      }
    }
  };

  const handleShowInternetPassword = async () => {
    if (showInternetPassword) {
      setShowInternetPassword(false);
      setDecryptedInternetPassword(null);
    } else {
      try {
        const res = await contractApi.getInternetCredentials(contractId);
        if (res.data?.password) {
          setDecryptedInternetPassword(res.data.password);
          setShowInternetPassword(true);
        }
      } catch (err) {
        alert('Internet-Passwort konnte nicht entschlüsselt werden');
      }
    }
  };

  const handleShowSipPassword = async (phoneNumberId: number) => {
    if (showSipPasswords[phoneNumberId]) {
      setShowSipPasswords(prev => ({ ...prev, [phoneNumberId]: false }));
      setDecryptedSipPasswords(prev => ({ ...prev, [phoneNumberId]: null }));
    } else {
      try {
        const res = await contractApi.getSipCredentials(phoneNumberId);
        const password = res.data?.password;
        if (password) {
          setDecryptedSipPasswords(prev => ({ ...prev, [phoneNumberId]: password }));
          setShowSipPasswords(prev => ({ ...prev, [phoneNumberId]: true }));
        }
      } catch (err) {
        alert('SIP-Passwort konnte nicht entschlüsselt werden');
      }
    }
  };

  const handleAutoLogin = async () => {
    const contract = data?.data;
    // Get username from stressfreiEmail or portalUsername
    const username = contract?.stressfreiEmail?.email || contract?.portalUsername;
    // Defense-in-depth: nur http(s) – verhindert `javascript:`-URLs aus Alt-Daten.
    const safeUrl = safeHttpUrl(contract?.provider?.portalUrl);
    if (!safeUrl || !username) {
      alert('Portal-URL oder Benutzername fehlt');
      return;
    }

    setIsAutoLoginLoading(true);
    try {
      // Get decrypted password
      const res = await contractApi.getPassword(contractId);
      if (!res.data?.password) {
        alert('Passwort konnte nicht entschlüsselt werden');
        return;
      }

      const provider = contract!.provider!;
      const baseUrl = safeUrl;
      const usernameField = provider.usernameFieldName || 'username';
      const passwordField = provider.passwordFieldName || 'password';

      // Build URL with query parameters
      const url = new URL(baseUrl);
      url.searchParams.set(usernameField, username);
      url.searchParams.set(passwordField, res.data.password);

      // Open in new tab
      window.open(url.toString(), '_blank');
    } catch (err) {
      alert('Fehler beim Auto-Login');
    } finally {
      setIsAutoLoginLoading(false);
    }
  };

  if (isLoading) {
    return <div className="text-center py-8">Laden...</div>;
  }

  if (!data?.data) {
    return <div className="text-center py-8 text-red-600">Vertrag nicht gefunden</div>;
  }

  const c = data.data;
  // Verbrauch aus Vorvertrag als Hinweis, wenn der Jahresverbrauch im aktuellen
  // Vertrag noch leer ist. Greift nur bei Strom/Gas mit einem berechenbaren
  // Vorvertrag.
  const previousConsumption = (() => {
    const pc = c.previousContract;
    if (!pc?.energyDetails || !pc.startDate || !pc.endDate) return null;
    if (c.type !== 'ELECTRICITY' && c.type !== 'GAS') return null;
    const cms = pc.energyDetails.contractMeters || [];
    if (cms.length > 0) {
      return calculateMultiMeterConsumption(cms, pc.startDate, pc.endDate, c.type);
    }
    const readings = pc.energyDetails.meter?.readings || [];
    if (readings.length === 0) return null;
    return calculateConsumption(readings, pc.startDate, pc.endDate, c.type);
  })();
  const previousConsumptionUsable = previousConsumption
    && (previousConsumption.type === 'exact' || previousConsumption.type === 'projected');
  const fallbackBack = isCustomerPortal ? '/contracts' : (c.customer ? `/customers/${c.customer.id}?tab=contracts` : '/contracts');
  const back = popHistory(location.state, fallbackBack);

  // Consent-Sperrung: Vertrag nicht anzeigen wenn Kunde keine Einwilligung hat
  if (!hasConsentApproval) {
    return (
      <div>
        <div className="flex items-center gap-4 mb-6">
          <Button variant="ghost" size="sm" onClick={() => navigate(back.to, { state: back.state })}>
            <ArrowLeft className="w-4 h-4" />
          </Button>
          <h1 className="text-2xl font-bold">Vertrag {c.contractNumber}</h1>
        </div>
        <div className="flex flex-col items-center justify-center py-16 text-center">
          <div className="bg-amber-50 border border-amber-200 rounded-full p-4 mb-4">
            <Lock className="w-8 h-8 text-amber-500" />
          </div>
          <h2 className="text-lg font-semibold text-gray-800 mb-2">
            Datenschutz-Einwilligung erforderlich
          </h2>
          <p className="text-sm text-gray-600 mb-6 max-w-md">
            Die Vertragsdaten können nicht angezeigt werden, da der Kunde der Datenschutzerklärung noch nicht zugestimmt hat.
          </p>
          <Link
            to={`/customers/${c.customerId}?tab=consents`}
            className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm"
          >
            <Shield className="w-4 h-4" />
            Zum Kunden: Einwilligungen / Datenschutz
          </Link>
        </div>
      </div>
    );
  }

  return (
    <div>
      {/* Sticky-Header: Vertragsnummer + Kunde + Aktionsbuttons bleiben
          beim Scrollen oben stehen. -mx-8 px-8 zieht den Balken auf die
          Layout-Padding-Kante, damit's optisch bündig ist. */}
      <div className="sticky top-[var(--app-banner-h,0px)] z-20 -mx-8 px-8 py-4 mb-6 bg-gray-100 border-b border-gray-200 flex items-center justify-between">
        <div>
          <div className="flex items-center gap-4 mb-2">
            <Button
              variant="ghost"
              size="sm"
              onClick={() => navigate(back.to, { state: back.state })}
            >
              <ArrowLeft className="w-4 h-4" />
            </Button>
            <h1 className="text-2xl font-bold">{c.contractNumber}</h1>
            <Badge>{typeLabels[c.type]}</Badge>
            <Badge variant={statusVariants[c.status]}>{statusLabels[c.status]}</Badge>
            <button
              onClick={() => setShowStatusInfo(true)}
              className="text-gray-400 hover:text-blue-600 transition-colors"
              title="Status-Erklärung"
            >
              <Info className="w-4 h-4" />
            </button>
            {/* Snooze-Hinweis wenn nextReviewDate in der Zukunft */}
            {c.nextReviewDate && new Date(c.nextReviewDate) > new Date() && (
              <div className="flex items-center gap-1 px-2 py-1 bg-amber-100 text-amber-800 rounded-full text-xs">
                <BellOff className="w-3 h-3" />
                <span>Zurückgestellt bis {formatDate(c.nextReviewDate)}</span>
                {hasPermission('contracts:update') && (
                  <button
                    onClick={() => setShowUnsnoozeConfirm(true)}
                    className="ml-1 p-0.5 hover:bg-amber-200 rounded"
                    title="Zurückstellung aufheben"
                  >
                    <X className="w-3 h-3" />
                  </button>
                )}
              </div>
            )}
          </div>
          {c.customer && (
            <p className="text-gray-500 ml-10 flex items-center gap-1">
              Kunde:{' '}
              <Link to={`/customers/${c.customer.id}`} state={pushHistory(currentPath, location.state)} className="text-blue-600 hover:underline">
                {c.customer.companyName || `${c.customer.firstName} ${c.customer.lastName}`}
              </Link>
              <a
                href={`/customers/${c.customer.id}`}
                target="_blank"
                rel="noopener noreferrer"
                title="Kundenakte in neuem Tab öffnen"
                aria-label="Kundenakte in neuem Tab öffnen"
                className="text-gray-400 hover:text-blue-600 p-1 rounded"
              >
                <ExternalLink className="w-4 h-4" />
              </a>
              <button
                type="button"
                onClick={() => setShowCustomerInfo(true)}
                title="Wichtige Kundendaten anzeigen (Schnellansicht mit Copy-Buttons)"
                className="text-gray-400 hover:text-blue-600 p-1 rounded"
                aria-label="Kundendaten anzeigen"
              >
                <Info className="w-4 h-4" />
              </button>
            </p>
          )}
        </div>
        {!isCustomer && (
          <div className="flex gap-2">
            {c.previousContract && (
              <Link to={`/contracts/${c.previousContract.id}`}>
                <Button variant="secondary">
                  <ArrowLeft className="w-4 h-4 mr-2" />
                  Vorgängervertrag
                </Button>
              </Link>
            )}
            {hasPermission('contracts:create') && !c.followUpContract && (
              <div className="relative inline-flex">
                {/* Hauptaktion: Folgevertrag anlegen */}
                <Button
                  variant="secondary"
                  onClick={() => setShowFollowUpConfirm(true)}
                  disabled={followUpMutation.isPending || renewalMutation.isPending}
                  className="!rounded-r-none !border-r-0"
                >
                  <Copy className="w-4 h-4 mr-2" />
                  {followUpMutation.isPending ? 'Erstelle...' : 'Folgevertrag anlegen'}
                </Button>
                {/* Dropdown-Pfeil für VVL */}
                <Button
                  variant="secondary"
                  onClick={() => setShowFollowUpMenu(!showFollowUpMenu)}
                  disabled={followUpMutation.isPending || renewalMutation.isPending}
                  className="!rounded-l-none !px-2"
                  title="Weitere Optionen"
                >
                  <ChevronDown className="w-4 h-4" />
                </Button>
                {showFollowUpMenu && (
                  <>
                    {/* Click-outside-Overlay */}
                    <div
                      className="fixed inset-0 z-10"
                      onClick={() => setShowFollowUpMenu(false)}
                    />
                    <div className="absolute top-full right-0 mt-1 z-20 w-56 bg-white border border-gray-200 rounded-lg shadow-lg py-1">
                      <button
                        type="button"
                        onClick={() => {
                          setShowFollowUpMenu(false);
                          setShowVvlConfirm(true);
                        }}
                        className="w-full text-left px-4 py-2 text-sm hover:bg-gray-100 flex items-center gap-2"
                      >
                        <Copy className="w-4 h-4 text-gray-500" />
                        VVL anlegen
                      </button>
                    </div>
                  </>
                )}
              </div>
            )}
            {c.followUpContract && (
              <Link to={`/contracts/${c.followUpContract.id}`}>
                <Button variant="secondary">
                  <ArrowRight className="w-4 h-4 mr-2" />
                  Folgevertrag anzeigen
                </Button>
              </Link>
            )}
            {hasPermission('contracts:create') && (
              <Link
                to={`/contracts/new?copyFrom=${contractId}&customerId=${c.customerId}`}
                state={pushHistory(currentPath, location.state)}
                title="Alle Daten dieses Vertrags in einen neuen, eigenständigen Vertrag übernehmen"
              >
                <Button variant="secondary">
                  <Copy className="w-4 h-4 mr-2" />
                  Kopieren
                </Button>
              </Link>
            )}
            {hasPermission('contracts:update') && (
              <Link to={`/contracts/${id}/edit`} state={pushHistory(currentPath, location.state)}>
                <Button variant="secondary">
                  <Edit className="w-4 h-4 mr-2" />
                  Bearbeiten
                </Button>
              </Link>
            )}
            <GenerateOrderButton contractId={contractId} />
            {hasPermission('contracts:delete') && (
              <Button
                variant="danger"
                onClick={() => {
                  if (confirm('Vertrag wirklich löschen?')) {
                    deleteMutation.mutate();
                  }
                }}
              >
                <Trash2 className="w-4 h-4 mr-2" />
                Löschen
              </Button>
            )}
          </div>
        )}
      </div>

      {/* Previous Contract Info */}
      {c.previousContract && (
        <Card className="mb-6 border-l-4 border-l-blue-500" title="Vorgängervertrag">
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            <div>
              <dt className="text-sm text-gray-500">Vertragsnummer</dt>
              <dd>
                <button
                  onClick={() => setShowPredecessorModal(true)}
                  className="text-blue-600 hover:underline"
                >
                  {c.previousContract.contractNumber}
                </button>
              </dd>
            </div>
            {c.previousContract.providerName && (
              <div>
                <dt className="text-sm text-gray-500">Anbieter</dt>
                <dd>{c.previousContract.providerName}</dd>
              </div>
            )}
            {c.previousContract.customerNumberAtProvider && (
              <div>
                <dt className="text-sm text-gray-500">Kundennummer</dt>
                <dd className="font-mono">{c.previousContract.customerNumberAtProvider}</dd>
              </div>
            )}
            {c.previousContract.contractNumberAtProvider && (
              <div>
                <dt className="text-sm text-gray-500">Vertragsnummer</dt>
                <dd className="font-mono">{c.previousContract.contractNumberAtProvider}</dd>
              </div>
            )}
            {c.previousContract.portalUsername && (
              <div>
                <dt className="text-sm text-gray-500">Zugangsdaten</dt>
                <dd>{c.previousContract.portalUsername}</dd>
              </div>
            )}
          </div>
        </Card>
      )}

      {/* Altanbieter-Info (nur wenn KEIN Vorgängervertrag aber Altanbieter-Daten vorhanden) */}
      {!c.previousContract && (c.previousProvider || c.previousCustomerNumber || c.previousContractNumber) && (
        <Card className="mb-6 border-l-4 border-l-gray-400" title="Altanbieter">
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
            {c.previousProvider && (
              <div>
                <dt className="text-sm text-gray-500">Anbieter</dt>
                <dd>{c.previousProvider.name}</dd>
              </div>
            )}
            {c.previousCustomerNumber && (
              <div>
                <dt className="text-sm text-gray-500">Kundennummer</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.previousCustomerNumber}
                  <CopyButton value={c.previousCustomerNumber} />
                </dd>
              </div>
            )}
            {c.previousContractNumber && (
              <div>
                <dt className="text-sm text-gray-500">Vertragsnummer</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.previousContractNumber}
                  <CopyButton value={c.previousContractNumber} />
                </dd>
              </div>
            )}
          </div>
        </Card>
      )}

      {/* Cancellation Confirmation Warning */}
      {c.cancellationConfirmationDate && (
        <div className="mb-6 p-4 bg-red-50 border-2 border-red-400 rounded-lg flex items-start gap-3">
          <span className="text-red-600 text-xl font-bold">!</span>
          <div>
            <p className="font-semibold text-red-800">Kündigungsbestätigung vorhanden</p>
            <p className="text-sm text-red-700 mt-1">
              Dieser Vertrag hat eine Kündigungsbestätigung vom{' '}
              <strong>{new Date(c.cancellationConfirmationDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })}</strong>.
              {c.cancellationConfirmationOptionsDate && (
                <> Optionen-Bestätigung: <strong>{new Date(c.cancellationConfirmationOptionsDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })}</strong>.</>
              )}
            </p>
          </div>
        </div>
      )}

      {/* Multisim Warning */}
      {c.type === 'MOBILE' && c.mobileDetails?.requiresMultisim && (
        <div className="mb-6 p-4 bg-amber-50 border border-amber-300 rounded-lg flex items-start gap-3">
          <span className="text-amber-600 text-xl font-bold">!</span>
          <div>
            <p className="font-semibold text-amber-800">Multisim erforderlich</p>
            <p className="text-sm text-amber-700 mt-1">
              Dieser Kunde benötigt eine Multisim-Karte. Multisim ist bei Klarmobil, Congstar und Otelo nicht buchbar.
              Bitte einen Anbieter wie Freenet oder vergleichbar wählen.
            </p>
          </div>
        </div>
      )}

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
        {/* Provider & Tariff */}
        <Card title="Anbieter & Tarif">
          <dl className="space-y-3">
            {(c.provider || c.providerName) && (
              <div>
                <dt className="text-sm text-gray-500">Anbieter</dt>
                <dd className="font-medium">{c.provider?.name || c.providerName}</dd>
              </div>
            )}
            {(c.tariff || c.tariffName) && (
              <div>
                <dt className="text-sm text-gray-500">Tarif</dt>
                <dd>{c.tariff?.name || c.tariffName}</dd>
              </div>
            )}
            {c.customerNumberAtProvider && (
              <div>
                <dt className="text-sm text-gray-500">Kundennummer</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.customerNumberAtProvider}
                  <CopyButton value={c.customerNumberAtProvider} />
                </dd>
              </div>
            )}
            {c.contractNumberAtProvider && (
              <div>
                <dt className="text-sm text-gray-500">Vertragsnummer</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.contractNumberAtProvider}
                  <CopyButton value={c.contractNumberAtProvider} />
                </dd>
              </div>
            )}
            {c.orderNumberAtSalesPlatform && (
              <div>
                <dt className="text-sm text-gray-500">Auftragsnr. Vertriebsplattform</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.orderNumberAtSalesPlatform}
                  <CopyButton value={c.orderNumberAtSalesPlatform} />
                </dd>
              </div>
            )}
            {c.customerNumberAtSalesPlatform && (
              <div>
                <dt className="text-sm text-gray-500">Kundennr. Vertriebsplattform</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.customerNumberAtSalesPlatform}
                  <CopyButton value={c.customerNumberAtSalesPlatform} />
                </dd>
              </div>
            )}
            {c.contractNumberAtSalesPlatform && (
              <div>
                <dt className="text-sm text-gray-500">Vertragsnr. Vertriebsplattform</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.contractNumberAtSalesPlatform}
                  <CopyButton value={c.contractNumberAtSalesPlatform} />
                </dd>
              </div>
            )}
            {c.salesPlatform && (
              <div>
                <dt className="text-sm text-gray-500">Vertriebsplattform</dt>
                <dd>{c.salesPlatform.name}</dd>
              </div>
            )}
            {c.commission !== null && c.commission !== undefined && (
              <div>
                <dt className="text-sm text-gray-500">Provision</dt>
                <dd>{c.commission.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })}</dd>
              </div>
            )}
            {c.priceFirst12Months && (
              <div>
                <dt className="text-sm text-gray-500">Preis erste 12 Monate</dt>
                <dd>{c.priceFirst12Months}</dd>
              </div>
            )}
            {c.priceFrom13Months && (
              <div>
                <dt className="text-sm text-gray-500">Preis ab 13. Monat</dt>
                <dd>{c.priceFrom13Months}</dd>
              </div>
            )}
            {c.priceAfter24Months && (
              <div>
                <dt className="text-sm text-gray-500">Preis nach 24 Monaten</dt>
                <dd>{c.priceAfter24Months}</dd>
              </div>
            )}
          </dl>
        </Card>

        {/* Duration & Cancellation */}
        <Card title="Laufzeit und Kündigung" className={c.cancellationConfirmationDate ? 'border-2 border-red-400' : ''}>
          {c.contractDuration && isUnlimitedDuration(c.contractDuration.code) && (
            <p className="text-sm text-gray-500 mb-4 bg-blue-50 border border-blue-200 rounded-lg p-3">
              <strong>Hinweis:</strong> Dieser Vertrag gilt als unbefristet mit der jeweiligen Kündigungsfrist.
            </p>
          )}
          <dl className="space-y-3">
            {c.startDate && (
              <div>
                <dt className="text-sm text-gray-500">Vertragsbeginn</dt>
                <dd>{new Date(c.startDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })}</dd>
              </div>
            )}
            {c.endDate && (
              <div>
                <dt className="text-sm text-gray-500">Vertragsende</dt>
                <dd>{new Date(c.endDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })}</dd>
              </div>
            )}
            {c.contractDuration && (
              <div>
                <dt className="text-sm text-gray-500">Vertragslaufzeit</dt>
                <dd>{c.contractDuration.description}</dd>
              </div>
            )}
            {c.cancellationPeriod && (
              <div>
                <dt className="text-sm text-gray-500">Kündigungsfrist</dt>
                <dd>{c.cancellationPeriod.description}</dd>
              </div>
            )}
            {c.cancellationConfirmationDate && (
              <div>
                <dt className="text-sm text-gray-500">Kündigungsbestätigungsdatum</dt>
                <dd>{new Date(c.cancellationConfirmationDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })}</dd>
              </div>
            )}
            {c.cancellationConfirmationOptionsDate && (
              <div>
                <dt className="text-sm text-gray-500">Kündigungsbestätigungsoptionendatum</dt>
                <dd>{new Date(c.cancellationConfirmationOptionsDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })}</dd>
              </div>
            )}
            {c.wasSpecialCancellation && (
              <div>
                <dt className="text-sm text-gray-500">Sonderkündigung</dt>
                <dd><Badge variant="warning">Ja</Badge></dd>
              </div>
            )}
          </dl>

          {/* Kündigungsdokumente */}
          {hasPermission('contracts:update') && (
            <div className="mt-6 pt-6 border-t">
              <h4 className="font-medium mb-4">Kündigungsdokumente</h4>
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                {/* Kündigungsschreiben */}
                <div>
                  <dt className="text-sm text-gray-500 mb-1">Kündigungsschreiben</dt>
                  {c.cancellationLetterPath ? (
                    <div className="flex items-center gap-3 flex-wrap">
                      <a
                        href={viewUrl(c.cancellationLetterPath)}
                        target="_blank"
                        rel="noopener noreferrer"
                        className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                      >
                        <Eye className="w-4 h-4" />
                        Anzeigen
                      </a>
                      <a
                        href={fileUrl(c.cancellationLetterPath)}
                        download
                        className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                      >
                        <Download className="w-4 h-4" />
                        Download
                      </a>
                      <FileUpload
                        onUpload={async (file) => {
                          await uploadApi.uploadCancellationLetter(contractId, file);
                          queryClient.invalidateQueries({ queryKey: ['contract', id] });
                        }}
                        existingFile={c.cancellationLetterPath}
                        accept=".pdf"
                        label="Ersetzen"
                      />
                      <button
                        onClick={async () => {
                          if (confirm('Dokument wirklich löschen?')) {
                            await uploadApi.deleteCancellationLetter(contractId);
                            queryClient.invalidateQueries({ queryKey: ['contract', id] });
                          }
                        }}
                        className="text-red-600 hover:underline text-sm flex items-center gap-1"
                      >
                        <Trash2 className="w-4 h-4" />
                        Löschen
                      </button>
                    </div>
                  ) : (
                    <FileUpload
                      onUpload={async (file) => {
                        await uploadApi.uploadCancellationLetter(contractId, file);
                        queryClient.invalidateQueries({ queryKey: ['contract', id] });
                      }}
                      accept=".pdf"
                      label="PDF hochladen"
                    />
                  )}
                </div>

                {/* Kündigungsbestätigung */}
                <div>
                  <dt className="text-sm text-gray-500 mb-1">Kündigungsbestätigung</dt>
                  {c.cancellationConfirmationPath ? (
                    <>
                      <div className="flex items-center gap-3 flex-wrap">
                        <a
                          href={viewUrl(c.cancellationConfirmationPath)}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                        >
                          <Eye className="w-4 h-4" />
                          Anzeigen
                        </a>
                        <a
                          href={fileUrl(c.cancellationConfirmationPath)}
                          download
                          className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                        >
                          <Download className="w-4 h-4" />
                          Download
                        </a>
                        <FileUpload
                          onUpload={async (file) => {
                            // Datei puffern, Datums-Modal öffnen
                            setCancelConfirmDate(
                              c.cancellationConfirmationDate
                                ? c.cancellationConfirmationDate.split('T')[0]
                                : new Date().toISOString().split('T')[0]
                            );
                            setPendingCancelFile(file);
                          }}
                          existingFile={c.cancellationConfirmationPath}
                          accept=".pdf"
                          label="Ersetzen"
                        />
                        <button
                          onClick={async () => {
                            if (confirm('Dokument wirklich löschen?')) {
                              await uploadApi.deleteCancellationConfirmation(contractId);
                              queryClient.invalidateQueries({ queryKey: ['contract', id] });
                            }
                          }}
                          className="text-red-600 hover:underline text-sm flex items-center gap-1"
                        >
                          <Trash2 className="w-4 h-4" />
                          Löschen
                        </button>
                      </div>
                      {/* Datum der Kündigungsbestätigung */}
                      <div className="mt-2">
                        <label className="text-xs text-gray-500 block mb-1">Bestätigung erhalten am</label>
                        <div className="flex items-center gap-2">
                          <AutosaveDateInput
                            value={c.cancellationConfirmationDate ? c.cancellationConfirmationDate.split('T')[0] : ''}
                            onSave={(value) => updateCancellationDateMutation.mutate(value)}
                          />
                          {c.cancellationConfirmationDate && (
                            <button
                              onClick={() => updateCancellationDateMutation.mutate(null)}
                              className="p-1 text-red-500 hover:text-red-700 hover:bg-red-50 rounded"
                              title="Datum löschen"
                            >
                              <Trash2 className="w-4 h-4" />
                            </button>
                          )}
                        </div>
                      </div>
                    </>
                  ) : (
                    <FileUpload
                      onUpload={async (file) => {
                        setCancelConfirmDate(new Date().toISOString().split('T')[0]);
                        setPendingCancelFile(file);
                      }}
                      accept=".pdf"
                      label="PDF hochladen"
                    />
                  )}
                </div>

                {/* Kündigungsschreiben Optionen */}
                <div>
                  <dt className="text-sm text-gray-500 mb-1">Kündigungsschreiben Optionen</dt>
                  {c.cancellationLetterOptionsPath ? (
                    <div className="flex items-center gap-3 flex-wrap">
                      <a
                        href={viewUrl(c.cancellationLetterOptionsPath)}
                        target="_blank"
                        rel="noopener noreferrer"
                        className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                      >
                        <Eye className="w-4 h-4" />
                        Anzeigen
                      </a>
                      <a
                        href={fileUrl(c.cancellationLetterOptionsPath)}
                        download
                        className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                      >
                        <Download className="w-4 h-4" />
                        Download
                      </a>
                      <FileUpload
                        onUpload={async (file) => {
                          await uploadApi.uploadCancellationLetterOptions(contractId, file);
                          queryClient.invalidateQueries({ queryKey: ['contract', id] });
                        }}
                        existingFile={c.cancellationLetterOptionsPath}
                        accept=".pdf"
                        label="Ersetzen"
                      />
                      <button
                        onClick={async () => {
                          if (confirm('Dokument wirklich löschen?')) {
                            await uploadApi.deleteCancellationLetterOptions(contractId);
                            queryClient.invalidateQueries({ queryKey: ['contract', id] });
                          }
                        }}
                        className="text-red-600 hover:underline text-sm flex items-center gap-1"
                      >
                        <Trash2 className="w-4 h-4" />
                        Löschen
                      </button>
                    </div>
                  ) : (
                    <FileUpload
                      onUpload={async (file) => {
                        await uploadApi.uploadCancellationLetterOptions(contractId, file);
                        queryClient.invalidateQueries({ queryKey: ['contract', id] });
                      }}
                      accept=".pdf"
                      label="PDF hochladen"
                    />
                  )}
                </div>

                {/* Kündigungsbestätigung Optionen */}
                <div>
                  <dt className="text-sm text-gray-500 mb-1">Kündigungsbestätigung Optionen</dt>
                  {c.cancellationConfirmationOptionsPath ? (
                    <>
                      <div className="flex items-center gap-3 flex-wrap">
                        <a
                          href={viewUrl(c.cancellationConfirmationOptionsPath)}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                        >
                          <Eye className="w-4 h-4" />
                          Anzeigen
                        </a>
                        <a
                          href={fileUrl(c.cancellationConfirmationOptionsPath)}
                          download
                          className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                        >
                          <Download className="w-4 h-4" />
                          Download
                        </a>
                        <FileUpload
                          onUpload={async (file) => {
                            await uploadApi.uploadCancellationConfirmationOptions(contractId, file);
                            queryClient.invalidateQueries({ queryKey: ['contract', id] });
                          }}
                          existingFile={c.cancellationConfirmationOptionsPath}
                          accept=".pdf"
                          label="Ersetzen"
                        />
                        <button
                          onClick={async () => {
                            if (confirm('Dokument wirklich löschen?')) {
                              await uploadApi.deleteCancellationConfirmationOptions(contractId);
                              queryClient.invalidateQueries({ queryKey: ['contract', id] });
                            }
                          }}
                          className="text-red-600 hover:underline text-sm flex items-center gap-1"
                        >
                          <Trash2 className="w-4 h-4" />
                          Löschen
                        </button>
                      </div>
                      {/* Datum der Kündigungsbestätigung Optionen */}
                      <div className="mt-2">
                        <label className="text-xs text-gray-500 block mb-1">Bestätigung erhalten am</label>
                        <div className="flex items-center gap-2">
                          <AutosaveDateInput
                            value={c.cancellationConfirmationOptionsDate ? c.cancellationConfirmationOptionsDate.split('T')[0] : ''}
                            onSave={(value) => updateCancellationOptionsDateMutation.mutate(value)}
                          />
                          {c.cancellationConfirmationOptionsDate && (
                            <button
                              onClick={() => updateCancellationOptionsDateMutation.mutate(null)}
                              className="p-1 text-red-500 hover:text-red-700 hover:bg-red-50 rounded"
                              title="Datum löschen"
                            >
                              <Trash2 className="w-4 h-4" />
                            </button>
                          )}
                        </div>
                      </div>
                    </>
                  ) : (
                    <FileUpload
                      onUpload={async (file) => {
                        await uploadApi.uploadCancellationConfirmationOptions(contractId, file);
                        queryClient.invalidateQueries({ queryKey: ['contract', id] });
                      }}
                      accept=".pdf"
                      label="PDF hochladen"
                    />
                  )}
                </div>
              </div>
            </div>
          )}
        </Card>
      </div>

      {/* Portal Credentials */}
      {(c.portalUsername || c.stressfreiEmail || c.hasPortalPassword) && (
        <Card className="mb-6" title="Zugangsdaten">
          <dl className="grid grid-cols-2 gap-4">
            {(c.portalUsername || c.stressfreiEmail) && (
              <div>
                <dt className="text-sm text-gray-500">
                  Benutzername
                  {c.stressfreiEmail && (
                    <span className="ml-2 text-xs text-blue-600">({customerEmailLabel})</span>
                  )}
                </dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.stressfreiEmail?.email || c.portalUsername}
                  <CopyButton value={c.stressfreiEmail?.email || c.portalUsername || ''} />
                </dd>
              </div>
            )}
            {(() => {
              // Defense-in-depth: nur http(s) als href erlauben,
              // damit Alt-Daten mit `javascript:` nicht klickbar werden.
              const safePortalUrl = safeHttpUrl(c.provider?.portalUrl);
              if (!safePortalUrl) return null;
              return (
                <div>
                  <dt className="text-sm text-gray-500">Portal-Link</dt>
                  <dd className="flex items-center gap-1">
                    <a
                      href={safePortalUrl}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-blue-600 hover:underline truncate"
                      title={safePortalUrl}
                    >
                      {safePortalUrl.replace(/^https?:\/\//, '').replace(/\/$/, '')}
                      <ExternalLink className="w-3 h-3 inline ml-1 -mt-0.5" />
                    </a>
                    <CopyButton value={safePortalUrl} />
                  </dd>
                </div>
              );
            })()}
            {c.hasPortalPassword && (
              <div>
                <dt className="text-sm text-gray-500">Passwort</dt>
                <dd className="flex items-center gap-2">
                  <span className="font-mono">
                    {showPassword && decryptedPassword ? decryptedPassword : '••••••••'}
                  </span>
                  {showPassword && decryptedPassword && (
                    <CopyButton value={decryptedPassword} />
                  )}
                  <Button variant="ghost" size="sm" onClick={handleShowPassword}>
                    {showPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                  </Button>
                </dd>
              </div>
            )}
          </dl>

          {/* Auto-Login Button */}
          {c.provider?.portalUrl && (c.portalUsername || c.stressfreiEmail) && c.hasPortalPassword && (
            <div className="mt-4 pt-4 border-t">
              <Button
                onClick={handleAutoLogin}
                disabled={isAutoLoginLoading}
                className="w-full sm:w-auto"
              >
                <ExternalLink className="w-4 h-4 mr-2" />
                {isAutoLoginLoading ? 'Wird geöffnet...' : 'Zum Kundenportal (Auto-Login)'}
              </Button>
              <p className="text-xs text-gray-500 mt-2">
                Öffnet das Portal mit vorausgefüllten Zugangsdaten
              </p>
            </div>
          )}
        </Card>
      )}

      {/* Linked Data */}
      <div className="grid grid-cols-1 lg:grid-cols-4 gap-6 mb-6">
        {c.address && (
          <Card title="Lieferadresse">
            <CopyableBlock
              values={[
                `${c.address.street} ${c.address.houseNumber}`,
                `${c.address.postalCode} ${c.address.city}`,
                c.address.country
              ]}
            >
              <p>
                {c.address.street} {c.address.houseNumber}
              </p>
              <p>
                {c.address.postalCode} {c.address.city}
              </p>
              <p className="text-gray-500">{c.address.country}</p>
            </CopyableBlock>
          </Card>
        )}
        {/* Rechnungsadresse: Falls nicht gesetzt, Lieferadresse anzeigen */}
        {(c.billingAddress || c.address) && (
          <Card title="Rechnungsadresse">
            {(() => {
              const addr = c.billingAddress || c.address;
              if (!addr) return null;
              return (
                <CopyableBlock
                  values={[
                    `${addr.street} ${addr.houseNumber}`,
                    `${addr.postalCode} ${addr.city}`,
                    addr.country
                  ]}
                >
                  <p>
                    {addr.street} {addr.houseNumber}
                  </p>
                  <p>
                    {addr.postalCode} {addr.city}
                  </p>
                  <p className="text-gray-500">{addr.country}</p>
                  {!c.billingAddress && c.address && (
                    <p className="text-xs text-gray-400 mt-1">(wie Lieferadresse)</p>
                  )}
                </CopyableBlock>
              );
            })()}
          </Card>
        )}
        {c.bankCard && (
          <Card
            title="Bankkarte"
            actions={c.bankCard.documentPath ? (
              <button
                type="button"
                onClick={() => setPdfModal({ title: 'Bankkarte – Dokument', path: c.bankCard!.documentPath! })}
                className="text-gray-400 hover:text-blue-600 p-1 rounded"
                title="Hinterlegtes Dokument anzeigen (PDF)"
                aria-label="Bankkarten-Dokument anzeigen"
              >
                <FileText className="w-4 h-4" />
              </button>
            ) : undefined}
          >
            <p className="font-medium">{c.bankCard.accountHolder}</p>
            <p className="font-mono flex items-center gap-1">
              {c.bankCard.iban}
              <CopyButton value={c.bankCard.iban} />
            </p>
            {c.bankCard.bic && (
              <p className="text-sm text-gray-600 flex items-center gap-1">
                <span className="text-gray-500">BIC:</span> {c.bankCard.bic}
                <CopyButton value={c.bankCard.bic} />
              </p>
            )}
            {c.bankCard.bankName && (
              <p className="text-sm text-gray-600 flex items-center gap-1">
                <span className="text-gray-500">Bank:</span> {c.bankCard.bankName}
                <CopyButton value={c.bankCard.bankName} />
              </p>
            )}
            {c.bankCard.cardNumber && (
              <p className="text-sm text-gray-600 flex items-center gap-1">
                <span className="text-gray-500">Kartennummer:</span> {c.bankCard.cardNumber}
                <CopyButton value={c.bankCard.cardNumber} />
              </p>
            )}
            {c.bankCard.expiryDate && (
              <p className="text-sm text-gray-600 flex items-center gap-1">
                <span className="text-gray-500">Ablaufdatum:</span> {formatDate(c.bankCard.expiryDate)}
                <CopyButton value={formatDate(c.bankCard.expiryDate)} />
              </p>
            )}
            {c.bankCard.description && (
              <p className="text-sm text-gray-600 mt-1 italic whitespace-pre-line">
                {c.bankCard.description}
              </p>
            )}
          </Card>
        )}
        {c.identityDocument && (
          <Card
            title="Ausweis"
            actions={c.identityDocument.documentPath ? (
              <button
                type="button"
                onClick={() => setPdfModal({ title: 'Ausweis – Dokument', path: c.identityDocument!.documentPath! })}
                className="text-gray-400 hover:text-blue-600 p-1 rounded"
                title="Hinterlegtes Dokument anzeigen (PDF)"
                aria-label="Ausweis-Dokument anzeigen"
              >
                <FileText className="w-4 h-4" />
              </button>
            ) : undefined}
          >
            <p className="font-mono flex items-center gap-1">
              {c.identityDocument.documentNumber}
              <CopyButton value={c.identityDocument.documentNumber} />
            </p>
            <p className="text-gray-500">{c.identityDocument.type}</p>
            {c.identityDocument.issuingAuthority && (
              <p className="text-sm text-gray-600 flex items-center gap-1">
                <span className="text-gray-500">Behörde:</span> {c.identityDocument.issuingAuthority}
                <CopyButton value={c.identityDocument.issuingAuthority} />
              </p>
            )}
            {c.identityDocument.issueDate && (
              <p className="text-sm text-gray-600 flex items-center gap-1">
                <span className="text-gray-500">Ausstellung:</span> {formatDate(c.identityDocument.issueDate)}
                <CopyButton value={formatDate(c.identityDocument.issueDate)} />
              </p>
            )}
            {c.identityDocument.expiryDate && (
              <p className="text-sm text-gray-600 flex items-center gap-1">
                <span className="text-gray-500">Ablaufdatum:</span> {formatDate(c.identityDocument.expiryDate)}
                <CopyButton value={formatDate(c.identityDocument.expiryDate)} />
              </p>
            )}
            {c.customer?.birthPlace && (
              <p className="text-sm text-gray-600 flex items-center gap-1">
                <span className="text-gray-500">Geburtsort:</span> {c.customer.birthPlace}
                <CopyButton value={c.customer.birthPlace} />
              </p>
            )}
            {c.customer?.birthDate && (
              <p className="text-sm text-gray-600 flex items-center gap-1">
                <span className="text-gray-500">Geburtsdatum:</span> {formatDate(c.customer.birthDate)}
                <CopyButton value={formatDate(c.customer.birthDate)} />
              </p>
            )}
          </Card>
        )}
      </div>

      {/* Type-specific details */}
      {c.energyDetails && (
        <Card
          className="mb-6"
          title={
            <div className="flex items-center gap-3">
              <span>{c.type === 'ELECTRICITY' ? 'Strom-Details' : 'Gas-Details'}</span>
              <Link
                to={`/customers/${c.customerId}?tab=meters`}
                target="_blank"
                rel="noopener noreferrer"
                className="inline-flex items-center gap-1 text-xs text-blue-600 hover:text-blue-800 hover:underline font-normal"
                title="Zähler-Übersicht des Kunden in neuem Tab öffnen"
              >
                <ExternalLink className="w-3 h-3" />
                Zähler verwalten
              </Link>
            </div>
          }
        >
          <dl className="grid grid-cols-2 md:grid-cols-4 gap-4">
            {c.energyDetails.meter && (
              <div>
                <dt className="text-sm text-gray-500 flex items-center gap-1 flex-wrap">
                  Zählernummer
                  {c.energyDetails.meter.tariffModel === 'DUAL' && (
                    <Badge variant="default">HT/NT</Badge>
                  )}
                  {c.energyDetails.meter.isActive === false && (
                    <Badge variant="danger">Inaktiv</Badge>
                  )}
                </dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.energyDetails.meter.meterNumber}
                  <CopyButton value={c.energyDetails.meter.meterNumber} />
                </dd>
                {c.energyDetails.meter.location && (
                  <dd className="text-xs text-gray-500 mt-1">
                    Standort: {c.energyDetails.meter.location}
                  </dd>
                )}
              </div>
            )}
            {(() => {
              // MaLo-ID kommt jetzt aus der Lieferadresse (je Sparte).
              const malo = c.type === 'ELECTRICITY' ? c.address?.maloIdElectricity : c.address?.maloIdGas;
              return malo ? (
                <div>
                  <dt className="text-sm text-gray-500">MaLo-ID ({c.type === 'ELECTRICITY' ? 'Strom' : 'Gas'})</dt>
                  <dd className="font-mono flex items-center gap-1">
                    {malo}
                    <CopyButton value={malo} />
                  </dd>
                </div>
              ) : null;
            })()}
            {c.energyDetails.noBonusDesired && (
              <div>
                <dt className="text-sm text-gray-500">Bonis</dt>
                <dd className="text-orange-700 font-medium">Keine Bonis erwünscht</dd>
              </div>
            )}
            {c.energyDetails.annualConsumption ? (
              <div>
                <dt className="text-sm text-gray-500">
                  Jahresverbrauch {c.type === 'ELECTRICITY' ? '' : '(m³)'}
                </dt>
                <dd>
                  {c.energyDetails.annualConsumption.toLocaleString('de-DE')}{' '}
                  {c.type === 'ELECTRICITY' ? 'kWh' : 'm³'}
                </dd>
              </div>
            ) : previousConsumptionUsable && (
              <div>
                <dt className="text-sm text-gray-500">
                  Jahresverbrauch {c.type === 'ELECTRICITY' ? '' : '(m³)'}
                </dt>
                <dd className="text-blue-700">
                  ~{(c.type === 'GAS'
                    ? previousConsumption!.consumptionM3 ?? previousConsumption!.consumptionKwh
                    : previousConsumption!.consumptionKwh
                  ).toLocaleString('de-DE', { maximumFractionDigits: 0 })}{' '}
                  {c.type === 'GAS' ? 'm³' : 'kWh'}
                  <div className="text-xs text-gray-500 mt-0.5">
                    geschätzt aus Vorvertrag{previousConsumption!.type === 'projected' ? ' (hochgerechnet)' : ''}
                  </div>
                </dd>
              </div>
            )}
            {c.type === 'GAS' && c.energyDetails.annualConsumptionKwh ? (
              <div>
                <dt className="text-sm text-gray-500">Jahresverbrauch (kWh)</dt>
                <dd>{c.energyDetails.annualConsumptionKwh.toLocaleString('de-DE')} kWh</dd>
              </div>
            ) : (c.type === 'GAS' && previousConsumptionUsable) ? (
              <div>
                <dt className="text-sm text-gray-500">Jahresverbrauch (kWh)</dt>
                <dd className="text-blue-700">
                  ~{previousConsumption!.consumptionKwh.toLocaleString('de-DE', { maximumFractionDigits: 0 })} kWh
                  <div className="text-xs text-gray-500 mt-0.5">
                    geschätzt aus Vorvertrag{previousConsumption!.type === 'projected' ? ' (hochgerechnet)' : ''}
                  </div>
                </dd>
              </div>
            ) : null}
            {c.energyDetails.basePrice != null && (
              <div>
                <dt className="text-sm text-gray-500">Grundpreis</dt>
                <dd>{c.energyDetails.basePrice.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 10 })} €/Monat</dd>
              </div>
            )}
            {c.energyDetails.unitPrice != null && (
              <div>
                <dt className="text-sm text-gray-500">
                  {c.energyDetails.unitPriceNt != null ? 'HT-Arbeitspreis' : 'Arbeitspreis'}
                </dt>
                <dd>
                  {c.energyDetails.unitPrice.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 10 })} €/kWh
                </dd>
              </div>
            )}
            {c.energyDetails.unitPriceNt != null && (
              <div>
                <dt className="text-sm text-gray-500">NT-Arbeitspreis</dt>
                <dd>
                  {c.energyDetails.unitPriceNt.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 10 })} €/kWh
                </dd>
              </div>
            )}
            {/* Bonus: Sofort + Neukunden einzeln + Gesamtbonus */}
            {c.energyDetails.instantBonus != null && c.energyDetails.instantBonus > 0 && (
              <div>
                <dt className="text-sm text-gray-500">Sofort-Bonus</dt>
                <dd>{c.energyDetails.instantBonus.toLocaleString('de-DE')} €</dd>
              </div>
            )}
            {c.energyDetails.newCustomerBonus != null && c.energyDetails.newCustomerBonus > 0 && (
              <div>
                <dt className="text-sm text-gray-500">Neukunden-Bonus</dt>
                <dd>{c.energyDetails.newCustomerBonus.toLocaleString('de-DE')} €</dd>
              </div>
            )}
            {((c.energyDetails.instantBonus ?? 0) + (c.energyDetails.newCustomerBonus ?? 0)) > 0 && (
              <div>
                <dt className="text-sm text-gray-500">Gesamtbonus</dt>
                <dd className="font-medium">
                  {((c.energyDetails.instantBonus ?? 0) + (c.energyDetails.newCustomerBonus ?? 0)).toLocaleString('de-DE')} €
                </dd>
              </div>
            )}
            {c.energyDetails.previousProviderName && (
              <div>
                <dt className="text-sm text-gray-500">Vorversorger</dt>
                <dd>{c.energyDetails.previousProviderName}</dd>
              </div>
            )}
            {c.energyDetails.previousCustomerNumber && (
              <div>
                <dt className="text-sm text-gray-500">Vorherige Kundennr.</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.energyDetails.previousCustomerNumber}
                  <CopyButton value={c.energyDetails.previousCustomerNumber} />
                </dd>
              </div>
            )}
          </dl>

          {/* Zählerstände - Multi-Zähler Support */}
          {c.energyDetails.contractMeters && c.energyDetails.contractMeters.length > 0 ? (
            <>
              {c.energyDetails.contractMeters.map((cm: ContractMeter, idx: number) => (
                cm.meter && (
                  <MeterReadingsSection
                    key={cm.id}
                    meterId={cm.meter.id}
                    meterType={cm.meter.type}
                    tariffModel={cm.meter.tariffModel}
                    readings={cm.meter.readings || []}
                    canEdit={hasPermission('contracts:update') && !isCustomer}
                    label={c.energyDetails!.contractMeters!.length > 1
                      ? `Zähler ${idx + 1}: ${cm.meter.meterNumber}${cm.removedAt ? ' (gewechselt)' : ' (aktuell)'}`
                      : undefined
                    }
                  />
                )
              ))}
            </>
          ) : c.energyDetails.meter ? (
            <MeterReadingsSection
              meterId={c.energyDetails.meter.id}
              meterType={c.energyDetails.meter.type}
              tariffModel={c.energyDetails.meter.tariffModel}
              readings={c.energyDetails.meter.readings || []}
              canEdit={hasPermission('contracts:update') && !isCustomer}
            />
          ) : null}

          {/* Folgezähler hinzufügen – auch bei Verträgen ohne ContractMeter-Eintrag
              (z. B. Folgeverträge oder Bestandsverträge im Single-Meter-Modell). */}
          {hasPermission('contracts:update') && !isCustomer && (c.energyDetails.meter || (c.energyDetails.contractMeters && c.energyDetails.contractMeters.length > 0)) && (
            <SuccessorMeterButton
              contractId={contractId}
              customerId={c.customerId}
              meterType={c.type as 'ELECTRICITY' | 'GAS'}
              existingMeterIds={
                c.energyDetails.contractMeters && c.energyDetails.contractMeters.length > 0
                  ? c.energyDetails.contractMeters.map((cm: ContractMeter) => cm.meterId)
                  : c.energyDetails.meter ? [c.energyDetails.meter.id] : []
              }
            />
          )}

          {/* Verbrauchsberechnung & Kostenvorschau */}
          <EnergyConsumptionCalculation
            contractType={c.type as 'ELECTRICITY' | 'GAS'}
            readings={c.energyDetails.meter?.readings || []}
            startDate={c.startDate}
            endDate={c.endDate}
            basePrice={c.energyDetails.basePrice}
            unitPrice={c.energyDetails.unitPrice}
            unitPriceNt={c.energyDetails.unitPriceNt}
            instantBonus={c.energyDetails.instantBonus}
            newCustomerBonus={c.energyDetails.newCustomerBonus}
            hasMeter={!!c.energyDetails.meter}
            contractMeters={c.energyDetails.contractMeters}
          />

          {/* Rechnungen */}
          <InvoicesSection
            ecdId={c.energyDetails.id}
            invoices={c.energyDetails.invoices || []}
            contractId={contractId}
            canEdit={hasPermission('contracts:update') && !isCustomer}
            showInvoiceWarnings={true}
          />
        </Card>
      )}

      {c.internetDetails && (
        <Card className="mb-6" title={
          c.type === 'DSL' ? 'DSL-Details' :
          c.type === 'CABLE' ? 'Kabelinternet-Details' :
          'Glasfaser-Details'
        }>
          <dl className="grid grid-cols-2 md:grid-cols-4 gap-4">
            {c.internetDetails.downloadSpeed && (
              <div>
                <dt className="text-sm text-gray-500">Download</dt>
                <dd>{c.internetDetails.downloadSpeed} Mbit/s</dd>
              </div>
            )}
            {c.internetDetails.uploadSpeed && (
              <div>
                <dt className="text-sm text-gray-500">Upload</dt>
                <dd>{c.internetDetails.uploadSpeed} Mbit/s</dd>
              </div>
            )}
            {c.internetDetails.routerModel && (
              <div>
                <dt className="text-sm text-gray-500">Router</dt>
                <dd>{c.internetDetails.routerModel}</dd>
              </div>
            )}
            {c.internetDetails.routerSerialNumber && (
              <div>
                <dt className="text-sm text-gray-500">Router S/N</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.internetDetails.routerSerialNumber}
                  <CopyButton value={c.internetDetails.routerSerialNumber} />
                </dd>
              </div>
            )}
            {c.internetDetails.propertyType && (
              <div>
                <dt className="text-sm text-gray-500">Objekttyp</dt>
                <dd>{c.internetDetails.propertyType}</dd>
              </div>
            )}
            {c.internetDetails.propertyLocation && (
              <div>
                <dt className="text-sm text-gray-500">Lage</dt>
                <dd>{c.internetDetails.propertyLocation}</dd>
              </div>
            )}
            {c.internetDetails.connectionLocation && (
              <div>
                <dt className="text-sm text-gray-500">Anschluss-Lage</dt>
                <dd>{c.internetDetails.connectionLocation}</dd>
              </div>
            )}
            {c.internetDetails.installationDate && (
              <div>
                <dt className="text-sm text-gray-500">Installation</dt>
                <dd>{formatDate(c.internetDetails.installationDate)}</dd>
              </div>
            )}
            {c.internetDetails.homeId && (
              <div>
                <dt className="text-sm text-gray-500">Home-ID</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.internetDetails.homeId}
                  <CopyButton value={c.internetDetails.homeId} />
                </dd>
              </div>
            )}
            {c.internetDetails.activationCode && (
              <div>
                <dt className="text-sm text-gray-500">Aktivierungscode</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.internetDetails.activationCode}
                  <CopyButton value={c.internetDetails.activationCode} />
                </dd>
              </div>
            )}
          </dl>

          {/* Internet-Zugangsdaten */}
          {(c.internetDetails.internetUsername || c.internetDetails.internetPasswordEncrypted) && (
            <div className="mt-4 pt-4 border-t">
              <h4 className="text-sm font-medium text-gray-700 mb-3">Internet-Zugangsdaten</h4>
              <dl className="grid grid-cols-2 md:grid-cols-4 gap-4">
                {c.internetDetails.internetUsername && (
                  <div>
                    <dt className="text-sm text-gray-500">Benutzername</dt>
                    <dd className="font-mono flex items-center gap-1">
                      {c.internetDetails.internetUsername}
                      <CopyButton value={c.internetDetails.internetUsername} />
                    </dd>
                  </div>
                )}
                {c.internetDetails.internetPasswordEncrypted && (
                  <div>
                    <dt className="text-sm text-gray-500">Passwort</dt>
                    <dd className="flex items-center gap-2">
                      <span className="font-mono">
                        {showInternetPassword && decryptedInternetPassword
                          ? decryptedInternetPassword
                          : '••••••••'}
                      </span>
                      {showInternetPassword && decryptedInternetPassword && (
                        <CopyButton value={decryptedInternetPassword} />
                      )}
                      <Button variant="ghost" size="sm" onClick={handleShowInternetPassword}>
                        {showInternetPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                      </Button>
                    </dd>
                  </div>
                )}
              </dl>
            </div>
          )}

          {/* Rufnummern mit SIP-Daten */}
          {c.internetDetails.phoneNumbers && c.internetDetails.phoneNumbers.length > 0 && (
            <div className="mt-4 pt-4 border-t">
              <h4 className="text-sm font-medium text-gray-700 mb-3">Rufnummern & SIP-Zugangsdaten</h4>
              <div className="space-y-3">
                {c.internetDetails.phoneNumbers.map((pn) => (
                  <div key={pn.id} className="p-3 bg-gray-50 rounded-lg">
                    <div className="flex items-center gap-2 mb-2">
                      <span className="font-mono font-medium flex items-center gap-1">
                        {pn.phoneNumber}
                        <CopyButton value={pn.phoneNumber} />
                      </span>
                      {pn.isMain && <Badge variant="success">Hauptnummer</Badge>}
                    </div>
                    {(pn.sipUsername || pn.sipPasswordEncrypted || pn.sipServer) && (
                      <dl className="grid grid-cols-2 md:grid-cols-4 gap-3 text-sm">
                        {pn.sipUsername && (
                          <div>
                            <dt className="text-gray-500">SIP-Benutzer</dt>
                            <dd className="font-mono flex items-center gap-1">
                              {pn.sipUsername}
                              <CopyButton value={pn.sipUsername} />
                            </dd>
                          </div>
                        )}
                        {pn.sipPasswordEncrypted && (
                          <div>
                            <dt className="text-gray-500">SIP-Passwort</dt>
                            <dd className="flex items-center gap-2">
                              <span className="font-mono">
                                {showSipPasswords[pn.id] && decryptedSipPasswords[pn.id]
                                  ? decryptedSipPasswords[pn.id]
                                  : '••••••••'}
                              </span>
                              {showSipPasswords[pn.id] && decryptedSipPasswords[pn.id] && (
                                <CopyButton value={decryptedSipPasswords[pn.id]!} />
                              )}
                              <Button variant="ghost" size="sm" onClick={() => handleShowSipPassword(pn.id)}>
                                {showSipPasswords[pn.id] ? <EyeOff className="w-3 h-3" /> : <Eye className="w-3 h-3" />}
                              </Button>
                            </dd>
                          </div>
                        )}
                        {pn.sipServer && (
                          <div>
                            <dt className="text-gray-500">SIP-Server</dt>
                            <dd className="font-mono flex items-center gap-1">
                              {pn.sipServer}
                              <CopyButton value={pn.sipServer} />
                            </dd>
                          </div>
                        )}
                      </dl>
                    )}
                  </div>
                ))}
              </div>
            </div>
          )}
        </Card>
      )}

      {c.mobileDetails && (
        <Card className="mb-6" title="Mobilfunk-Details">
          <dl className="grid grid-cols-2 md:grid-cols-4 gap-4">
            {c.mobileDetails.mobileNetwork && (
              <div>
                <dt className="text-sm text-gray-500">Mobilfunknetz</dt>
                <dd>{({ TELEKOM: 'Telekom', VODAFONE: 'Vodafone', TELEFONICA: 'Telefónica' } as Record<string, string>)[c.mobileDetails.mobileNetwork] || c.mobileDetails.mobileNetwork}</dd>
              </div>
            )}
            {c.mobileDetails.dataVolume && (
              <div>
                <dt className="text-sm text-gray-500">Datenvolumen</dt>
                <dd>{c.mobileDetails.dataVolume} GB</dd>
              </div>
            )}
            {c.mobileDetails.includedMinutes && (
              <div>
                <dt className="text-sm text-gray-500">Inklusiv-Minuten</dt>
                <dd>{c.mobileDetails.includedMinutes}</dd>
              </div>
            )}
            {c.mobileDetails.includedSMS && (
              <div>
                <dt className="text-sm text-gray-500">Inklusiv-SMS</dt>
                <dd>{c.mobileDetails.includedSMS}</dd>
              </div>
            )}
            {c.mobileDetails.deviceModel && (
              <div>
                <dt className="text-sm text-gray-500">Gerät</dt>
                <dd>{c.mobileDetails.deviceModel}</dd>
              </div>
            )}
            {c.mobileDetails.deviceImei && (
              <div>
                <dt className="text-sm text-gray-500">IMEI</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.mobileDetails.deviceImei}
                  <CopyButton value={c.mobileDetails.deviceImei} />
                </dd>
              </div>
            )}
            {c.mobileDetails.requiresMultisim && (
              <div>
                <dt className="text-sm text-gray-500">Multisim</dt>
                <dd><Badge variant="warning">Erforderlich</Badge></dd>
              </div>
            )}
          </dl>

          {/* SIM-Karten */}
          {c.mobileDetails.simCards && c.mobileDetails.simCards.length > 0 && (
            <div className="mt-6 pt-6 border-t">
              <h4 className="font-medium mb-4">SIM-Karten</h4>
              <div className="space-y-3">
                {c.mobileDetails.simCards.map((simCard) => (
                  <SimCardDisplay key={simCard.id} simCard={simCard} />
                ))}
              </div>
            </div>
          )}

          {/* Legacy: Alte Felder falls keine simCards vorhanden */}
          {(!c.mobileDetails.simCards || c.mobileDetails.simCards.length === 0) &&
            (c.mobileDetails.phoneNumber || c.mobileDetails.simCardNumber) && (
            <div className="mt-6 pt-6 border-t">
              <h4 className="font-medium mb-4">SIM-Karte (Legacy)</h4>
              <dl className="grid grid-cols-2 gap-4">
                {c.mobileDetails.phoneNumber && (
                  <div>
                    <dt className="text-sm text-gray-500">Rufnummer</dt>
                    <dd className="font-mono flex items-center gap-1">
                      {c.mobileDetails.phoneNumber}
                      <CopyButton value={c.mobileDetails.phoneNumber} />
                    </dd>
                  </div>
                )}
                {c.mobileDetails.simCardNumber && (
                  <div>
                    <dt className="text-sm text-gray-500">SIM-Kartennummer</dt>
                    <dd className="font-mono flex items-center gap-1">
                      {c.mobileDetails.simCardNumber}
                      <CopyButton value={c.mobileDetails.simCardNumber} />
                    </dd>
                  </div>
                )}
              </dl>
            </div>
          )}
        </Card>
      )}

      {c.tvDetails && (
        <Card className="mb-6" title="TV-Details">
          <dl className="grid grid-cols-2 md:grid-cols-3 gap-4">
            {c.tvDetails.receiverModel && (
              <div>
                <dt className="text-sm text-gray-500">Receiver</dt>
                <dd>{c.tvDetails.receiverModel}</dd>
              </div>
            )}
            {c.tvDetails.smartcardNumber && (
              <div>
                <dt className="text-sm text-gray-500">Smartcard</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.tvDetails.smartcardNumber}
                  <CopyButton value={c.tvDetails.smartcardNumber} />
                </dd>
              </div>
            )}
            {c.tvDetails.package && (
              <div>
                <dt className="text-sm text-gray-500">Paket</dt>
                <dd>{c.tvDetails.package}</dd>
              </div>
            )}
          </dl>
        </Card>
      )}

      {c.carInsuranceDetails && (
        <Card className="mb-6" title="KFZ-Versicherung Details">
          <dl className="grid grid-cols-2 md:grid-cols-4 gap-4">
            {c.carInsuranceDetails.licensePlate && (
              <div>
                <dt className="text-sm text-gray-500">Kennzeichen</dt>
                <dd className="font-mono font-bold flex items-center gap-1">
                  {c.carInsuranceDetails.licensePlate}
                  <CopyButton value={c.carInsuranceDetails.licensePlate} />
                </dd>
              </div>
            )}
            {c.carInsuranceDetails.vehicleType && (
              <div>
                <dt className="text-sm text-gray-500">Fahrzeug</dt>
                <dd>{c.carInsuranceDetails.vehicleType}</dd>
              </div>
            )}
            {c.carInsuranceDetails.hsn && (
              <div>
                <dt className="text-sm text-gray-500">HSN/TSN</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.carInsuranceDetails.hsn}/{c.carInsuranceDetails.tsn}
                  <CopyButton value={`${c.carInsuranceDetails.hsn}/${c.carInsuranceDetails.tsn}`} />
                </dd>
              </div>
            )}
            {c.carInsuranceDetails.vin && (
              <div>
                <dt className="text-sm text-gray-500">FIN</dt>
                <dd className="font-mono text-sm flex items-center gap-1">
                  {c.carInsuranceDetails.vin}
                  <CopyButton value={c.carInsuranceDetails.vin} />
                </dd>
              </div>
            )}
            {c.carInsuranceDetails.firstRegistration && (
              <div>
                <dt className="text-sm text-gray-500">Erstzulassung</dt>
                <dd>
                  {formatDate(c.carInsuranceDetails.firstRegistration)}
                </dd>
              </div>
            )}
            {c.carInsuranceDetails.noClaimsClass && (
              <div>
                <dt className="text-sm text-gray-500">SF-Klasse</dt>
                <dd>{c.carInsuranceDetails.noClaimsClass}</dd>
              </div>
            )}
            <div>
              <dt className="text-sm text-gray-500">Versicherungsart</dt>
              <dd>
                <Badge
                  variant={
                    c.carInsuranceDetails.insuranceType === 'FULL'
                      ? 'success'
                      : c.carInsuranceDetails.insuranceType === 'PARTIAL'
                      ? 'warning'
                      : 'default'
                  }
                >
                  {c.carInsuranceDetails.insuranceType === 'FULL'
                    ? 'Vollkasko'
                    : c.carInsuranceDetails.insuranceType === 'PARTIAL'
                    ? 'Teilkasko'
                    : 'Haftpflicht'}
                </Badge>
              </dd>
            </div>
            {c.carInsuranceDetails.deductiblePartial && (
              <div>
                <dt className="text-sm text-gray-500">SB Teilkasko</dt>
                <dd>{c.carInsuranceDetails.deductiblePartial} €</dd>
              </div>
            )}
            {c.carInsuranceDetails.deductibleFull && (
              <div>
                <dt className="text-sm text-gray-500">SB Vollkasko</dt>
                <dd>{c.carInsuranceDetails.deductibleFull} €</dd>
              </div>
            )}
            {c.carInsuranceDetails.policyNumber && (
              <div>
                <dt className="text-sm text-gray-500">Versicherungsschein-Nr.</dt>
                <dd className="font-mono flex items-center gap-1">
                  {c.carInsuranceDetails.policyNumber}
                  <CopyButton value={c.carInsuranceDetails.policyNumber} />
                </dd>
              </div>
            )}
            {c.carInsuranceDetails.previousInsurer && (
              <div>
                <dt className="text-sm text-gray-500">Vorversicherer</dt>
                <dd>{c.carInsuranceDetails.previousInsurer}</dd>
              </div>
            )}
          </dl>
        </Card>
      )}

      {/* Contract Tasks */}
      <ContractTasksSection
        contractId={contractId}
        canEdit={hasPermission('contracts:update')}
        isCustomerPortal={isCustomerPortal}
      />

      {/* Rechnungen (bei allen Vertragstypen, außer Energie - die haben ihre eigene Section) */}
      {!['ELECTRICITY', 'GAS'].includes(c.type) && !isCustomerPortal && (
        <Card className="mb-6">
          <InvoicesSection
            invoices={c.invoices || []}
            contractId={contractId}
            canEdit={hasPermission('contracts:update')}
          />
        </Card>
      )}

      {/* Gutschriften (Subventionen) – nur Mitarbeiter/Admin */}
      {!isCustomerPortal && hasPermission('contracts:read') && (
        <CreditNotesSection
          contractId={contractId}
          canEdit={hasPermission('contracts:update')}
        />
      )}

      {/* Vertragsdokumente */}
      {!isCustomerPortal && (
        <ContractDocumentsSection
          contractId={contractId}
          canEdit={hasPermission('contracts:update')}
        />
      )}

      {/* Zugeordnete E-Mails */}
      {!isCustomerPortal && hasPermission('contracts:read') && c.customerId && (
        <ContractEmailsSection
          contractId={contractId}
          customerId={c.customerId}
        />
      )}

      {c.notes && (
        <Card title="Notizen">
          <p className="whitespace-pre-wrap">{c.notes}</p>
        </Card>
      )}

      {/* Vertragshistorie (nur für Mitarbeiter) */}
      {!isCustomerPortal && hasPermission('contracts:read') && (
        <ContractHistorySection
          contractId={contractId}
          canEdit={hasPermission('contracts:update')}
          knownContracts={{
            ...(c.previousContract?.contractNumber
              ? { [c.previousContract.contractNumber]: c.previousContract.id }
              : {}),
            ...(c.followUpContract?.contractNumber
              ? { [c.followUpContract.contractNumber]: c.followUpContract.id }
              : {}),
          }}
        />
      )}

      {/* PDF-Viewer (Bankkarte-/Ausweis-Dokument) */}
      <PdfViewerModal
        isOpen={!!pdfModal}
        onClose={() => setPdfModal(null)}
        title={pdfModal?.title || 'Dokument'}
        path={pdfModal?.path}
      />

      {/* Vorgängervertrag Modal */}
      {showPredecessorModal && c.previousContract && (
        <ContractDetailModal
          contractId={c.previousContract.id}
          isOpen={true}
          onClose={() => setShowPredecessorModal(false)}
        />
      )}

      {/* Kunden-Schnellansicht */}
      {c.customer && (
        <CustomerInfoModal
          customerId={c.customer.id}
          open={showCustomerInfo}
          onClose={() => setShowCustomerInfo(false)}
          deliveryAddress={c.address}
          billingAddress={c.billingAddress}
          contractStressfreiEmailId={c.stressfreiEmailId}
        />
      )}

      {/* Folgevertrag Bestätigung */}
      <Modal
        isOpen={showFollowUpConfirm}
        onClose={() => setShowFollowUpConfirm(false)}
        title="Folgevertrag anlegen"
        size="sm"
      >
        <div className="space-y-4">
          <p className="text-gray-700">
            Möchten Sie wirklich einen Folgevertrag für diesen Vertrag anlegen?
          </p>
          <p className="text-sm text-gray-500">
            Die Daten des aktuellen Vertrags werden als Vorlage übernommen.
          </p>
          <div className="flex justify-end gap-3 pt-2">
            <Button
              variant="secondary"
              onClick={() => setShowFollowUpConfirm(false)}
            >
              Nein
            </Button>
            <Button
              onClick={() => {
                setShowFollowUpConfirm(false);
                followUpMutation.mutate();
              }}
            >
              Ja, anlegen
            </Button>
          </div>
        </div>
      </Modal>

      {/* VVL Bestätigung */}
      <Modal
        isOpen={showVvlConfirm}
        onClose={() => setShowVvlConfirm(false)}
        title="Vertragsverlängerung (VVL) anlegen"
        size="sm"
      >
        <div className="space-y-4">
          <p className="text-gray-700">
            Möchten Sie eine Vertragsverlängerung für diesen Vertrag anlegen?
          </p>
          <p className="text-sm text-gray-500">
            Alle Daten werden 1:1 übernommen (auch Provider, Tarif, Portal-
            Zugang, Preise und Vertragsdokumente). Das Startdatum wird auf
            den nächsten Laufzeit-Beginn berechnet (altes Startdatum +
            Vertragslaufzeit). Das <strong>Auftragsdokument</strong> wird
            <strong> nicht </strong> mitkopiert – das ist die neue,
            unterschriebene VVL, die Sie selbst hochladen.
          </p>
          {c.startDate && c.contractDuration?.description && (
            <div className="text-xs text-gray-500 bg-gray-50 p-2 rounded">
              Vorhersage: alter Beginn{' '}
              <strong>{new Date(c.startDate).toLocaleDateString('de-DE')}</strong> +{' '}
              <strong>{c.contractDuration.description}</strong>
              {' = '}neuer VVL-Beginn (siehe danach im Vertrag)
            </div>
          )}
          <div className="flex justify-end gap-3 pt-2">
            <Button
              variant="secondary"
              onClick={() => setShowVvlConfirm(false)}
            >
              Nein
            </Button>
            <Button
              onClick={() => {
                setShowVvlConfirm(false);
                renewalMutation.mutate();
              }}
              disabled={renewalMutation.isPending}
            >
              {renewalMutation.isPending ? 'Erstelle...' : 'Ja, VVL anlegen'}
            </Button>
          </div>
        </div>
      </Modal>

      {/* Status-Info Modal */}
      <StatusInfoModal isOpen={showStatusInfo} onClose={() => setShowStatusInfo(false)} />

      {/* Kündigungsbestätigung: Datum erfassen und dann Upload */}
      <Modal
        isOpen={pendingCancelFile !== null}
        onClose={() => setPendingCancelFile(null)}
        title="Kündigungsbestätigung – Datum angeben"
        size="sm"
      >
        <div className="space-y-4">
          <p className="text-sm text-gray-700">
            Wann wurde die Kündigung vom Anbieter bestätigt? Du kannst das Datum auch später noch anpassen.
          </p>
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Bestätigung erhalten am</label>
            <input
              type="date"
              value={cancelConfirmDate}
              onChange={(e) => setCancelConfirmDate(e.target.value)}
              className="block w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>
          <div className="flex justify-end gap-3 pt-2">
            <Button variant="secondary" onClick={() => setPendingCancelFile(null)}>
              Abbrechen
            </Button>
            <Button
              onClick={async () => {
                if (!pendingCancelFile) return;
                try {
                  await uploadApi.uploadCancellationConfirmation(
                    contractId,
                    pendingCancelFile,
                    cancelConfirmDate || undefined,
                  );
                  queryClient.invalidateQueries({ queryKey: ['contract', id] });
                  setPendingCancelFile(null);
                } catch (err) {
                  alert('Fehler beim Hochladen: ' + (err instanceof Error ? err.message : 'Unbekannt'));
                }
              }}
            >
              Hochladen
            </Button>
          </div>
        </div>
      </Modal>

      {/* Un-Snooze Bestätigungsmodal */}
      <Modal
        isOpen={showUnsnoozeConfirm}
        onClose={() => setShowUnsnoozeConfirm(false)}
        title="Zurückstellung aufheben?"
      >
        <div className="space-y-4">
          <p className="text-gray-700">
            Möchten Sie die Zurückstellung für diesen Vertrag wirklich aufheben?
          </p>
          <p className="text-sm text-gray-500">
            Der Vertrag wird danach wieder im Cockpit angezeigt, wenn Fristen anstehen oder abgelaufen sind.
          </p>
          <div className="flex justify-end gap-3 pt-4">
            <Button variant="secondary" onClick={() => setShowUnsnoozeConfirm(false)}>
              Abbrechen
            </Button>
            <Button
              variant="danger"
              onClick={() => unsnoozeMutation.mutate()}
              disabled={unsnoozeMutation.isPending}
            >
              {unsnoozeMutation.isPending ? 'Wird aufgehoben...' : 'Ja, aufheben'}
            </Button>
          </div>
        </div>
      </Modal>
    </div>
  );
}

// ==================== VERTRAGSDOKUMENTE ====================

const DOCUMENT_TYPES = [
  'Auftragsformular',
  'Auftragsbestätigung',
  'Lieferbestätigung',
  'Vertragsunterlagen',
  'Vollmacht',
  'Widerrufsbelehrung',
  'Preisblatt',
  'Sonstiges',
];

function ContractDocumentsSection({
  contractId,
  canEdit,
}: {
  contractId: number;
  canEdit: boolean;
}) {
  const queryClient = useQueryClient();
  const [showUpload, setShowUpload] = useState(false);
  const [uploadType, setUploadType] = useState(DOCUMENT_TYPES[0]);
  const [uploadNotes, setUploadNotes] = useState('');
  const [uploadDeliveryDate, setUploadDeliveryDate] = useState<string>(
    () => new Date().toISOString().split('T')[0],
  );
  const [isJpgModalOpen, setIsJpgModalOpen] = useState(false);

  const { data: docsData } = useQuery({
    queryKey: ['contract-documents', contractId],
    queryFn: () => contractApi.getDocuments(contractId),
  });

  const uploadMutation = useMutation({
    mutationFn: ({ file, documentType, notes, deliveryDate }: { file: File; documentType: string; notes?: string; deliveryDate?: string }) =>
      contractApi.uploadDocument(contractId, file, documentType, notes, deliveryDate),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract-documents', contractId] });
      // Contract selbst neu laden – Status kann sich durch Lieferbestätigung geändert haben
      queryClient.invalidateQueries({ queryKey: ['contract'] });
      setShowUpload(false);
      setUploadNotes('');
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (documentId: number) => contractApi.deleteDocument(contractId, documentId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contract-documents', contractId] });
    },
  });

  const documents: ContractDocument[] = docsData?.data || [];

  const isDelivery = uploadType.trim().toLowerCase() === 'lieferbestätigung';

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      uploadMutation.mutate({
        file,
        documentType: uploadType,
        notes: uploadNotes || undefined,
        deliveryDate: isDelivery ? uploadDeliveryDate : undefined,
      });
    }
  };

  return (
    <Card className="mb-6" title={
      <div className="flex items-center justify-between w-full">
        <div className="flex items-center gap-2">
          <FileText className="w-5 h-5" />
          <span>Vertragsdokumente</span>
          <span className="text-sm font-normal text-gray-500">({documents.length})</span>
        </div>
        {canEdit && (
          <Button variant="ghost" size="sm" onClick={() => setShowUpload(!showUpload)}>
            <Plus className="w-4 h-4" />
          </Button>
        )}
      </div>
    }>
      {/* Upload-Bereich */}
      {showUpload && (
        <div className="mb-4 p-4 bg-blue-50 border border-blue-200 rounded-lg">
          <div className="grid grid-cols-1 sm:grid-cols-3 gap-3 mb-3">
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">Dokumenttyp</label>
              <select
                value={uploadType}
                onChange={(e) => setUploadType(e.target.value)}
                className="block w-full px-3 py-2 border border-gray-300 rounded-lg text-sm"
              >
                {DOCUMENT_TYPES.map((t) => (
                  <option key={t} value={t}>{t}</option>
                ))}
              </select>
            </div>
            <div className="sm:col-span-2">
              <label className="block text-sm font-medium text-gray-700 mb-1">Notiz (optional)</label>
              <input
                type="text"
                value={uploadNotes}
                onChange={(e) => setUploadNotes(e.target.value)}
                placeholder="z.B. Unterschrieben am 15.03.2026"
                className="block w-full px-3 py-2 border border-gray-300 rounded-lg text-sm"
              />
            </div>
          </div>
          {isDelivery && (
            <div className="mb-3 p-3 bg-white border border-blue-300 rounded">
              <label className="block text-sm font-medium text-gray-700 mb-1">Lieferdatum</label>
              <input
                type="date"
                value={uploadDeliveryDate}
                onChange={(e) => setUploadDeliveryDate(e.target.value)}
                className="block w-full max-w-[220px] px-3 py-2 border border-gray-300 rounded-lg text-sm"
              />
              <p className="text-xs text-gray-500 mt-1">
                Falls der Vertrag noch auf Entwurf steht, wird er auf Aktiv gesetzt und dieses Datum als Vertragsbeginn übernommen.
              </p>
            </div>
          )}
          <div className="flex items-center gap-3 flex-wrap">
            <label className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 cursor-pointer text-sm">
              <Plus className="w-4 h-4" />
              Datei wählen (PDF, JPG, PNG)
              <input type="file" accept=".pdf,.jpg,.jpeg,.png" className="hidden" onChange={handleFileSelect} />
            </label>
            <Button variant="ghost" size="sm" onClick={() => setIsJpgModalOpen(true)} title="Mehrere JPGs zu einer PDF kombinieren">
              <Images className="w-4 h-4 mr-1" /> JPGs → PDF
            </Button>
            <Button variant="secondary" size="sm" onClick={() => setShowUpload(false)}>Abbrechen</Button>
            {uploadMutation.isPending && <span className="text-sm text-gray-500">Hochladen...</span>}
          </div>
          <JpgToPdfModal
            isOpen={isJpgModalOpen}
            onClose={() => setIsJpgModalOpen(false)}
            onComplete={(file) => {
              uploadMutation.mutate({
                file,
                documentType: uploadType,
                notes: uploadNotes || undefined,
                deliveryDate: isDelivery ? uploadDeliveryDate : undefined,
              });
            }}
            fileNameHint={uploadType}
          />
          {uploadMutation.isError && (
            <p className="text-xs text-red-600 mt-2">Fehler beim Hochladen</p>
          )}
        </div>
      )}

      {/* Dokumentliste */}
      {documents.length === 0 ? (
        <p className="text-sm text-gray-500">Keine Dokumente vorhanden.</p>
      ) : (
        <div className="space-y-2">
          {documents.map((doc) => (
            <div key={doc.id} className="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
              <div className="flex items-center gap-3">
                <FileText className="w-4 h-4 text-gray-400" />
                <div>
                  <div className="flex items-center gap-2">
                    <span className="text-xs px-2 py-0.5 rounded-full bg-blue-100 text-blue-700">
                      {doc.documentType}
                    </span>
                    <a
                      href={viewUrl(doc.documentPath)}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-sm text-blue-600 hover:underline"
                    >
                      {doc.originalName}
                    </a>
                  </div>
                  <div className="flex items-center gap-3 mt-0.5 text-xs text-gray-500">
                    <span>{formatDate(doc.createdAt)}</span>
                    {doc.uploadedBy && <span>von {doc.uploadedBy}</span>}
                    {doc.notes && <span>– {doc.notes}</span>}
                  </div>
                </div>
              </div>
              <div className="flex items-center gap-2">
                <a
                  href={fileUrl(doc.documentPath)}
                  download
                  className="text-gray-400 hover:text-blue-600"
                  title="Herunterladen"
                >
                  <Download className="w-4 h-4" />
                </a>
                {canEdit && (
                  <button
                    onClick={() => {
                      if (confirm(`Dokument "${doc.originalName}" wirklich löschen?`)) {
                        deleteMutation.mutate(doc.id);
                      }
                    }}
                    className="text-gray-400 hover:text-red-600"
                    title="Löschen"
                  >
                    <Trash2 className="w-4 h-4" />
                  </button>
                )}
              </div>
            </div>
          ))}
        </div>
      )}
    </Card>
  );
}

// ==================== AUFTRAG GENERIEREN BUTTON ====================

function GenerateOrderButton({ contractId }: { contractId: number }) {
  const [showDropdown, setShowDropdown] = useState(false);
  const [showInputModal, setShowInputModal] = useState<{ templateId: number; templateName: string } | null>(null);

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

  const templates = (templatesData?.data || []).filter(t => t.isActive);
  if (templates.length === 0) return null;

  const handleSelect = async (templateId: number, templateName: string) => {
    setShowDropdown(false);
    // Prüfen ob manuelle Inputs nötig sind
    try {
      const result = await pdfTemplateApi.getRequiredInputs(templateId, contractId);
      const inputs = result.data;
      if (inputs && (inputs.needsStressfreiEmail || inputs.manualFields.length > 0)) {
        setShowInputModal({ templateId, templateName });
      } else {
        // Direkt generieren (GET-Link) – kurzlebiger Download-Token
        const downloadToken = await authApi.getDownloadToken();
        window.open(`${pdfTemplateApi.generateUrl(templateId, contractId)}?token=${downloadToken ?? ''}`, '_blank');
      }
    } catch {
      // Fallback: direkt generieren
      const downloadToken = await authApi.getDownloadToken();
      window.open(`${pdfTemplateApi.generateUrl(templateId, contractId)}?token=${downloadToken ?? ''}`, '_blank');
    }
  };

  return (
    <>
      {templates.length === 1 ? (
        <Button variant="secondary" onClick={() => handleSelect(templates[0].id, templates[0].name)}>
          <FileText className="w-4 h-4 mr-2" />
          {templates[0].name}
        </Button>
      ) : (
        <div className="relative">
          <Button variant="secondary" onClick={() => setShowDropdown(!showDropdown)}>
            <FileText className="w-4 h-4 mr-2" />
            Auftrag generieren
            <ChevronDown className="w-3 h-3 ml-1" />
          </Button>
          {showDropdown && (
            <>
              <div className="fixed inset-0 z-10" onClick={() => setShowDropdown(false)} />
              <div className="absolute right-0 mt-1 w-64 bg-white border rounded-lg shadow-lg z-20 py-1">
                {templates.map((t) => (
                  <button
                    key={t.id}
                    className="w-full text-left px-4 py-2 text-sm hover:bg-gray-50 flex items-center gap-2"
                    onClick={() => handleSelect(t.id, t.name)}
                  >
                    <FileText className="w-4 h-4 text-blue-500" />
                    <div>
                      <span className="font-medium">{t.name}</span>
                      {t.providerName && <span className="text-xs text-gray-500 ml-1">({t.providerName})</span>}
                    </div>
                  </button>
                ))}
              </div>
            </>
          )}
        </div>
      )}

      {showInputModal && (
        <GenerateInputModal
          templateId={showInputModal.templateId}
          templateName={showInputModal.templateName}
          contractId={contractId}
          onClose={() => setShowInputModal(null)}
        />
      )}
    </>
  );
}

function GenerateInputModal({ templateId, templateName, contractId, onClose }: {
  templateId: number;
  templateName: string;
  contractId: number;
  onClose: () => void;
}) {
  const [stressfreiEmailId, setStressfreiEmailId] = useState('');
  const [manualValues, setManualValues] = useState<Record<string, string>>({});
  const [generating] = useState(false);
  const { customerEmailLabel } = useProviderSettings();

  const { data: inputsData, isLoading } = useQuery({
    queryKey: ['pdf-inputs', templateId, contractId],
    queryFn: () => pdfTemplateApi.getRequiredInputs(templateId, contractId),
  });

  const inputs = inputsData?.data;

  const handleGenerate = async () => {
    const downloadToken = await authApi.getDownloadToken();
    const params = new URLSearchParams();
    params.set('token', downloadToken ?? '');
    if (stressfreiEmailId) params.set('stressfreiEmailId', stressfreiEmailId);
    for (const [key, value] of Object.entries(manualValues)) {
      if (value) params.set(`manual_${key}`, value);
    }
    window.open(`${pdfTemplateApi.generateUrl(templateId, contractId)}?${params}`, '_blank');
    onClose();
  };

  if (isLoading) return null;

  return (
    <Modal isOpen={true} onClose={onClose} title={`${templateName} – Zusätzliche Angaben`}>
      <div className="space-y-4">
        {inputs?.needsStressfreiEmail && (
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">{customerEmailLabel} E-Mail</label>
            <select
              value={stressfreiEmailId}
              onChange={(e) => setStressfreiEmailId(e.target.value)}
              className="block w-full px-3 py-2 border border-gray-300 rounded-lg text-sm"
            >
              <option value="">Bitte wählen...</option>
              {inputs.stressfreiEmails.map((e) => (
                <option key={e.id} value={e.id}>{e.email}</option>
              ))}
            </select>
          </div>
        )}

        {inputs?.manualFields && inputs.manualFields.length > 0 && (
          <div className="space-y-3">
            <p className="text-sm font-medium text-gray-700">Freitextfelder</p>
            {inputs.manualFields.map((f) => (
              <Input
                key={f.key}
                label={f.pdfFieldName}
                value={manualValues[f.key] || ''}
                onChange={(e) => setManualValues({ ...manualValues, [f.key]: e.target.value })}
                placeholder="Eingabe..."
              />
            ))}
          </div>
        )}

        <div className="flex justify-end gap-3 pt-2">
          <Button variant="secondary" onClick={onClose}>Abbrechen</Button>
          <Button onClick={handleGenerate} disabled={generating}>
            <FileText className="w-4 h-4 mr-2" />
            {generating ? 'Generiere...' : 'PDF generieren'}
          </Button>
        </div>
      </div>
    </Modal>
  );
}
