import { useEffect, useMemo, useState } from 'react';
import { useNavigate, useParams, useSearchParams, useLocation, Link } from 'react-router-dom';
import { popHistory } from '../../utils/navigation';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useForm } from 'react-hook-form';
import toast from 'react-hot-toast';
import { contractApi, customerApi, platformApi, cancellationPeriodApi, contractDurationApi, providerApi, contractCategoryApi } from '../../services/api';
import Card from '../../components/ui/Card';
import Button from '../../components/ui/Button';
import Input from '../../components/ui/Input';
import Select from '../../components/ui/Select';
import CopyButton from '../../components/ui/CopyButton';
import CustomerInfoModal from '../../components/contracts/CustomerInfoModal';
import { buildContractLabelParts } from '../../utils/contractLabel';
import type { ContractType } from '../../types';
import { formatDate } from '../../utils/dateFormat';
import { useProviderSettings } from '../../hooks/useProviderSettings';
import { Plus, Trash2, Eye, EyeOff, Info, X, ArrowLeft, ExternalLink, Mail, Copy, FileText } from 'lucide-react';
import PdfViewerModal from '../../components/ui/PdfViewerModal';

// Kleine Helper-Komponente: Label + Mini-Link im neuen Tab. Wird neben
// Select-Feldern eingesetzt, deren Stammdaten an anderer Stelle gepflegt
// werden (Kundenakte, Settings) – damit der User direkt von dort in die
// passende Verwaltungsseite springen kann.
function LabelWithLink({ children, to, title }: { children: React.ReactNode; to: string; title: string }) {
  return (
    <span className="inline-flex items-center gap-2">
      <span>{children}</span>
      <Link
        to={to}
        target="_blank"
        rel="noopener noreferrer"
        className="inline-flex items-center text-blue-600 hover:text-blue-800"
        title={title}
        onClick={(e) => e.stopPropagation()}
      >
        <ExternalLink className="w-3 h-3" />
      </Link>
    </span>
  );
}
import { calculateConsumption, calculateMultiMeterConsumption } from '../../utils/energyCalculations';

// Contract types are now loaded dynamically from the database

const statusOptions = [
  { value: 'DRAFT', label: 'Entwurf' },
  { value: 'PENDING', label: 'Ausstehend' },
  { value: 'ACTIVE', label: 'Aktiv' },
  { value: 'ONGOING', label: 'Läuft weiter (unbestimmt)' },
  { value: 'CANCELLED', label: 'Gekündigt / Bestätigung abwarten' },
  { value: 'CANCELLED_CONFIRMED', label: 'Gekündigt / bestätigt' },
  { value: 'EXPIRED', label: 'Abgelaufen' },
  { value: 'DEACTIVATED', label: 'Deaktiviert' },
];

// 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>
  );
}

export default function ContractForm() {
  const { id } = useParams();
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const location = useLocation();
  const queryClient = useQueryClient();
  const isEdit = !!id;
  const back = popHistory(location.state, isEdit ? `/contracts/${id}` : '/contracts');
  const { customerEmailLabel } = useProviderSettings();

  const preselectedCustomerId = searchParams.get('customerId');
  // Kopier-Modus: `?copyFrom=<id>` legt einen NEUEN, eigenständigen Vertrag
  // an, aber mit allen Daten eines Bestandsvertrags vorbefüllt. Kein
  // Bearbeiten (isEdit bleibt false) → beim Speichern entsteht ein frischer
  // Vertrag. Unique-/instanzspezifische Felder werden beim Prefill geleert.
  const copyFromId = searchParams.get('copyFrom');
  const isCopy = !isEdit && !!copyFromId;

  const { register, handleSubmit, reset, watch, setValue, formState: { errors } } = useForm<any>({
    defaultValues: {
      customerId: preselectedCustomerId || '',
      type: 'ELECTRICITY',
      status: 'DRAFT',
      previousContractId: '',
    },
  });

  const contractType = watch('type') as ContractType;
  const customerId = watch('customerId');
  const previousContractId = watch('previousContractId');
  const selectedMeterId = watch('meterId');
  const selectedBankCardId = watch('bankCardId');
  const selectedDocumentId = watch('identityDocumentId');

  // Fetch existing contract for edit
  const { data: contract } = useQuery({
    queryKey: ['contract', id],
    queryFn: () => contractApi.getById(parseInt(id!)),
    enabled: isEdit,
  });

  // Fetch source contract for copy mode
  const { data: copySource } = useQuery({
    queryKey: ['contract', 'copy', copyFromId],
    queryFn: () => contractApi.getById(parseInt(copyFromId!)),
    enabled: isCopy,
  });

  // Fetch customers for dropdown
  const { data: customersData } = useQuery({
    queryKey: ['customers-all'],
    queryFn: () => customerApi.getAll({ limit: 1000 }),
  });

  // Fetch customer details when selected
  const { data: customerDetail } = useQuery({
    queryKey: ['customer', customerId],
    queryFn: () => customerApi.getById(parseInt(customerId)),
    enabled: !!customerId,
  });

  // Fetch contracts for same customer (for predecessor selection)
  const { data: customerContractsData } = useQuery({
    queryKey: ['customer-contracts-for-predecessor', customerId],
    // includeDeactivated: auch deaktivierte Verträge als möglichen Vorgänger
    // anbieten – sonst geht die Verknüpfung verloren, wenn man einen
    // Folgevertrag aus einem deaktivierten Vertrag anlegt/bearbeitet.
    queryFn: () => contractApi.getAll({ customerId: parseInt(customerId), limit: 1000, includeDeactivated: true }),
    enabled: !!customerId,
  });

  // Vorvertrag (für Verbrauchs-Übernahme bei Energieverträgen). Wird nur geladen,
  // wenn ein previousContractId gesetzt ist und der Typ Strom/Gas ist.
  const { data: previousContractData } = useQuery({
    queryKey: ['contract', previousContractId],
    queryFn: () => contractApi.getById(parseInt(previousContractId)),
    enabled: !!previousContractId && ['ELECTRICITY', 'GAS'].includes(contractType),
  });

  // Fetch platforms
  const { data: platformsData } = useQuery({
    queryKey: ['platforms'],
    queryFn: () => platformApi.getAll(),
  });

  // Fetch cancellation periods
  const { data: cancellationPeriodsData } = useQuery({
    queryKey: ['cancellation-periods'],
    queryFn: () => cancellationPeriodApi.getAll(),
  });

  // Fetch contract durations
  const { data: contractDurationsData } = useQuery({
    queryKey: ['contract-durations'],
    queryFn: () => contractDurationApi.getAll(),
  });

  // Fetch providers
  const { data: providersData } = useQuery({
    queryKey: ['providers'],
    queryFn: () => providerApi.getAll(),
  });

  // Fetch contract categories (types)
  const { data: contractCategoriesData } = useQuery({
    queryKey: ['contract-categories'],
    queryFn: () => contractCategoryApi.getAll(),
  });

  // Watch providerId for tariff filtering
  const selectedProviderId = watch('providerId');

  // Reset tariffId when providerId changes (but not on initial load)
  const [previousProviderId, setPreviousProviderId] = useState<string | null>(null);

  // SIM-Karten State für Mobilfunk
  interface SimCardInput {
    id?: number;
    phoneNumber: string;
    simCardNumber: string;
    pin: string;
    puk: string;
    hasExistingPin?: boolean;  // Zeigt an ob PIN bereits in DB vorhanden
    hasExistingPuk?: boolean;  // Zeigt an ob PUK bereits in DB vorhanden
    isMultisim: boolean;
    isMain: boolean;
    isEsim: boolean;
    cardUser: string;
  }
  const [simCards, setSimCards] = useState<SimCardInput[]>([]);

  // Rufnummern State für Internet-Verträge
  interface PhoneNumberInput {
    id?: number;
    // areaCode + subscriber sind die getrennten Eingabefelder.
    // phoneNumber-Feld in der DB ist immer die zusammengesetzte
    // "Vorwahl Anschluss"-Form, wird im Submit kombiniert.
    areaCode: string;
    subscriber: string;
    sipUsername: string;
    sipPassword: string;
    hasExistingSipPassword?: boolean;
    sipServer: string;
    isMain: boolean;
  }
  const [phoneNumbers, setPhoneNumbers] = useState<PhoneNumberInput[]>([]);
  const [isContractLoaded, setIsContractLoaded] = useState(false);

  // Portal-Benutzername: Manuell oder Stressfrei-Adresse
  const [usernameType, setUsernameType] = useState<'manual' | 'stressfrei' | 'not_required'>('manual');
  const [selectedStressfreiEmailId, setSelectedStressfreiEmailId] = useState<string>('');

  // Passwort-Sichtbarkeit
  const [showPortalPassword, setShowPortalPassword] = useState(false);
  const [showCustomerInfo, setShowCustomerInfo] = useState(false);
  // PDF-Viewer-Modal (Bankkarte-/Ausweis-Dokument der aktuell gewählten Karte)
  const [pdfModal, setPdfModal] = useState<{ title: string; path: string } | null>(null);
  const [showInternetPassword, setShowInternetPassword] = useState(false);
  const [showSipPasswords, setShowSipPasswords] = useState<Record<number, boolean>>({});
  const [showSimPins, setShowSimPins] = useState<Record<number, boolean>>({});
  const [showSimPuks, setShowSimPuks] = useState<Record<number, boolean>>({});

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

  // For new contracts, mark as "loaded" immediately so provider change detection works
  useEffect(() => {
    if (!isEdit) {
      setIsContractLoaded(true);
    }
  }, [isEdit]);

  // Set preselected customer from URL params (for new contracts)
  useEffect(() => {
    if (!isEdit && preselectedCustomerId && customersData?.data) {
      // Only set if the customer exists in the list
      const customerExists = customersData.data.some(c => c.id.toString() === preselectedCustomerId);
      if (customerExists) {
        setValue('customerId', preselectedCustomerId);
      }
    }
  }, [isEdit, preselectedCustomerId, customersData, setValue]);

  // Reset tariffId when providerId changes (but only after initial contract load)
  useEffect(() => {
    // Only reset tariff if:
    // 1. Contract has been loaded (or we're creating new)
    // 2. Provider actually changed (not empty/null -> value which happens on load)
    // Note: previousProviderId can be '' (empty string) initially, so we need to check for truthy
    if (isContractLoaded && previousProviderId && selectedProviderId !== previousProviderId) {
      setValue('tariffId', '');
    }
    setPreviousProviderId(selectedProviderId);
  }, [selectedProviderId, previousProviderId, setValue, isContractLoaded]);

  // Set default type when categories are loaded (only for new contracts)
  useEffect(() => {
    if (!isEdit && contractCategoriesData?.data && contractCategoriesData.data.length > 0) {
      const currentType = watch('type');
      // Only set if current type is empty or doesn't exist in categories
      const categories = contractCategoriesData.data.filter(c => c.isActive);
      const typeExists = categories.some(c => c.code === currentType);
      if (!currentType || !typeExists) {
        const firstCategory = categories.sort((a, b) => a.sortOrder - b.sortOrder)[0];
        if (firstCategory) {
          setValue('type', firstCategory.code);
        }
      }
    }
  }, [contractCategoriesData, isEdit, setValue, watch]);

  // Bootstrap: Set customerId first so customerDetail can load (needed for dropdowns)
  useEffect(() => {
    if (isEdit && contract?.data && !customerId) {
      setValue('customerId', contract.data.customerId.toString());
    } else if (isCopy && copySource?.data && !customerId) {
      setValue('customerId', copySource.data.customerId.toString());
    }
  }, [isEdit, contract, isCopy, copySource, customerId, setValue]);

  // Reset form when contract data AND ALL dropdown data are loaded
  // This ensures dropdowns can properly display the selected values
  // We need customerDetail for addresses/bankCards/documents and providersData for tariffs
  useEffect(() => {
    const src = isEdit ? contract?.data : (isCopy ? copySource?.data : null);
    if (src && platformsData?.data && contractCategoriesData?.data && providersData?.data && customerDetail?.data) {
      const c = src;
      const values: any = {
        customerId: c.customerId.toString(),
        type: c.type,
        status: c.status,
        addressId: c.addressId?.toString() || '',
        billingAddressId: c.billingAddressId?.toString() || '',
        bankCardId: c.bankCardId?.toString() || '',
        identityDocumentId: c.identityDocumentId?.toString() || '',
        salesPlatformId: c.salesPlatformId?.toString() || '',
        providerId: c.providerId?.toString() || '',
        tariffId: c.tariffId?.toString() || '',
        providerName: c.providerName || '',
        tariffName: c.tariffName || '',
        customerNumberAtProvider: c.customerNumberAtProvider || '',
        contractNumberAtProvider: c.contractNumberAtProvider || '',
        orderNumberAtSalesPlatform: c.orderNumberAtSalesPlatform || '',
        customerNumberAtSalesPlatform: c.customerNumberAtSalesPlatform || '',
        contractNumberAtSalesPlatform: c.contractNumberAtSalesPlatform || '',
        priceFirst12Months: c.priceFirst12Months || '',
        priceFrom13Months: c.priceFrom13Months || '',
        priceAfter24Months: c.priceAfter24Months || '',
        startDate: c.startDate ? c.startDate.split('T')[0] : '',
        endDate: c.endDate ? c.endDate.split('T')[0] : '',
        cancellationPeriodId: c.cancellationPeriodId?.toString() || '',
        contractDurationId: c.contractDurationId?.toString() || '',
        commission: c.commission || '',
        portalUsername: c.portalUsername || '',
        notes: c.notes || '',
        // Energy details
        meterId: c.energyDetails?.meterId?.toString() || '',
        annualConsumption: c.energyDetails?.annualConsumption || '',
        annualConsumptionKwh: c.energyDetails?.annualConsumptionKwh || '',
        basePrice: c.energyDetails?.basePrice || '',
        unitPrice: c.energyDetails?.unitPrice || '',
        unitPriceNt: c.energyDetails?.unitPriceNt || '',
        instantBonus: c.energyDetails?.instantBonus || '',
        newCustomerBonus: c.energyDetails?.newCustomerBonus || '',
        noBonusDesired: c.energyDetails?.noBonusDesired || false,
        // Internet details
        downloadSpeed: c.internetDetails?.downloadSpeed || '',
        uploadSpeed: c.internetDetails?.uploadSpeed || '',
        routerModel: c.internetDetails?.routerModel || '',
        routerSerialNumber: c.internetDetails?.routerSerialNumber || '',
        installationDate: c.internetDetails?.installationDate ? c.internetDetails.installationDate.split('T')[0] : '',
        internetUsername: c.internetDetails?.internetUsername || '',
        propertyType: c.internetDetails?.propertyType || '',
        propertyLocation: c.internetDetails?.propertyLocation || '',
        connectionLocation: c.internetDetails?.connectionLocation || '',
        homeId: c.internetDetails?.homeId || '',
        activationCode: c.internetDetails?.activationCode || '',
        // Mobile details
        requiresMultisim: c.mobileDetails?.requiresMultisim || false,
        mobileNetwork: c.mobileDetails?.mobileNetwork || '',
        dataVolume: c.mobileDetails?.dataVolume || '',
        includedMinutes: c.mobileDetails?.includedMinutes || '',
        includedSMS: c.mobileDetails?.includedSMS || '',
        deviceModel: c.mobileDetails?.deviceModel || '',
        deviceImei: c.mobileDetails?.deviceImei || '',
        // Legacy
        phoneNumber: c.mobileDetails?.phoneNumber || '',
        simCardNumber: c.mobileDetails?.simCardNumber || '',
        // TV details
        receiverModel: c.tvDetails?.receiverModel || '',
        smartcardNumber: c.tvDetails?.smartcardNumber || '',
        tvPackage: c.tvDetails?.package || '',
        // Car insurance details
        licensePlate: c.carInsuranceDetails?.licensePlate || '',
        hsn: c.carInsuranceDetails?.hsn || '',
        tsn: c.carInsuranceDetails?.tsn || '',
        vin: c.carInsuranceDetails?.vin || '',
        vehicleType: c.carInsuranceDetails?.vehicleType || '',
        firstRegistration: c.carInsuranceDetails?.firstRegistration ? c.carInsuranceDetails.firstRegistration.split('T')[0] : '',
        noClaimsClass: c.carInsuranceDetails?.noClaimsClass || '',
        insuranceType: c.carInsuranceDetails?.insuranceType || 'LIABILITY',
        deductiblePartial: c.carInsuranceDetails?.deductiblePartial || '',
        deductibleFull: c.carInsuranceDetails?.deductibleFull || '',
        policyNumber: c.carInsuranceDetails?.policyNumber || '',
        previousInsurer: c.carInsuranceDetails?.previousInsurer || '',
        // Kündigungsdaten
        cancellationConfirmationDate: c.cancellationConfirmationDate ? c.cancellationConfirmationDate.split('T')[0] : '',
        cancellationConfirmationOptionsDate: c.cancellationConfirmationOptionsDate ? c.cancellationConfirmationOptionsDate.split('T')[0] : '',
        wasSpecialCancellation: c.wasSpecialCancellation || false,
        // Vorgänger-Vertrag
        previousContractId: c.previousContractId?.toString() || '',
        // Altanbieter (nur wenn kein Vorgängervertrag)
        previousProviderId: c.previousProviderId?.toString() || '',
        previousCustomerNumber: c.previousCustomerNumber || '',
        previousContractNumber: c.previousContractNumber || '',
      };

      // Kopier-Modus: instanz-spezifische / eindeutige Felder leeren, damit
      // ein echter neuer eigenständiger Vertrag entsteht und keine Nummern
      // versehentlich doppelt vergeben werden. Der Rest (Tarif, Anbieter,
      // Preise, Detailfelder …) bleibt als Vorlage erhalten und wird vom
      // User bei Bedarf angepasst.
      if (isCopy) {
        Object.assign(values, {
          status: 'DRAFT',
          previousContractId: '',
          // Neuer Vertrag = neuer Zeitraum
          startDate: '',
          endDate: '',
          installationDate: '',
          cancellationConfirmationDate: '',
          cancellationConfirmationOptionsDate: '',
          wasSpecialCancellation: false,
          // Legacy-Mobilfunk-Felder (kein sichtbares Formularfeld mehr, aber
          // im Reset gesetzt): eindeutige Rufnummer/SIM-Nummer ebenfalls
          // leeren, sonst trügen zwei getrennte Verträge desselben Kunden
          // unbemerkt dieselbe Rufnummer (Pentest R135/136). Die SIM-Karten-
          // Liste wird ohnehin schon nicht übernommen.
          phoneNumber: '',
          simCardNumber: '',
          // Eindeutige Kunden-/Vertragsnummern beim Anbieter & Plattform
          customerNumberAtProvider: '',
          contractNumberAtProvider: '',
          orderNumberAtSalesPlatform: '',
          customerNumberAtSalesPlatform: '',
          contractNumberAtSalesPlatform: '',
          // Portal-Zugangsdaten (Benutzername/Stressfrei-Verknüpfung) bewusst
          // BEHALTEN – bei gleichem Anbieter oft identisch. Das Passwort liegt
          // verschlüsselt vor und wird (wie beim Bearbeiten) nicht ins Feld
          // geladen; es bleibt leer und kann bei Bedarf neu gesetzt werden.
        });
      }

      reset(values);

      // SIM-Karten & Rufnummern sind hardware-/vertragsspezifisch (eindeutige
      // Karten-/Telefonnummern) → im Kopier-Modus NICHT übernehmen.
      // Load simCards if available
      if (!isCopy && c.mobileDetails?.simCards && c.mobileDetails.simCards.length > 0) {
        setSimCards(c.mobileDetails.simCards.map(sc => ({
          id: sc.id,
          phoneNumber: sc.phoneNumber || '',
          simCardNumber: sc.simCardNumber || '',
          pin: '', // PIN/PUK werden nicht im Klartext geladen
          puk: '',
          hasExistingPin: !!sc.pin,  // true wenn verschlüsselter Wert vorhanden
          hasExistingPuk: !!sc.puk,  // true wenn verschlüsselter Wert vorhanden
          isMultisim: sc.isMultisim,
          isMain: sc.isMain,
          isEsim: sc.isEsim ?? false,
          cardUser: sc.cardUser || '',
        })));
      } else {
        setSimCards([]);
      }

      // Load phoneNumbers if available (Internet contracts)
      if (!isCopy && c.internetDetails?.phoneNumbers && c.internetDetails.phoneNumbers.length > 0) {
        setPhoneNumbers(c.internetDetails.phoneNumbers.map(pn => {
          // Wenn areaCode gepflegt ist → 1:1 nutzen, sonst aus phoneNumber
          // heuristisch splitten (dann sollte der User das Ergebnis prüfen
          // und beim nächsten Speichern fixen).
          const splitLegacy = (s: string) => {
            const cleaned = s.replace(/[()]/g, '').trim();
            const sep = cleaned.match(/^(\d{2,5})[\/\s\-](.+)$/);
            if (sep) return { ac: sep[1], rest: sep[2].replace(/[\s\-/]/g, '') };
            const noSep = cleaned.match(/^(0\d{1,4})(\d{3,})$/);
            if (noSep) return { ac: noSep[1], rest: noSep[2] };
            return { ac: '', rest: cleaned };
          };
          const full = pn.phoneNumber || '';
          let ac = pn.areaCode || '';
          let rest = '';
          if (ac && full.startsWith(ac)) {
            rest = full.slice(ac.length).replace(/^[\s\-/]+/, '').trim();
          } else if (ac) {
            rest = full.replace(ac, '').replace(/^[\s\-/]+/, '').trim();
          } else {
            const s = splitLegacy(full);
            ac = s.ac;
            rest = s.rest;
          }
          return {
            id: pn.id,
            areaCode: ac,
            subscriber: rest,
            sipUsername: pn.sipUsername || '',
            sipPassword: '', // SIP-Passwort wird nicht im Klartext geladen
            hasExistingSipPassword: !!pn.sipPasswordEncrypted,
            sipServer: pn.sipServer || '',
            isMain: pn.isMain,
          };
        }));
      } else {
        setPhoneNumbers([]);
      }

      // Portal-Benutzername-Typ initialisieren.
      // Opt-out („nicht benötigt") gewinnt vor Stressfrei/Manual, damit ein
      // versehentlich noch alter portalUsername den Radio-Zustand nicht
      // überstimmt. Gilt auch im Kopier-Modus: Portal-Zugangsdaten werden
      // mitkopiert (nur das Passwort bleibt leer, s.o.).
      if (c.portalCredentialsNotRequired) {
        setUsernameType('not_required');
        setSelectedStressfreiEmailId('');
      } else if (c.stressfreiEmailId) {
        setUsernameType('stressfrei');
        setSelectedStressfreiEmailId(c.stressfreiEmailId.toString());
      } else {
        setUsernameType('manual');
        setSelectedStressfreiEmailId('');
      }

      // Mark contract as loaded so provider change detection works correctly
      setIsContractLoaded(true);
    }
  }, [contract, copySource, isEdit, isCopy, reset, platformsData, contractCategoriesData, providersData, customerDetail]);

  // Watch für Enddatum-Berechnung
  const startDate = watch('startDate');
  const contractDurationId = watch('contractDurationId');

  // Berechne Vertragsende aus Beginn + Laufzeit
  useEffect(() => {
    if (startDate && contractDurationId && contractDurationsData?.data) {
      const duration = contractDurationsData.data.find(d => d.id === parseInt(contractDurationId));
      if (duration) {
        const start = new Date(startDate);
        const code = duration.code;

        // Parse duration code (z.B. "12M", "24M", "1J", "2J")
        const match = code.match(/^(\d+)([MTJ])$/);
        if (match) {
          const value = parseInt(match[1]);
          const unit = match[2];

          let endDate = new Date(start);
          if (unit === 'T') {
            endDate.setDate(endDate.getDate() + value);
          } else if (unit === 'M') {
            endDate.setMonth(endDate.getMonth() + value);
          } else if (unit === 'J') {
            endDate.setFullYear(endDate.getFullYear() + value);
          }

          // Setze das berechnete Enddatum
          setValue('endDate', endDate.toISOString().split('T')[0]);
        }
      }
    }
  }, [startDate, contractDurationId, contractDurationsData, setValue]);

  const createMutation = useMutation({
    mutationFn: contractApi.create,
    onSuccess: (_, variables) => {
      queryClient.invalidateQueries({ queryKey: ['contracts'] });
      if (variables.customerId) {
        queryClient.invalidateQueries({ queryKey: ['customer', variables.customerId.toString()] });
      }
      queryClient.invalidateQueries({ queryKey: ['customers'] });
      // Navigate back to customer's contracts tab if coming from customer
      if (preselectedCustomerId) {
        navigate(`/customers/${preselectedCustomerId}?tab=contracts`);
      } else {
        navigate('/contracts');
      }
    },
  });

  const updateMutation = useMutation({
    mutationFn: (data: any) => contractApi.update(parseInt(id!), data),
    onSuccess: (_, variables) => {
      queryClient.invalidateQueries({ queryKey: ['contracts'] });
      queryClient.invalidateQueries({ queryKey: ['contract', id] });
      if (variables.customerId) {
        queryClient.invalidateQueries({ queryKey: ['customer', variables.customerId.toString()] });
      }
      queryClient.invalidateQueries({ queryKey: ['customers'] });
      navigate(`/contracts/${id}`);
    },
  });

  const onSubmit = (data: any) => {
    // Helper to safely parse integers - returns undefined for empty/invalid values
    const safeParseInt = (val: string | number | undefined | null): number | undefined => {
      if (val === undefined || val === null || val === '') return undefined;
      const parsed = parseInt(String(val));
      return isNaN(parsed) ? undefined : parsed;
    };

    // Find the selected category to get its ID
    const selectedCategory = contractCategories.find(c => c.code === data.type);

    // Validate required fields
    const customerIdParsed = safeParseInt(data.customerId);
    if (!customerIdParsed) {
      alert('Bitte wählen Sie einen Kunden aus');
      return;
    }

    if (!data.type || !selectedCategory) {
      alert('Bitte wählen Sie einen Vertragstyp aus');
      return;
    }

    // Helper: Leere Strings werden zu null, damit Prisma das Feld auf NULL setzt
    const emptyToNull = (val: string | undefined | null): string | null => {
      if (val === undefined || val === null || val === '') return null;
      return val;
    };

    const contractData: any = {
      customerId: customerIdParsed,
      type: data.type,
      contractCategoryId: selectedCategory.id,
      status: data.status,
      addressId: safeParseInt(data.addressId) ?? null,
      billingAddressId: safeParseInt(data.billingAddressId) ?? null,
      bankCardId: safeParseInt(data.bankCardId) ?? null,
      identityDocumentId: safeParseInt(data.identityDocumentId) ?? null,
      salesPlatformId: safeParseInt(data.salesPlatformId) ?? null,
      providerId: safeParseInt(data.providerId) ?? null,
      tariffId: safeParseInt(data.tariffId) ?? null,
      providerName: emptyToNull(data.providerName),
      tariffName: emptyToNull(data.tariffName),
      customerNumberAtProvider: emptyToNull(data.customerNumberAtProvider),
      contractNumberAtProvider: emptyToNull(data.contractNumberAtProvider),
      orderNumberAtSalesPlatform: emptyToNull(data.orderNumberAtSalesPlatform),
      customerNumberAtSalesPlatform: emptyToNull(data.customerNumberAtSalesPlatform),
      contractNumberAtSalesPlatform: emptyToNull(data.contractNumberAtSalesPlatform),
      priceFirst12Months: emptyToNull(data.priceFirst12Months),
      priceFrom13Months: emptyToNull(data.priceFrom13Months),
      priceAfter24Months: emptyToNull(data.priceAfter24Months),
      startDate: data.startDate ? new Date(data.startDate) : null,
      endDate: data.endDate ? new Date(data.endDate) : null,
      cancellationPeriodId: safeParseInt(data.cancellationPeriodId) ?? null,
      contractDurationId: safeParseInt(data.contractDurationId) ?? null,
      commission: data.commission ? parseFloat(data.commission) : null,
      // Portal-Benutzername: manuell, Stressfrei-Adresse oder Opt-out.
      // Bei 'not_required' werden Username-Felder + Passwort explizit
      // geleert und das Flag gesetzt – so verschwindet die Cockpit-Warnung.
      portalUsername: usernameType === 'manual' ? emptyToNull(data.portalUsername) : null,
      stressfreiEmailId: usernameType === 'stressfrei' && selectedStressfreiEmailId ? parseInt(selectedStressfreiEmailId) : null,
      portalCredentialsNotRequired: usernameType === 'not_required',
      portalPassword: usernameType === 'not_required' ? undefined : (data.portalPassword || undefined), // Passwort: undefined = nicht ändern
      notes: emptyToNull(data.notes),
      cancellationConfirmationDate: data.cancellationConfirmationDate ? new Date(data.cancellationConfirmationDate) : null,
      cancellationConfirmationOptionsDate: data.cancellationConfirmationOptionsDate ? new Date(data.cancellationConfirmationOptionsDate) : null,
      wasSpecialCancellation: data.wasSpecialCancellation || false,
      previousContractId: safeParseInt(data.previousContractId) ?? null,
      // Altanbieter (nur wenn kein Vorgängervertrag)
      previousProviderId: data.previousContractId ? null : (safeParseInt(data.previousProviderId) ?? null),
      previousCustomerNumber: data.previousContractId ? null : emptyToNull(data.previousCustomerNumber),
      previousContractNumber: data.previousContractId ? null : emptyToNull(data.previousContractNumber),
    };

    // Add type-specific details
    if (['ELECTRICITY', 'GAS'].includes(data.type)) {
      contractData.energyDetails = {
        meterId: safeParseInt(data.meterId) ?? null,
        // maloId wird nicht mehr am Vertrag gepflegt – sie gehört zur Lieferadresse.
        annualConsumption: data.annualConsumption ? parseFloat(data.annualConsumption) : null,
        annualConsumptionKwh: data.annualConsumptionKwh ? parseFloat(data.annualConsumptionKwh) : null,
        basePrice: data.basePrice ? parseFloat(data.basePrice) : null,
        unitPrice: data.unitPrice ? parseFloat(data.unitPrice) : null,
        unitPriceNt: data.unitPriceNt ? parseFloat(data.unitPriceNt) : null,
        instantBonus: data.instantBonus ? parseFloat(data.instantBonus) : null,
        newCustomerBonus: data.newCustomerBonus ? parseFloat(data.newCustomerBonus) : null,
        noBonusDesired: !!data.noBonusDesired,
      };
    }

    if (['DSL', 'CABLE', 'FIBER'].includes(data.type)) {
      contractData.internetDetails = {
        downloadSpeed: safeParseInt(data.downloadSpeed) ?? null,
        uploadSpeed: safeParseInt(data.uploadSpeed) ?? null,
        routerModel: emptyToNull(data.routerModel),
        routerSerialNumber: emptyToNull(data.routerSerialNumber),
        installationDate: data.installationDate ? new Date(data.installationDate) : null,
        // Internet-Zugangsdaten
        internetUsername: emptyToNull(data.internetUsername),
        internetPassword: data.internetPassword || undefined, // Passwort: undefined = nicht ändern
        // Objekt & Lage
        propertyType: emptyToNull(data.propertyType),
        propertyLocation: emptyToNull(data.propertyLocation),
        connectionLocation: emptyToNull(data.connectionLocation),
        // Glasfaser-spezifisch
        homeId: emptyToNull(data.homeId),
        // Vodafone DSL/Kabel spezifisch
        activationCode: emptyToNull(data.activationCode),
        // Rufnummern mit SIP-Daten
        phoneNumbers: phoneNumbers.length > 0 ? phoneNumbers.map(pn => {
          const ac = (pn.areaCode || '').trim();
          const sub = (pn.subscriber || '').trim();
          // phoneNumber bleibt das kombinierte "Vorwahl Anschluss"-Feld
          // für Listen/Suchen, areaCode/subscriber sind die getrennten Werte.
          const combined = ac && sub ? `${ac} ${sub}` : (sub || ac);
          return {
            id: pn.id,
            phoneNumber: combined,
            areaCode: ac || undefined,
            isMain: pn.isMain ?? false,
            sipUsername: emptyToNull(pn.sipUsername),
            sipPassword: pn.sipPassword || undefined, // Passwort: undefined = nicht ändern
            sipServer: emptyToNull(pn.sipServer),
          };
        }) : undefined,
      };
    }

    if (data.type === 'MOBILE') {
      contractData.mobileDetails = {
        requiresMultisim: data.requiresMultisim || false,
        mobileNetwork: emptyToNull(data.mobileNetwork),
        dataVolume: data.dataVolume ? parseFloat(data.dataVolume) : null,
        includedMinutes: safeParseInt(data.includedMinutes) ?? null,
        includedSMS: safeParseInt(data.includedSMS) ?? null,
        deviceModel: emptyToNull(data.deviceModel),
        deviceImei: emptyToNull(data.deviceImei),
        // Legacy
        phoneNumber: emptyToNull(data.phoneNumber),
        simCardNumber: emptyToNull(data.simCardNumber),
        // SIM-Karten
        simCards: simCards.length > 0 ? simCards.map(sc => ({
          id: sc.id,
          phoneNumber: emptyToNull(sc.phoneNumber),
          simCardNumber: emptyToNull(sc.simCardNumber),
          pin: sc.pin || undefined, // Passwort: undefined = nicht ändern
          puk: sc.puk || undefined, // Passwort: undefined = nicht ändern
          isMultisim: sc.isMultisim,
          isMain: sc.isMain,
          isEsim: sc.isEsim,
          cardUser: emptyToNull(sc.cardUser),
        })) : undefined,
      };
    }

    if (data.type === 'TV') {
      contractData.tvDetails = {
        receiverModel: emptyToNull(data.receiverModel),
        smartcardNumber: emptyToNull(data.smartcardNumber),
        package: emptyToNull(data.tvPackage),
      };
    }

    if (data.type === 'CAR_INSURANCE') {
      contractData.carInsuranceDetails = {
        licensePlate: emptyToNull(data.licensePlate),
        hsn: emptyToNull(data.hsn),
        tsn: emptyToNull(data.tsn),
        vin: emptyToNull(data.vin),
        vehicleType: emptyToNull(data.vehicleType),
        firstRegistration: data.firstRegistration ? new Date(data.firstRegistration) : null,
        noClaimsClass: emptyToNull(data.noClaimsClass),
        insuranceType: data.insuranceType,
        deductiblePartial: data.deductiblePartial ? parseFloat(data.deductiblePartial) : null,
        deductibleFull: data.deductibleFull ? parseFloat(data.deductibleFull) : null,
        policyNumber: emptyToNull(data.policyNumber),
        previousInsurer: emptyToNull(data.previousInsurer),
      };
    }

    if (isEdit) {
      updateMutation.mutate(contractData);
    } else {
      createMutation.mutate(contractData);
    }
  };

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

  const customer = customerDetail?.data;
  const addresses = customer?.addresses || [];
  const bankCards = customer?.bankCards?.filter((c) => c.isActive) || [];
  const documents = customer?.identityDocuments?.filter((d) => d.isActive) || [];
  // Aktuell im Dropdown gewählte Bankkarte/Ausweis – für die Copy-Buttons
  // neben dem Label (nur reiner Wert: IBAN bzw. Ausweisnummer).
  const selectedBankCard = bankCards.find((c) => c.id.toString() === String(selectedBankCardId));
  const selectedDocument = documents.find((d) => d.id.toString() === String(selectedDocumentId));
  const meters = customer?.meters || [];
  const selectedMeter = meters.find(m => m.id.toString() === selectedMeterId);

  // Verbrauch aus Vorvertrag berechnen (für Übernehmen-Hinweis am Jahresverbrauch).
  // Nutzt die clientseitige Verbrauchsberechnung – egal ob Single- oder Multi-Meter,
  // egal ob exakt oder hochgerechnet.
  const previousConsumption = useMemo(() => {
    const pc = previousContractData?.data;
    if (!pc?.energyDetails || !pc.startDate || !pc.endDate) return null;
    if (!['ELECTRICITY', 'GAS'].includes(pc.type)) return null;
    const cms = pc.energyDetails.contractMeters || [];
    if (cms.length > 0) {
      return calculateMultiMeterConsumption(cms, pc.startDate, pc.endDate, pc.type as 'ELECTRICITY' | 'GAS');
    }
    const readings = pc.energyDetails.meter?.readings || [];
    if (readings.length === 0) return null;
    return calculateConsumption(readings, pc.startDate, pc.endDate, pc.type as 'ELECTRICITY' | 'GAS');
  }, [previousContractData]);
  const previousConsumptionUsable = previousConsumption
    && (previousConsumption.type === 'exact' || previousConsumption.type === 'projected');
  const stressfreiEmails = customer?.stressfreiEmails?.filter((e: { isActive: boolean }) => e.isActive) || [];
  const platforms = platformsData?.data || [];
  const cancellationPeriods = cancellationPeriodsData?.data || [];
  const contractDurations = contractDurationsData?.data || [];
  const providers = providersData?.data?.filter(p => p.isActive) || [];
  const contractCategories = contractCategoriesData?.data?.filter(c => c.isActive).sort((a, b) => a.sortOrder - b.sortOrder) || [];
  const typeOptions = contractCategories.map(c => ({ value: c.code, label: c.name }));

  // Available predecessor contracts (same customer, excluding current contract if editing)
  const predecessorContracts = (customerContractsData?.data || [])
    .filter(c => !isEdit || c.id !== parseInt(id!))
    .sort((a, b) => new Date(b.startDate || 0).getTime() - new Date(a.startDate || 0).getTime());

  // Get tariffs for selected provider
  const selectedProvider = providers.find(p => p.id === parseInt(selectedProviderId || '0'));
  const availableTariffs = selectedProvider?.tariffs?.filter(t => t.isActive) || [];

  // Helper to format customer label with optional birth date
  const formatCustomerLabel = (c: { customerNumber: string; companyName?: string; firstName: string; lastName: string; birthDate?: string }) => {
    const name = c.companyName || `${c.firstName} ${c.lastName}`;
    const birthDateStr = c.birthDate
      ? ` (geb. ${new Date(c.birthDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })})`
      : '';
    return `${c.customerNumber} - ${name}${birthDateStr}`;
  };

  // Build customer options, ensuring current customer from contract is always included
  const customerOptions = (() => {
    const customers = customersData?.data || [];
    const options = customers.map((c) => ({
      value: c.id.toString(),
      label: formatCustomerLabel(c),
    }));

    // If editing and contract's customer isn't in the list yet, add it
    if (isEdit && contract?.data?.customer) {
      const contractCustomer = contract.data.customer;
      const exists = options.some((o) => o.value === contractCustomer.id.toString());
      if (!exists) {
        options.unshift({
          value: contractCustomer.id.toString(),
          label: formatCustomerLabel(contractCustomer),
        });
      }
    }

    return options;
  })();

  return (
    <div>
      {/* Sticky-Header: Zurück-Button + Titel + Kunde-Zeile bleiben beim
          Scrollen oben stehen. Layout-Padding wird per -mx-8 px-8
          überbrückt, damit der Balken bündig ist. */}
      <div className="sticky top-[var(--app-banner-h,0px)] z-20 -mx-8 px-8 pt-4 pb-3 mb-6 bg-gray-100 border-b border-gray-200">
        <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">
            {isEdit ? 'Vertrag bearbeiten' : isCopy ? 'Neuer Vertrag (Kopie)' : 'Neuer Vertrag'}
          </h1>
        </div>
        {isCopy && (
          <p className="ml-12 mt-1 text-sm text-blue-700 bg-blue-50 border border-blue-200 rounded px-2 py-1 inline-flex items-center gap-1">
            <Copy className="w-4 h-4" />
            Kopie eines bestehenden Vertrags – wird als <strong>neuer eigenständiger Vertrag</strong> gespeichert.
            Anbieter/Tarif, Preise, Kunden-/Vertragsnummern und Daten bitte prüfen. Portal-Benutzername
            übernommen, Passwort ggf. neu setzen.
          </p>
        )}
        {customer && (
          <p className="text-gray-500 ml-12 flex items-center gap-1">
            Kunde:{' '}
            <Link
              to={`/customers/${customer.id}`}
              className="text-blue-600 hover:underline"
            >
              {customer.companyName || `${customer.firstName} ${customer.lastName}`}
            </Link>
            <a
              href={`/customers/${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)"
              aria-label="Kundendaten anzeigen"
              className="text-gray-400 hover:text-blue-600 p-1 rounded"
            >
              <Info className="w-4 h-4" />
            </button>
          </p>
        )}
      </div>

      {error && (
        <div className="mb-4 p-4 bg-red-50 border border-red-200 text-red-700 rounded-lg">
          {error instanceof Error ? error.message : 'Ein Fehler ist aufgetreten'}
        </div>
      )}

      <form onSubmit={handleSubmit(onSubmit)}>
        <Card className="mb-6" title="Vertragsdaten">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <Select
              label="Kunde *"
              {...register('customerId', { required: 'Kunde erforderlich' })}
              options={customerOptions}
              error={errors.customerId?.message as string}
            />

            <Select
              label="Vertragstyp *"
              {...register('type', { required: 'Typ erforderlich' })}
              options={typeOptions}
            />

            <div>
              <div className="flex items-center gap-1 mb-1">
                <label className="block text-sm font-medium text-gray-700">Status</label>
                <button
                  type="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>
              </div>
              <Select
                {...register('status')}
                options={statusOptions}
              />
            </div>

            <Select
              label={
                <LabelWithLink to="/settings/platforms" title="Vertriebsplattformen verwalten (neuer Tab)">
                  Vertriebsplattform
                </LabelWithLink>
              }
              {...register('salesPlatformId')}
              options={platforms.map((p) => ({ value: p.id, label: p.name }))}
            />

            {/* Vorgänger-Vertrag auswählen (nur wenn Kunde gewählt) */}
            {customerId && (
              <Select
                label="Vorgänger-Vertrag"
                {...register('previousContractId')}
                options={predecessorContracts.map((c) => {
                  const parts = buildContractLabelParts(c);
                  const dateHint = c.startDate ? ` – ${formatDate(c.startDate)}` : '';
                  const suffix = parts.extras.length > 0 ? ` · ${parts.extras.join(' · ')}` : '';
                  const deact = c.status === 'DEACTIVATED' ? ' · deaktiviert' : '';
                  return {
                    value: c.id,
                    label: `${c.contractNumber} (${c.type}${dateHint})${suffix}${deact}`,
                  };
                })}
                placeholder="Keinen Vorgänger auswählen"
              />
            )}

            {/* Altanbieter-Daten (nur wenn KEIN Vorgängervertrag ausgewählt) */}
            {customerId && !previousContractId && (
              <div className="mt-4 p-4 bg-gray-50 rounded-lg border border-gray-200">
                <h4 className="text-sm font-medium text-gray-700 mb-3">Altanbieter-Daten</h4>
                <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                  <Select
                    label="Altanbieter"
                    {...register('previousProviderId')}
                    options={providers.map((p) => ({ value: p.id, label: p.name }))}
                    placeholder="Bitte wählen..."
                  />
                  <Input
                    label="Kundennr. beim Altanbieter"
                    {...register('previousCustomerNumber')}
                  />
                  <Input
                    label="Vertragsnr. beim Altanbieter"
                    {...register('previousContractNumber')}
                  />
                </div>
              </div>
            )}
          </div>
        </Card>

        {customerId && (
          <Card className="mb-6" title="Kundendaten verknüpfen">
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
              <Select
                label={
                  <LabelWithLink to={`/customers/${customerId}?tab=addresses`} title="Adressen des Kunden in neuem Tab öffnen">
                    Lieferadresse
                  </LabelWithLink>
                }
                {...register('addressId')}
                options={addresses
                  .filter((a) => a.type === 'DELIVERY_RESIDENCE')
                  .map((a) => ({
                    value: a.id,
                    label: `${a.street} ${a.houseNumber}, ${a.postalCode} ${a.city}`,
                  }))}
              />

              <Select
                label={
                  <LabelWithLink to={`/customers/${customerId}?tab=addresses`} title="Adressen des Kunden in neuem Tab öffnen">
                    Rechnungsadresse
                  </LabelWithLink>
                }
                {...register('billingAddressId')}
                options={addresses
                  .filter((a) => a.type === 'BILLING')
                  .map((a) => ({
                    value: a.id,
                    label: `${a.street} ${a.houseNumber}, ${a.postalCode} ${a.city}`,
                  }))}
                placeholder="Wie Lieferadresse"
              />
            </div>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div>
              <Select
                label={
                  <span className="inline-flex items-center gap-1">
                    <LabelWithLink to={`/customers/${customerId}?tab=bankcards`} title="Bankkarten des Kunden in neuem Tab öffnen">
                      Bankkarte
                    </LabelWithLink>
                    {selectedBankCard?.documentPath && (
                      <button
                        type="button"
                        onClick={(e) => { e.preventDefault(); e.stopPropagation(); setPdfModal({ title: 'Bankkarte – Dokument', path: selectedBankCard.documentPath! }); }}
                        className="text-gray-400 hover:text-blue-600 p-0.5 rounded"
                        title="Hinterlegtes Dokument anzeigen (PDF)"
                        aria-label="Bankkarten-Dokument anzeigen"
                      >
                        <FileText className="w-3.5 h-3.5" />
                      </button>
                    )}
                    {selectedBankCard && (
                      <CopyButton value={selectedBankCard.iban} title="IBAN kopieren" />
                    )}
                  </span>
                }
                {...register('bankCardId')}
                options={bankCards.map((c) => {
                  // Beschreibung kompakt anhängen, damit man Karten am
                  // Kontext unterscheiden kann (z.B. "Geschäftskonto").
                  // Newlines flach machen, Länge cappen.
                  const desc = c.description
                    ? c.description.replace(/\s+/g, ' ').trim().slice(0, 60)
                    : '';
                  return {
                    value: c.id,
                    label: `${c.iban} (${c.accountHolder})${desc ? ` – ${desc}` : ''}`,
                  };
                })}
              />
              {selectedBankCard && (
                <div className="mt-1.5 space-y-0.5 text-xs text-gray-600">
                  {selectedBankCard.bic && (
                    <div className="flex items-center gap-1"><span className="text-gray-500">BIC:</span> {selectedBankCard.bic}<CopyButton value={selectedBankCard.bic} /></div>
                  )}
                  {selectedBankCard.bankName && (
                    <div className="flex items-center gap-1"><span className="text-gray-500">Bank:</span> {selectedBankCard.bankName}<CopyButton value={selectedBankCard.bankName} /></div>
                  )}
                  {selectedBankCard.cardNumber && (
                    <div className="flex items-center gap-1"><span className="text-gray-500">Kartennummer:</span> {selectedBankCard.cardNumber}<CopyButton value={selectedBankCard.cardNumber} /></div>
                  )}
                  {selectedBankCard.expiryDate && (
                    <div className="flex items-center gap-1"><span className="text-gray-500">Ablaufdatum:</span> {formatDate(selectedBankCard.expiryDate)}<CopyButton value={formatDate(selectedBankCard.expiryDate)} /></div>
                  )}
                </div>
              )}
              </div>

              <div>
              <Select
                label={
                  <span className="inline-flex items-center gap-1">
                    <LabelWithLink to={`/customers/${customerId}?tab=documents`} title="Ausweise des Kunden in neuem Tab öffnen">
                      Ausweis
                    </LabelWithLink>
                    {selectedDocument?.documentPath && (
                      <button
                        type="button"
                        onClick={(e) => { e.preventDefault(); e.stopPropagation(); setPdfModal({ title: 'Ausweis – Dokument', path: selectedDocument.documentPath! }); }}
                        className="text-gray-400 hover:text-blue-600 p-0.5 rounded"
                        title="Hinterlegtes Dokument anzeigen (PDF)"
                        aria-label="Ausweis-Dokument anzeigen"
                      >
                        <FileText className="w-3.5 h-3.5" />
                      </button>
                    )}
                    {selectedDocument && (
                      <CopyButton value={selectedDocument.documentNumber} title="Ausweisnummer kopieren" />
                    )}
                  </span>
                }
                {...register('identityDocumentId')}
                options={documents.map((d) => ({
                  value: d.id,
                  label: `${d.documentNumber} (${d.type})`,
                }))}
              />
              {selectedDocument && (
                <div className="mt-1.5 space-y-0.5 text-xs text-gray-600">
                  {selectedDocument.issueDate && (
                    <div className="flex items-center gap-1"><span className="text-gray-500">Ausstellung:</span> {formatDate(selectedDocument.issueDate)}<CopyButton value={formatDate(selectedDocument.issueDate)} /></div>
                  )}
                  {selectedDocument.expiryDate && (
                    <div className="flex items-center gap-1"><span className="text-gray-500">Ablaufdatum:</span> {formatDate(selectedDocument.expiryDate)}<CopyButton value={formatDate(selectedDocument.expiryDate)} /></div>
                  )}
                  {selectedDocument.issuingAuthority && (
                    <div className="flex items-center gap-1"><span className="text-gray-500">Behörde:</span> {selectedDocument.issuingAuthority}<CopyButton value={selectedDocument.issuingAuthority} /></div>
                  )}
                  {customer?.birthPlace && (
                    <div className="flex items-center gap-1"><span className="text-gray-500">Geburtsort:</span> {customer.birthPlace}<CopyButton value={customer.birthPlace} /></div>
                  )}
                  {customer?.birthDate && (
                    <div className="flex items-center gap-1"><span className="text-gray-500">Geburtsdatum:</span> {formatDate(customer.birthDate)}<CopyButton value={formatDate(customer.birthDate)} /></div>
                  )}
                </div>
              )}
              </div>
            </div>
          </Card>
        )}

        <Card className="mb-6" title="Anbieter & Tarif">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <Select
              label={
                <LabelWithLink to="/settings/providers" title="Anbieter & Tarife verwalten (neuer Tab)">
                  Anbieter
                </LabelWithLink>
              }
              {...register('providerId')}
              options={providers.map((p) => ({ value: p.id, label: p.name }))}
            />
            <Select
              label={
                <LabelWithLink to="/settings/providers" title="Anbieter & Tarife verwalten (neuer Tab)">
                  Tarif
                </LabelWithLink>
              }
              {...register('tariffId')}
              options={availableTariffs.map((t) => ({ value: t.id, label: t.name }))}
              disabled={!selectedProviderId}
            />
            {contractType === 'MOBILE' && (
              <Select
                label="Mobilfunknetz"
                {...register('mobileNetwork')}
                options={[
                  { value: 'TELEKOM', label: 'Telekom' },
                  { value: 'VODAFONE', label: 'Vodafone' },
                  { value: 'TELEFONICA', label: 'Telefónica' },
                ]}
                placeholder="Bitte auswählen"
              />
            )}
            <Input label="Kundennummer beim Anbieter" maxLength={100} {...register('customerNumberAtProvider')} />
            <Input label="Vertragsnummer beim Anbieter" maxLength={100} {...register('contractNumberAtProvider')} />
            <Input label="Auftragsnummer bei Vertriebsplattform" maxLength={100} {...register('orderNumberAtSalesPlatform')} />
            <Input label="Kundennummer bei Vertriebsplattform" maxLength={100} {...register('customerNumberAtSalesPlatform')} />
            <Input label="Vertragsnummer bei Vertriebsplattform" maxLength={100} {...register('contractNumberAtSalesPlatform')} />
            <Input label="Provision (€)" type="number" step="0.01" {...register('commission')} />
            <Input label="Preis erste 12 Monate" {...register('priceFirst12Months')} placeholder="z.B. 29,99 €/Monat" />
            <Input label="Preis ab 13. Monat" {...register('priceFrom13Months')} placeholder="z.B. 39,99 €/Monat" />
            <Input label="Preis nach 24 Monaten" {...register('priceAfter24Months')} placeholder="z.B. 49,99 €/Monat" />
          </div>
        </Card>

        <Card className="mb-6" title="Laufzeit und Kündigung">
          <p className="text-sm text-gray-500 mb-4 bg-blue-50 border border-blue-200 rounded-lg p-3">
            <strong>Hinweis:</strong> Ist die Laufzeit ≤ 4 Wochen, 1 Monat oder 30 Tage, gilt der Vertrag als unbefristet mit der jeweiligen Kündigungsfrist.
          </p>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <Input
              label="Vertragsbeginn"
              type="date"
              {...register('startDate')}
              value={watch('startDate') || ''}
              onClear={() => setValue('startDate', '')}
            />
            <Input label="Vertragsende (berechnet)" type="date" {...register('endDate')} disabled className="bg-gray-50" />
            <Select
              label="Vertragslaufzeit"
              {...register('contractDurationId')}
              options={contractDurations.map((cd) => ({ value: cd.id, label: cd.description }))}
            />
            <Select
              label="Kündigungsfrist"
              {...register('cancellationPeriodId')}
              options={cancellationPeriods.map((cp) => ({ value: cp.id, label: cp.description }))}
            />
            <Input
              label="Kündigungsbestätigungsdatum"
              type="date"
              {...register('cancellationConfirmationDate')}
              value={watch('cancellationConfirmationDate') || ''}
              onClear={() => setValue('cancellationConfirmationDate', '')}
            />
            <Input
              label="Kündigungsbestätigungsoptionendatum"
              type="date"
              {...register('cancellationConfirmationOptionsDate')}
              value={watch('cancellationConfirmationOptionsDate') || ''}
              onClear={() => setValue('cancellationConfirmationOptionsDate', '')}
            />
            <div className="col-span-2">
              <label className="inline-flex items-center gap-2 cursor-pointer">
                <input type="checkbox" {...register('wasSpecialCancellation')} className="rounded border-gray-300" />
                <span>Wurde sondergekündigt?</span>
              </label>
            </div>
          </div>
        </Card>

        <Card className="mb-6" title="Zugangsdaten (verschlüsselt gespeichert)">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              {(() => {
                // Aktiv kopierbaren Wert je nach Modus ermitteln:
                // - Manuell: aktueller Eingabewert von portalUsername
                // - Stressfrei: E-Mail der ausgewählten Stressfrei-Adresse
                const manualUsername = (watch('portalUsername') as string) || '';
                const selectedStressfreiEmail = selectedStressfreiEmailId
                  ? stressfreiEmails.find((e: { id: number; email: string }) => e.id.toString() === selectedStressfreiEmailId)?.email
                  : '';
                const copyValue = usernameType === 'manual'
                  ? manualUsername.trim()
                  : (selectedStressfreiEmail || '');
                return (
                  <label className="flex items-center gap-2 mb-2 text-sm font-medium text-gray-700">
                    <span>Portal Benutzername</span>
                    {copyValue && <CopyButton value={copyValue} title={`Benutzername "${copyValue}" in Zwischenablage kopieren`} />}
                    {customerId && (
                      <a
                        href={`/customers/${customerId}?tab=stressfrei`}
                        target="_blank"
                        rel="noopener noreferrer"
                        title={`${customerEmailLabel} Adresse beim Kunden anlegen (neuer Tab)`}
                        aria-label={`${customerEmailLabel} Adresse beim Kunden anlegen (neuer Tab)`}
                        className="text-gray-400 hover:text-blue-600 p-0.5 rounded"
                      >
                        <ExternalLink className="w-3.5 h-3.5" />
                      </a>
                    )}
                  </label>
                );
              })()}
              <div className="space-y-2">
                <label className="flex items-center gap-2 cursor-pointer">
                  <input
                    type="radio"
                    name="usernameType"
                    checked={usernameType === 'manual'}
                    onChange={() => {
                      setUsernameType('manual');
                      setSelectedStressfreiEmailId('');
                    }}
                    className="text-blue-600"
                  />
                  <span className="text-sm">Manuell eingeben</span>
                </label>
                {usernameType === 'manual' && (
                  <Input
                    {...register('portalUsername')}
                    maxLength={100}
                    placeholder="Benutzername eingeben..."
                  />
                )}
                <label className="flex items-center gap-2 cursor-pointer">
                  <input
                    type="radio"
                    name="usernameType"
                    checked={usernameType === 'stressfrei'}
                    onChange={() => {
                      setUsernameType('stressfrei');
                      setValue('portalUsername', '');
                    }}
                    className="text-blue-600"
                  />
                  <span className="text-sm">{customerEmailLabel} Adresse</span>
                </label>
                {usernameType === 'stressfrei' && (
                  <div className="flex items-start gap-2">
                    <div className="flex-1 min-w-0">
                      <Select
                        value={selectedStressfreiEmailId}
                        onChange={(e) => setSelectedStressfreiEmailId(e.target.value)}
                        options={stressfreiEmails.map((e: { id: number; email: string; notes?: string }) => ({
                          value: e.id,
                          label: e.email + (e.notes ? ` (${e.notes})` : ''),
                        }))}
                        placeholder={stressfreiEmails.length === 0 ? 'Keine Stressfrei-Adressen vorhanden' : 'Adresse auswählen...'}
                      />
                    </div>
                    {customerId && (
                      <div className="flex items-center gap-1 pt-1.5 flex-shrink-0">
                        <a
                          href={`/customers/${customerId}?tab=stressfrei`}
                          target="_blank"
                          rel="noopener noreferrer"
                          title={`${customerEmailLabel} Adressen des Kunden in neuem Tab öffnen`}
                          aria-label={`${customerEmailLabel} Adressen des Kunden in neuem Tab öffnen`}
                          className="text-gray-400 hover:text-blue-600 p-1 rounded"
                        >
                          <ExternalLink className="w-4 h-4" />
                        </a>
                        <a
                          href={`/customers/${customerId}?tab=emails`}
                          target="_blank"
                          rel="noopener noreferrer"
                          title="E-Mail-Postfach des Kunden in neuem Tab öffnen"
                          aria-label="E-Mail-Postfach des Kunden in neuem Tab öffnen"
                          className="text-gray-400 hover:text-blue-600 p-1 rounded"
                        >
                          <Mail className="w-4 h-4" />
                        </a>
                      </div>
                    )}
                  </div>
                )}
                {usernameType === 'stressfrei' && stressfreiEmails.length === 0 && (
                  <p className="text-xs text-amber-600">
                    Keine {customerEmailLabel} Adressen für diesen Kunden vorhanden. Bitte zuerst beim Kunden anlegen.
                  </p>
                )}
                <label className="flex items-center gap-2 cursor-pointer">
                  <input
                    type="radio"
                    name="usernameType"
                    checked={usernameType === 'not_required'}
                    onChange={() => {
                      setUsernameType('not_required');
                      setValue('portalUsername', '');
                      setValue('portalPassword', '');
                      setSelectedStressfreiEmailId('');
                    }}
                    className="text-blue-600"
                  />
                  <span className="text-sm">Nicht möglich zu bekommen / nicht benötigt</span>
                </label>
                {usernameType === 'not_required' && (
                  <p className="text-xs text-gray-500">
                    Anbieter hat kein Portal oder Kunde bekommt keine Zugangsdaten. Die Warnung „Portal-Zugangsdaten fehlen" im Cockpit wird für diesen Vertrag unterdrückt.
                  </p>
                )}
              </div>
            </div>
            {usernameType !== 'not_required' && (
              <div className="mt-8">
                <label className="block text-sm font-medium text-gray-700 mb-1">
                  {isEdit ? 'Neues Passwort (leer lassen = unverändert)' : 'Portal Passwort'}
                </label>
                <div className="relative">
                  <input
                    type={showPortalPassword ? 'text' : 'password'}
                    {...register('portalPassword')}
                    className="block w-full px-3 py-2 pr-10 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                  />
                  <button
                    type="button"
                    onClick={() => setShowPortalPassword(!showPortalPassword)}
                    className="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 hover:text-gray-600"
                  >
                    {showPortalPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                  </button>
                </div>
              </div>
            )}
          </div>
        </Card>

        {/* Energy-specific fields */}
        {['ELECTRICITY', 'GAS'].includes(contractType) && (
          <Card className="mb-6" title={contractType === 'ELECTRICITY' ? 'Strom-Details' : 'Gas-Details'}>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              {(() => {
                const selectedAddressId = watch('addressId');
                const meterRegister = register('meterId');
                // Zähler werden auf die Lieferadresse des Vertrags gefiltert. Zähler ohne
                // Lieferadresse (Bestand) bleiben für den aktuell gewählten Eintrag sichtbar,
                // damit die Auswahl nicht verschwindet, bis sie nachgepflegt sind.
                const filteredMeters = meters.filter((m) => {
                  if (m.type !== contractType) return false;
                  const isCurrentlySelected = m.id.toString() === watch('meterId');
                  if (isCurrentlySelected) return true;
                  if (!selectedAddressId) return false;
                  return m.addressId != null && m.addressId.toString() === selectedAddressId;
                });
                return (
                  <Select
                    label={
                      <LabelWithLink to={`/customers/${customerId}?tab=meters`} title="Zähler des Kunden in neuem Tab öffnen">
                        Zähler
                      </LabelWithLink>
                    }
                    {...meterRegister}
                    onChange={(e) => {
                      meterRegister.onChange(e);
                      const m = meters.find((x) => x.id.toString() === e.target.value);
                      if (m && !m.isActive) {
                        toast(
                          'Deaktivierter Zähler ausgewählt. Ist das gewollt? Handelt es sich um einen Altvertrag?',
                          { icon: '⚠️', duration: 6000 },
                        );
                      }
                    }}
                    options={filteredMeters.map((m) => ({
                      value: m.id,
                      label: `${m.meterNumber}${m.location ? ` (${m.location})` : ''}${!m.isActive ? ' (deaktiviert)' : ''}`,
                    }))}
                    placeholder={
                      !selectedAddressId
                        ? 'Erst Lieferadresse wählen...'
                        : filteredMeters.length === 0
                          ? 'Kein Zähler für diese Adresse vorhanden'
                          : 'Zähler wählen...'
                    }
                  />
                );
              })()}
              {(() => {
                // MaLo-ID gehört zur Lieferadresse (nicht zum Vertrag) → Lesefeld,
                // Wert je nach Sparte aus der gewählten Lieferadresse.
                const selAddr = addresses.find((a) => String(a.id) === watch('addressId'));
                const isElectricity = contractType === 'ELECTRICITY';
                const maloValue = isElectricity ? selAddr?.maloIdElectricity : selAddr?.maloIdGas;
                const sparte = isElectricity ? 'Strom' : 'Gas';
                return (
                  <div>
                    <label className="block text-sm font-medium text-gray-700 mb-1">
                      MaLo-ID (Marktlokations-ID {sparte})
                    </label>
                    <div className="flex items-center gap-2">
                      <input
                        type="text"
                        value={maloValue || ''}
                        readOnly
                        placeholder={!watch('addressId')
                          ? 'Erst Lieferadresse wählen…'
                          : `Keine MaLo-ID ${sparte} an der Lieferadresse hinterlegt`}
                        className="block w-full px-3 py-2 border border-gray-300 rounded-lg bg-gray-100 text-gray-700 cursor-not-allowed"
                      />
                      {maloValue && <CopyButton value={maloValue} />}
                    </div>
                    <p className="text-xs text-gray-500 mt-1">
                      Wird aus der Lieferadresse übernommen –{' '}
                      {customerId ? (
                        <a
                          href={`/customers/${customerId}?tab=addresses`}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="text-blue-600 hover:underline"
                        >
                          dort pflegen
                        </a>
                      ) : 'in der Kundenakte an der Adresse pflegen'}.
                    </p>
                  </div>
                );
              })()}
              <div>
                <Input
                  label={`Jahresverbrauch (${contractType === 'ELECTRICITY' ? 'kWh' : 'm³'})`}
                  type="number"
                  {...register('annualConsumption')}
                />
                {previousConsumptionUsable && (
                  <p className="mt-1 text-xs text-blue-600 flex items-center gap-2">
                    <span>
                      Vorvertrag: {(contractType === 'GAS'
                        ? previousConsumption!.consumptionM3 ?? previousConsumption!.consumptionKwh
                        : previousConsumption!.consumptionKwh
                      ).toLocaleString('de-DE', { maximumFractionDigits: 0 })} {contractType === 'GAS' ? 'm³' : 'kWh'}
                      {previousConsumption!.type === 'projected' && ' (hochgerechnet)'}
                    </span>
                    <button
                      type="button"
                      className="text-blue-700 hover:underline"
                      onClick={() => {
                        const v = contractType === 'GAS'
                          ? previousConsumption!.consumptionM3 ?? previousConsumption!.consumptionKwh
                          : previousConsumption!.consumptionKwh;
                        setValue('annualConsumption', Math.round(v) as any, { shouldDirty: true });
                      }}
                    >
                      Übernehmen
                    </button>
                  </p>
                )}
              </div>
              {contractType === 'GAS' && (
                <div>
                  <Input
                    label="Jahresverbrauch (kWh)"
                    type="number"
                    {...register('annualConsumptionKwh')}
                  />
                  {previousConsumptionUsable && (
                    <p className="mt-1 text-xs text-blue-600 flex items-center gap-2">
                      <span>
                        Vorvertrag: {previousConsumption!.consumptionKwh.toLocaleString('de-DE', { maximumFractionDigits: 0 })} kWh
                        {previousConsumption!.type === 'projected' && ' (hochgerechnet)'}
                      </span>
                      <button
                        type="button"
                        className="text-blue-700 hover:underline"
                        onClick={() => setValue('annualConsumptionKwh', Math.round(previousConsumption!.consumptionKwh) as any, { shouldDirty: true })}
                      >
                        Übernehmen
                      </button>
                    </p>
                  )}
                </div>
              )}
              <Input label="Grundpreis (€/Monat)" type="number" step="any" {...register('basePrice')} />
              <EuroCentInput
                label={selectedMeter?.tariffModel === 'DUAL' ? 'HT-Arbeitspreis (€/kWh)' : 'Arbeitspreis (€/kWh)'}
                value={watch('unitPrice')}
                onChange={(v) => setValue('unitPrice', v, { shouldDirty: true })}
              />
              {selectedMeter?.tariffModel === 'DUAL' && (
                <EuroCentInput
                  label="NT-Arbeitspreis (€/kWh)"
                  value={watch('unitPriceNt')}
                  onChange={(v) => setValue('unitPriceNt', v, { shouldDirty: true })}
                />
              )}
              <Input label="Sofort-Bonus (€)" type="number" step="0.01" {...register('instantBonus')} />
              <Input label="Neukunden-Bonus (€)" type="number" step="0.01" {...register('newCustomerBonus')} />
            </div>

            <label className="flex items-center gap-2 mt-3">
              <input type="checkbox" {...register('noBonusDesired')} className="rounded" />
              <span className="text-sm text-gray-700">Keine Bonis erwünscht</span>
            </label>

            {/* Hinweis für Zählerstände und Rechnungen */}
            {isEdit && (
              <div className="mt-4 p-3 bg-blue-50 border border-blue-200 rounded-lg text-sm text-blue-700">
                <strong>Hinweis:</strong> Zählerstände und Rechnungen werden in der{' '}
                <span className="font-medium">Vertragsdetailansicht</span> verwaltet, nicht hier im Bearbeitungsformular.
              </div>
            )}
          </Card>
        )}

        {/* Internet-specific fields */}
        {['DSL', 'CABLE', 'FIBER'].includes(contractType) && (
          <>
            <Card className="mb-6" title={
              contractType === 'DSL' ? 'DSL-Details' :
              contractType === 'CABLE' ? 'Kabelinternet-Details' :
              'Glasfaser-Details'
            }>
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <Input label="Download (Mbit/s)" type="number" {...register('downloadSpeed')} />
                <Input label="Upload (Mbit/s)" type="number" {...register('uploadSpeed')} />
                <Input label="Router Modell" {...register('routerModel')} />
                <Input label="Router Seriennummer" {...register('routerSerialNumber')} />
                <Input
                  label="Installationsdatum"
                  type="date"
                  {...register('installationDate')}
                  value={watch('installationDate') || ''}
                  onClear={() => setValue('installationDate', '')}
                />
              </div>

              {/* Objekt & Lage */}
              <h4 className="text-sm font-medium text-gray-700 mt-4 mb-2">Objekt & Lage</h4>
              <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                <Select
                  label="Objekttyp"
                  {...register('propertyType')}
                  options={[
                    { value: '', label: 'Bitte wählen...' },
                    { value: 'Mehrparteienhaus', label: 'Mehrparteienhaus' },
                    { value: 'Freistehendes Haus', label: 'Freistehendes Haus' },
                    { value: 'Doppelhaushälfte', label: 'Doppelhaushälfte' },
                    { value: 'Reihenhaus', label: 'Reihenhaus' },
                    { value: 'Wohnung', label: 'Wohnung' },
                    { value: 'Bürogebäude', label: 'Bürogebäude' },
                    { value: 'Gewerbeeinheit', label: 'Gewerbeeinheit' },
                  ]}
                />
                <Select
                  label="Lage"
                  {...register('propertyLocation')}
                  options={[
                    { value: '', label: 'Bitte wählen...' },
                    { value: 'Vorderhaus', label: 'Vorderhaus' },
                    { value: 'Hinterhaus', label: 'Hinterhaus' },
                    { value: 'Links', label: 'Links' },
                    { value: 'Rechts', label: 'Rechts' },
                    { value: 'Mitte', label: 'Mitte' },
                    { value: 'Keller', label: 'Keller' },
                    { value: 'Souterrain', label: 'Souterrain' },
                    { value: 'Erdgeschoss', label: 'Erdgeschoss' },
                    ...[...Array(25)].map((_, i) => ({ value: `${i + 1}. OG`, label: `${i + 1}. Obergeschoss` })),
                    { value: 'Dachgeschoss', label: 'Dachgeschoss' },
                  ]}
                />
                <Select
                  label="Lage des Anschlusses"
                  {...register('connectionLocation')}
                  options={[
                    { value: '', label: 'Bitte wählen...' },
                    { value: 'Flur', label: 'Flur' },
                    { value: 'Wohnzimmer', label: 'Wohnzimmer' },
                    { value: 'Schlafzimmer', label: 'Schlafzimmer' },
                    { value: 'Kinderzimmer', label: 'Kinderzimmer' },
                    { value: 'Küche', label: 'Küche' },
                    { value: 'Büro', label: 'Büro' },
                    { value: 'HWR', label: 'Hauswirtschaftsraum (HWR)' },
                    { value: 'Hausanschlussraum', label: 'Hausanschlussraum' },
                    { value: 'Abstellraum', label: 'Abstellraum' },
                    { value: 'Garage', label: 'Garage' },
                    { value: 'Serverraum', label: 'Serverraum' },
                    { value: 'Empfang', label: 'Empfang / Rezeption' },
                    { value: 'Keller', label: 'Keller' },
                  ]}
                />
              </div>

              <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
                {/* HomeID nur bei Glasfaser */}
                {contractType === 'FIBER' && (
                  <Input label="Home-ID" {...register('homeId')} />
                )}
                {/* Aktivierungscode bei Vodafone + DSL oder Kabel */}
                {selectedProvider?.name?.toLowerCase().includes('vodafone') && ['DSL', 'CABLE'].includes(contractType) && (
                  <Input label="Aktivierungscode" {...register('activationCode')} />
                )}
              </div>
            </Card>

            <Card className="mb-6" title="Internet-Zugangsdaten (verschlüsselt)">
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <Input label="Benutzername" {...register('internetUsername')} />
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1">
                    {isEdit ? 'Neues Passwort (leer = beibehalten)' : 'Passwort'}
                  </label>
                  <div className="relative">
                    <input
                      type={showInternetPassword ? 'text' : 'password'}
                      {...register('internetPassword')}
                      className="block w-full px-3 py-2 pr-10 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                    />
                    <button
                      type="button"
                      onClick={() => setShowInternetPassword(!showInternetPassword)}
                      className="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 hover:text-gray-600"
                    >
                      {showInternetPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                    </button>
                  </div>
                </div>
              </div>
            </Card>

            <Card className="mb-6" title="Rufnummern & SIP-Zugangsdaten">
              <p className="text-sm text-gray-500 mb-4">
                Hier können Sie Festnetz-Rufnummern mit SIP-Zugangsdaten erfassen.
              </p>

              {phoneNumbers.length > 0 && (
                <div className="space-y-4 mb-4">
                  {phoneNumbers.map((pn, index) => (
                    <div key={index} className="p-4 border rounded-lg bg-gray-50">
                      <div className="flex justify-between items-center mb-3">
                        <div className="flex items-center gap-3">
                          <span className="font-medium">Rufnummer {index + 1}</span>
                          <label className="flex items-center gap-1 text-sm">
                            <input
                              type="checkbox"
                              checked={pn.isMain}
                              onChange={(e) => {
                                const updated = [...phoneNumbers];
                                if (e.target.checked) {
                                  updated.forEach((p, i) => p.isMain = i === index);
                                } else {
                                  updated[index].isMain = false;
                                }
                                setPhoneNumbers(updated);
                              }}
                              className="rounded border-gray-300"
                            />
                            Hauptnummer
                          </label>
                        </div>
                        <Button
                          type="button"
                          variant="ghost"
                          size="sm"
                          onClick={() => {
                            setPhoneNumbers(phoneNumbers.filter((_, i) => i !== index));
                          }}
                        >
                          <Trash2 className="w-4 h-4 text-red-500" />
                        </Button>
                      </div>
                      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-3">
                        <Input
                          label="Vorwahl"
                          value={pn.areaCode}
                          onChange={(e) => {
                            const updated = [...phoneNumbers];
                            updated[index].areaCode = e.target.value;
                            setPhoneNumbers(updated);
                          }}
                          placeholder="z.B. 030"
                        />
                        <Input
                          label="Rufnummer"
                          value={pn.subscriber}
                          onChange={(e) => {
                            const updated = [...phoneNumbers];
                            updated[index].subscriber = e.target.value;
                            setPhoneNumbers(updated);
                          }}
                          placeholder="z.B. 123456"
                        />
                        <Input
                          label="SIP-Benutzername"
                          value={pn.sipUsername}
                          onChange={(e) => {
                            const updated = [...phoneNumbers];
                            updated[index].sipUsername = e.target.value;
                            setPhoneNumbers(updated);
                          }}
                        />
                        <div>
                          <label className="block text-sm font-medium text-gray-700 mb-1">
                            {pn.hasExistingSipPassword ? "SIP-Passwort (bereits hinterlegt)" : "SIP-Passwort"}
                          </label>
                          <div className="relative">
                            <input
                              type={showSipPasswords[index] ? 'text' : 'password'}
                              value={pn.sipPassword}
                              onChange={(e) => {
                                const updated = [...phoneNumbers];
                                updated[index].sipPassword = e.target.value;
                                setPhoneNumbers(updated);
                              }}
                              placeholder={pn.hasExistingSipPassword ? "Leer = beibehalten" : ""}
                              className="block w-full px-3 py-2 pr-10 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                            />
                            <button
                              type="button"
                              onClick={() => setShowSipPasswords(prev => ({ ...prev, [index]: !prev[index] }))}
                              className="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 hover:text-gray-600"
                            >
                              {showSipPasswords[index] ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                            </button>
                          </div>
                        </div>
                        <Input
                          label="SIP-Server"
                          value={pn.sipServer}
                          onChange={(e) => {
                            const updated = [...phoneNumbers];
                            updated[index].sipServer = e.target.value;
                            setPhoneNumbers(updated);
                          }}
                          placeholder="z.B. sip.provider.de"
                        />
                      </div>
                    </div>
                  ))}
                </div>
              )}

              <Button
                type="button"
                variant="secondary"
                onClick={() => {
                  setPhoneNumbers([...phoneNumbers, {
                    areaCode: '',
                    subscriber: '',
                    sipUsername: '',
                    sipPassword: '',
                    sipServer: '',
                    isMain: phoneNumbers.length === 0,
                  }]);
                }}
              >
                <Plus className="w-4 h-4 mr-2" />
                Rufnummer hinzufügen
              </Button>
            </Card>
          </>
        )}

        {/* Mobile-specific fields */}
        {contractType === 'MOBILE' && (
          <>
            <Card className="mb-6" title="Mobilfunk-Details">
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <Input label="Datenvolumen (GB)" type="number" {...register('dataVolume')} />
                <Input label="Inklusiv-Minuten" type="number" {...register('includedMinutes')} />
                <Input label="Inklusiv-SMS" type="number" {...register('includedSMS')} />
                <Input label="Gerät (Modell)" {...register('deviceModel')} />
                <Input label="Gerät (IMEI)" {...register('deviceImei')} />
              </div>

              {/* Multisim erforderlich */}
              <div className="mt-4 pt-4 border-t">
                <label className="flex items-start gap-3 cursor-pointer">
                  <input
                    type="checkbox"
                    {...register('requiresMultisim')}
                    className="mt-1 rounded border-gray-300"
                  />
                  <div>
                    <span className="font-medium">Multisim erforderlich</span>
                    <p className="text-sm text-amber-600 mt-1">
                      Hinweis: Multisim ist bei Klarmobil, Congstar und Otelo nicht buchbar. Muss Freenet oder vergleichbar sein.
                    </p>
                  </div>
                </label>
              </div>
            </Card>

            <Card className="mb-6" title="SIM-Karten">
              <p className="text-sm text-gray-500 mb-4">
                Hier können Sie alle SIM-Karten zum Vertrag erfassen (Hauptkarte und Multisim-Karten).
              </p>

              {simCards.length > 0 && (
                <div className="space-y-4 mb-4">
                  {simCards.map((card, index) => (
                    <div key={index} className="p-4 border rounded-lg bg-gray-50">
                      <div className="flex justify-between items-center mb-3">
                        <div className="flex items-center gap-3">
                          <span className="font-medium">SIM-Karte {index + 1}</span>
                          <label className="flex items-center gap-1 text-sm">
                            <input
                              type="checkbox"
                              checked={card.isMain}
                              onChange={(e) => {
                                const updated = [...simCards];
                                // Nur eine Hauptkarte erlauben
                                if (e.target.checked) {
                                  updated.forEach((c, i) => c.isMain = i === index);
                                } else {
                                  updated[index].isMain = false;
                                }
                                setSimCards(updated);
                              }}
                              className="rounded border-gray-300"
                            />
                            Hauptkarte
                          </label>
                          <label className="flex items-center gap-1 text-sm">
                            <input
                              type="checkbox"
                              checked={card.isEsim}
                              onChange={(e) => {
                                const updated = [...simCards];
                                updated[index].isEsim = e.target.checked;
                                setSimCards(updated);
                              }}
                              className="rounded border-gray-300"
                            />
                            eSIM
                          </label>
                          <label className="flex items-center gap-1 text-sm">
                            <input
                              type="checkbox"
                              checked={card.isMultisim}
                              onChange={(e) => {
                                const updated = [...simCards];
                                updated[index].isMultisim = e.target.checked;
                                setSimCards(updated);
                              }}
                              className="rounded border-gray-300"
                            />
                            Multisim
                          </label>
                        </div>
                        <Button
                          type="button"
                          variant="ghost"
                          size="sm"
                          onClick={() => {
                            setSimCards(simCards.filter((_, i) => i !== index));
                          }}
                        >
                          <Trash2 className="w-4 h-4 text-red-500" />
                        </Button>
                      </div>
                      <div className="mb-3">
                        <Input
                          label="Kartennutzer"
                          value={card.cardUser}
                          onChange={(e) => {
                            const updated = [...simCards];
                            updated[index].cardUser = e.target.value;
                            setSimCards(updated);
                          }}
                          placeholder="z.B. Mitarbeiter-/Kind-Name (optional, kann vom Vertragsinhaber abweichen)"
                        />
                      </div>
                      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3">
                        <Input
                          label="Rufnummer"
                          value={card.phoneNumber}
                          onChange={(e) => {
                            const updated = [...simCards];
                            updated[index].phoneNumber = e.target.value;
                            setSimCards(updated);
                          }}
                          placeholder="z.B. 0171 1234567"
                        />
                        <Input
                          label="SIM-Kartennummer"
                          value={card.simCardNumber}
                          onChange={(e) => {
                            const updated = [...simCards];
                            updated[index].simCardNumber = e.target.value;
                            setSimCards(updated);
                          }}
                          placeholder="ICCID"
                        />
                        <div>
                          <label className="block text-sm font-medium text-gray-700 mb-1">
                            {card.hasExistingPin ? "PIN (bereits hinterlegt)" : "PIN"}
                          </label>
                          <div className="relative">
                            <input
                              type={showSimPins[index] ? 'text' : 'password'}
                              value={card.pin}
                              onChange={(e) => {
                                const updated = [...simCards];
                                updated[index].pin = e.target.value;
                                setSimCards(updated);
                              }}
                              placeholder={card.hasExistingPin ? "Leer = beibehalten" : "4-stellig"}
                              className="block w-full px-3 py-2 pr-10 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                            />
                            <button
                              type="button"
                              onClick={() => setShowSimPins(prev => ({ ...prev, [index]: !prev[index] }))}
                              className="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 hover:text-gray-600"
                            >
                              {showSimPins[index] ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                            </button>
                          </div>
                        </div>
                        <div>
                          <label className="block text-sm font-medium text-gray-700 mb-1">
                            {card.hasExistingPuk ? "PUK (bereits hinterlegt)" : "PUK"}
                          </label>
                          <div className="relative">
                            <input
                              type={showSimPuks[index] ? 'text' : 'password'}
                              value={card.puk}
                              onChange={(e) => {
                                const updated = [...simCards];
                                updated[index].puk = e.target.value;
                                setSimCards(updated);
                              }}
                              placeholder={card.hasExistingPuk ? "Leer = beibehalten" : "8-stellig"}
                              className="block w-full px-3 py-2 pr-10 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                            />
                            <button
                              type="button"
                              onClick={() => setShowSimPuks(prev => ({ ...prev, [index]: !prev[index] }))}
                              className="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 hover:text-gray-600"
                            >
                              {showSimPuks[index] ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                            </button>
                          </div>
                        </div>
                      </div>
                    </div>
                  ))}
                </div>
              )}

              <Button
                type="button"
                variant="secondary"
                onClick={() => {
                  setSimCards([...simCards, {
                    phoneNumber: '',
                    simCardNumber: '',
                    pin: '',
                    puk: '',
                    isMultisim: false,
                    isMain: simCards.length === 0, // Erste Karte ist Hauptkarte
                    isEsim: false,
                    cardUser: '',
                  }]);
                }}
              >
                <Plus className="w-4 h-4 mr-2" />
                SIM-Karte hinzufügen
              </Button>
            </Card>
          </>
        )}

        {/* TV-specific fields */}
        {contractType === 'TV' && (
          <Card className="mb-6" title="TV-Details">
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              <Input label="Receiver Modell" {...register('receiverModel')} />
              <Input label="Smartcard-Nummer" {...register('smartcardNumber')} />
              <Input label="Paket" {...register('tvPackage')} placeholder="z.B. Basis, Premium, Sport" />
            </div>
          </Card>
        )}

        {/* Car Insurance-specific fields */}
        {contractType === 'CAR_INSURANCE' && (
          <Card className="mb-6" title="KFZ-Versicherung Details">
            <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
              <Input label="Kennzeichen" {...register('licensePlate')} />
              <Input label="HSN" {...register('hsn')} />
              <Input label="TSN" {...register('tsn')} />
              <Input label="FIN (VIN)" {...register('vin')} />
              <Input label="Fahrzeugtyp" {...register('vehicleType')} />
              <Input
                label="Erstzulassung"
                type="date"
                {...register('firstRegistration')}
                value={watch('firstRegistration') || ''}
                onClear={() => setValue('firstRegistration', '')}
              />
              <Input label="SF-Klasse" {...register('noClaimsClass')} />
              <Select
                label="Versicherungsart"
                {...register('insuranceType')}
                options={[
                  { value: 'LIABILITY', label: 'Haftpflicht' },
                  { value: 'PARTIAL', label: 'Teilkasko' },
                  { value: 'FULL', label: 'Vollkasko' },
                ]}
              />
              <Input label="SB Teilkasko (€)" type="number" {...register('deductiblePartial')} />
              <Input label="SB Vollkasko (€)" type="number" {...register('deductibleFull')} />
              <Input label="Versicherungsscheinnummer" {...register('policyNumber')} />
              <Input label="Vorversicherer" {...register('previousInsurer')} />
            </div>
          </Card>
        )}

        <Card className="mb-6" title="Notizen">
          <textarea
            {...register('notes')}
            rows={4}
            className="block w-full px-3 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
            placeholder="Interne Notizen..."
          />
        </Card>

        {/* Sticky-Footer: Speichern/Abbrechen bleiben unten sichtbar,
            damit man beim langen Formular nicht ganz nach unten scrollen
            muss. -mx-8 px-8 -mb-8 zieht den Balken bündig an die
            Layout-Padding-Kante. */}
        <div className="sticky bottom-0 z-20 -mx-8 px-8 pt-3 pb-3 -mb-8 mt-6 bg-gray-100 border-t border-gray-200 flex justify-end gap-4">
          <Button type="button" variant="secondary" onClick={() => navigate(back.to, { state: back.state })}>
            Abbrechen
          </Button>
          <Button type="submit" disabled={isLoading}>
            {isLoading ? 'Speichern...' : 'Speichern'}
          </Button>
        </div>
      </form>

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

      {/* Kunden-Schnellansicht */}
      {customer && (
        <CustomerInfoModal
          customerId={customer.id}
          open={showCustomerInfo}
          onClose={() => setShowCustomerInfo(false)}
          deliveryAddress={addresses.find((a) => String(a.id) === watch('addressId')) || null}
          billingAddress={addresses.find((a) => String(a.id) === watch('billingAddressId')) || null}
          contractStressfreiEmailId={selectedStressfreiEmailId ? parseInt(selectedStressfreiEmailId) : null}
        />
      )}

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

/**
 * Doppel-Input für Arbeitspreise: links €/kWh, rechts ct/kWh.
 * Beide bidirektional verkoppelt – Tippen im Cent-Feld setzt das
 * darunterliegende Euro-Feld (÷ 100), und umgekehrt. Persistiert
 * wird ausschließlich der Euro-Wert (Backend-Format unverändert).
 * Cent-Anzeige wird live aus dem Euro-Wert abgeleitet.
 */
function EuroCentInput({
  label,
  value,
  onChange,
}: {
  label: string;
  value: string | number | undefined | null;
  onChange: (v: string) => void;
}) {
  // Euro-Wert als String wie die anderen Inputs (react-hook-form merged
  // numeric / string-Werte). Wir trimmen trailing zeros bei der
  // Cent-Anzeige, damit "0.25 €" sauber als "25 ct" angezeigt wird –
  // ohne "25.000000".
  const euroStr = value == null ? '' : String(value);
  const centDisplay = (() => {
    if (euroStr === '') return '';
    const n = parseFloat(euroStr);
    if (!Number.isFinite(n)) return '';
    // × 100 mit Float-Rauschen-Schutz (0.25 * 100 = 25.000000000000004)
    const c = Math.round(n * 100 * 1_000_000) / 1_000_000;
    return String(c);
  })();

  const handleCentChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const raw = e.target.value;
    if (raw === '') {
      onChange('');
      return;
    }
    const num = parseFloat(raw);
    if (!Number.isFinite(num)) {
      onChange('');
      return;
    }
    // cent / 100, Float-Rauschen-Schutz analog.
    const euro = Math.round((num / 100) * 1_000_000) / 1_000_000;
    onChange(String(euro));
  };

  const inputCls =
    'block w-full px-3 py-2 pr-8 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500';

  return (
    <div className="w-full">
      <label className="block text-sm font-medium text-gray-700 mb-1">{label}</label>
      <div className="grid grid-cols-2 gap-2">
        <div className="relative">
          <input
            type="number"
            step="any"
            value={euroStr}
            onChange={(e) => onChange(e.target.value)}
            className={inputCls}
          />
          <span className="absolute right-3 top-2 text-gray-400 text-sm pointer-events-none">€</span>
        </div>
        <div className="relative">
          <input
            type="number"
            step="any"
            value={centDisplay}
            onChange={handleCentChange}
            className={inputCls}
          />
          <span className="absolute right-3 top-2 text-gray-400 text-sm pointer-events-none">ct</span>
        </div>
      </div>
    </div>
  );
}
