import { useState, useEffect } from 'react';
import { useParams, Link, useNavigate, useSearchParams, useLocation } from 'react-router-dom';
import { pushHistory, popHistory } from '../../utils/navigation';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import toast from 'react-hot-toast';
import { customerApi, addressApi, bankCardApi, documentApi, meterApi, uploadApi, contractApi, stressfreiEmailApi, emailProviderApi, gdprApi, StressfreiEmail, ContractTreeNode } from '../../services/api';
import { EmailClientTab } from '../../components/email';
import ReferralsTab from '../../components/customers/ReferralsTab';
import { useAuth } from '../../context/AuthContext';
import Card from '../../components/ui/Card';
import Button from '../../components/ui/Button';
import Badge from '../../components/ui/Badge';
import Tabs from '../../components/ui/Tabs';
import Modal from '../../components/ui/Modal';
import Input from '../../components/ui/Input';
import Select from '../../components/ui/Select';
import FileUpload from '../../components/ui/FileUpload';
import { Edit, Plus, Trash2, MapPin, CreditCard, FileText, Gauge, Eye, EyeOff, Download, Globe, UserPlus, X, Search, Mail, Copy, Check, ChevronDown, ChevronRight, Info, Shield, ShieldCheck, ShieldX, ShieldAlert, Lock, ArrowLeft, Cake, RefreshCw, ExternalLink, Images } from 'lucide-react';
import JpgToPdfModal from '../../components/ui/JpgToPdfModal';
import CopyButton, { CopyableBlock } from '../../components/ui/CopyButton';
import BirthdayManagementModal from '../../components/BirthdayManagementModal';
import { formatDate } from '../../utils/dateFormat';
import { getContractTypeInfo } from '../../utils/contractInfo';
import { useProviderSettings } from '../../hooks/useProviderSettings';
import type { Address, BankCard, IdentityDocument, Meter, Customer, CustomerRepresentative, CustomerSummary, CustomerConsent, ConsentType, ConsentStatus, RepresentativeAuthorization } from '../../types';
import { fileUrl, viewUrl } from '../../utils/fileUrl';

export default function CustomerDetail({ portalCustomerId }: { portalCustomerId?: number } = {}) {
  const { id } = useParams();
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const { hasPermission, isCustomerPortal } = useAuth();
  const location = useLocation();
  const back = popHistory(location.state, isCustomerPortal ? '/' : '/customers');
  const [searchParams, setSearchParams] = useSearchParams();
  const customerId = portalCustomerId || parseInt(id!);
  const defaultTab = searchParams.get('tab') || 'addresses';
  const [activeTab, setActiveTab] = useState(defaultTab);
  const { customerEmailLabel } = useProviderSettings();

  // Tab-Wechsel in URL synchronisieren (für Browser-History)
  const handleTabChange = (tabId: string) => {
    setActiveTab(tabId);
    setSearchParams({ tab: tabId }, { replace: true });
  };

  const [showAddressModal, setShowAddressModal] = useState(false);
  const [showBankCardModal, setShowBankCardModal] = useState(false);
  const [showDocumentModal, setShowDocumentModal] = useState(false);
  const [showMeterModal, setShowMeterModal] = useState(false);
  const [showStressfreiEmailModal, setShowStressfreiEmailModal] = useState(false);
  const [showBirthdayModal, setShowBirthdayModal] = useState(false);
  const [showInactive, setShowInactive] = useState(false);
  const [editingBankCard, setEditingBankCard] = useState<BankCard | null>(null);
  const [editingDocument, setEditingDocument] = useState<IdentityDocument | null>(null);
  const [editingAddress, setEditingAddress] = useState<Address | null>(null);
  const [editingMeter, setEditingMeter] = useState<Meter | null>(null);
  const [editingStressfreiEmail, setEditingStressfreiEmail] = useState<StressfreiEmail | null>(null);

  const { data: customer, isLoading } = useQuery({
    queryKey: ['customer', customerId],
    queryFn: () => customerApi.getById(customerId),
  });

  // Consent-Status prüfen
  const { data: consentStatusData } = useQuery({
    queryKey: ['consent-status', customerId],
    queryFn: () => gdprApi.checkConsentStatus(customerId),
    enabled: !!customer?.data,
  });

  const hasConsentApproval = consentStatusData?.data?.hasConsent ?? false;

  const deleteMutation = useMutation({
    mutationFn: () => customerApi.delete(customerId),
    onSuccess: () => {
      navigate('/customers');
    },
  });

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

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

  const c = customer.data;

  // Gesperrter Inhalt für Tabs ohne Einwilligung
  const blockedContent = (
    <ConsentBlockedContent onGoToConsentsTab={() => handleTabChange('consents')} />
  );

  const tabs = [
    {
      id: 'addresses',
      label: 'Adressen',
      content: (
        <AddressesTab
          customerId={customerId}
          addresses={c.addresses || []}
          canEdit={hasPermission('customers:update')}
          onAdd={() => setShowAddressModal(true)}
          onEdit={(addr) => setEditingAddress(addr)}
        />
      ),
    },
    {
      id: 'bankcards',
      label: 'Bankkarten',
      content: hasConsentApproval ? (
        <BankCardsTab
          customerId={customerId}
          bankCards={c.bankCards || []}
          canEdit={hasPermission('customers:update')}
          showInactive={showInactive}
          onToggleInactive={() => setShowInactive(!showInactive)}
          onAdd={() => setShowBankCardModal(true)}
          onEdit={(card) => setEditingBankCard(card)}
        />
      ) : blockedContent,
    },
    {
      id: 'documents',
      label: 'Ausweise',
      content: hasConsentApproval ? (
        <DocumentsTab
          customerId={customerId}
          documents={c.identityDocuments || []}
          canEdit={hasPermission('customers:update')}
          showInactive={showInactive}
          onToggleInactive={() => setShowInactive(!showInactive)}
          onAdd={() => setShowDocumentModal(true)}
          onEdit={(doc) => setEditingDocument(doc)}
        />
      ) : blockedContent,
    },
    {
      id: 'meters',
      label: 'Zähler',
      content: hasConsentApproval ? (
        <MetersTab
          customerId={customerId}
          meters={c.meters || []}
          addresses={c.addresses || []}
          canEdit={hasPermission('customers:update')}
          showInactive={showInactive}
          onToggleInactive={() => setShowInactive(!showInactive)}
          onAdd={() => setShowMeterModal(true)}
          onEdit={(meter) => setEditingMeter(meter)}
        />
      ) : blockedContent,
    },
    ...(!isCustomerPortal ? [{
      id: 'stressfrei',
      label: customerEmailLabel,
      content: (
        <StressfreiEmailsTab
          customerId={customerId}
          emails={c.stressfreiEmails || []}
          canEdit={hasPermission('customers:update')}
          showInactive={showInactive}
          onToggleInactive={() => setShowInactive(!showInactive)}
          onAdd={() => setShowStressfreiEmailModal(true)}
          onEdit={(email) => setEditingStressfreiEmail(email)}
        />
      ),
    }] : []),
    {
      id: 'emails',
      label: 'E-Mail-Postfach',
      content: hasConsentApproval ? (
        <EmailClientTab customerId={customerId} />
      ) : blockedContent,
    },
    {
      id: 'contracts',
      label: 'Verträge',
      content: hasConsentApproval ? (
        <ContractsTab
          customerId={customerId}
        />
      ) : blockedContent,
    },
    ...(hasPermission('customers:update') ? [{
      id: 'portal',
      label: 'Portal',
      content: (
        <PortalTab
          customerId={customerId}
          canEdit={hasPermission('customers:update')}
        />
      ),
    }] : []),
    ...(hasPermission('customers:read') && !isCustomerPortal ? [{
      id: 'referrals',
      label: 'Geworben / angeworben',
      // Bewusst ohne Consent-Gate (hasConsentApproval): funktioniert auch
      // ohne Datenschutz-Einwilligung des Kunden. Nur Staff, nie Portal.
      content: (
        <ReferralsTab
          customerId={customerId}
          customerName={c.type === 'BUSINESS' && c.companyName ? c.companyName : `${c.firstName} ${c.lastName}`}
          canEdit={hasPermission('customers:update')}
        />
      ),
    }] : []),
    ...(hasPermission('customers:read') && !isCustomerPortal ? [{
      id: 'consents',
      label: 'Einwilligungen / Datenschutz',
      content: (
        <ConsentTab
          customerId={customerId}
          canEdit={false}
          customerEmail={c.email || undefined}
          customer={c}
          onUpdate={() => {
            queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
            queryClient.invalidateQueries({ queryKey: ['consent-status', customerId] });
          }}
        />
      ),
    }] : []),
  ];

  return (
    <div>
      <div className="flex items-center justify-between mb-6">
        <div className="flex items-center gap-3">
          <Button variant="ghost" size="sm" onClick={() => navigate(back.to, { state: back.state })}>
            <ArrowLeft className="w-4 h-4" />
          </Button>
          <div>
            <h1 className="text-2xl font-bold">
              {c.type === 'BUSINESS' && c.companyName
                ? c.companyName
                : `${c.firstName} ${c.lastName}`}
            </h1>
          <p className="text-gray-500 font-mono flex items-center gap-1">
            {c.customerNumber}
            <CopyButton value={c.customerNumber} />
          </p>
          </div>
        </div>
        <div className="flex gap-2">
          {hasPermission('customers:update') && (
            <Link to={`/customers/${id}/edit`} state={pushHistory(location.pathname + location.search, (location as any).state)}>
              <Button variant="secondary">
                <Edit className="w-4 h-4 mr-2" />
                Bearbeiten
              </Button>
            </Link>
          )}
          {hasPermission('customers:delete') && (
            <Button
              variant="danger"
              onClick={() => {
                if (confirm('Kunde wirklich löschen?')) {
                  deleteMutation.mutate();
                }
              }}
            >
              <Trash2 className="w-4 h-4 mr-2" />
              Löschen
            </Button>
          )}
        </div>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
        <Card title="Stammdaten" className="lg:col-span-2">
          <dl className="grid grid-cols-2 gap-4">
            <div>
              <dt className="text-sm text-gray-500">Typ</dt>
              <dd>
                <Badge variant={c.type === 'BUSINESS' ? 'info' : 'default'}>
                  {c.type === 'BUSINESS' ? 'Geschäftskunde' : 'Privatkunde'}
                </Badge>
              </dd>
            </div>
            {c.salutation && (
              <div>
                <dt className="text-sm text-gray-500">Anrede</dt>
                <dd className="flex items-center gap-1">
                  {c.salutation}
                  <CopyButton value={c.salutation} />
                </dd>
              </div>
            )}
            <div>
              <dt className="text-sm text-gray-500">Anrede per</dt>
              <dd className="flex items-center gap-2 flex-wrap">
                <Badge variant={c.useInformalAddress ? 'info' : 'default'}>
                  {c.useInformalAddress ? 'Du (informell)' : 'Sie (formell)'}
                </Badge>
                <span className="text-xs text-gray-400">Standard für alle Mitarbeiter</span>
              </dd>
            </div>
            {!isCustomerPortal && (
              <div>
                <dt className="text-sm text-gray-500">Anrede für mich</dt>
                <dd><SalutationPreferenceToggle customerId={customerId} customerDefaultInformal={!!c.useInformalAddress} /></dd>
              </div>
            )}
            <div>
              <dt className="text-sm text-gray-500">Vorname</dt>
              <dd className="flex items-center gap-1">
                {c.firstName}
                <CopyButton value={c.firstName} />
              </dd>
            </div>
            <div>
              <dt className="text-sm text-gray-500">Nachname</dt>
              <dd className="flex items-center gap-1">
                {c.lastName}
                <CopyButton value={c.lastName} />
              </dd>
            </div>
            {c.companyName && (
              <div className="col-span-2">
                <dt className="text-sm text-gray-500">Firma</dt>
                <dd className="flex items-center gap-1">
                  {c.companyName}
                  <CopyButton value={c.companyName} />
                </dd>
              </div>
            )}
            {c.foundingDate && (
              <div>
                <dt className="text-sm text-gray-500">Gründungsdatum</dt>
                <dd className="flex items-center gap-1">
                  {new Date(c.foundingDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })}
                  <CopyButton value={new Date(c.foundingDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })} />
                </dd>
              </div>
            )}
            {c.birthDate && (
              <div>
                <dt className="text-sm text-gray-500">Geburtsdatum</dt>
                <dd className="flex items-center gap-1">
                  {new Date(c.birthDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })}
                  <CopyButton value={new Date(c.birthDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })} />
                  {!isCustomerPortal && hasPermission('customers:update') && (
                    <button
                      type="button"
                      onClick={() => setShowBirthdayModal(true)}
                      className="ml-1 p-1 hover:bg-pink-50 rounded transition-colors"
                      title="Geburtstag verwalten"
                    >
                      <Cake className="w-4 h-4 text-pink-500" />
                    </button>
                  )}
                </dd>
              </div>
            )}
            {c.birthPlace && (
              <div>
                <dt className="text-sm text-gray-500">Geburtsort</dt>
                <dd className="flex items-center gap-1">
                  {c.birthPlace}
                  <CopyButton value={c.birthPlace} />
                </dd>
              </div>
            )}
          </dl>
        </Card>

        <Card title="Kontakt">
          <dl className="space-y-3">
            {c.email && (
              <div>
                <dt className="text-sm text-gray-500">E-Mail</dt>
                <dd className="flex items-center gap-1">
                  <a href={`mailto:${c.email}`} className="text-blue-600 hover:underline">
                    {c.email}
                  </a>
                  <CopyButton value={c.email} />
                  {(c.stressfreiEmails?.length ?? 0) > 0 && (
                    <a
                      href={`/customers/${c.id}?tab=stressfrei`}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-gray-400 hover:text-blue-600 ml-1"
                      title="Stressfrei-Wechseln-Adressen öffnen (neuer Tab). Nach Änderung der Stamm-E-Mail dort die Weiterleitungen synchronisieren."
                    >
                      <ExternalLink className="w-3.5 h-3.5" />
                    </a>
                  )}
                </dd>
              </div>
            )}
            {c.phone && (
              <div>
                <dt className="text-sm text-gray-500">Telefon</dt>
                <dd className="flex items-center gap-1">
                  <a href={`tel:${c.phone}`} className="text-blue-600 hover:underline">
                    {c.phone}
                  </a>
                  <CopyButton value={c.phone} />
                </dd>
              </div>
            )}
            {c.mobile && (
              <div>
                <dt className="text-sm text-gray-500">Mobil</dt>
                <dd className="flex items-center gap-1">
                  <a href={`tel:${c.mobile}`} className="text-blue-600 hover:underline">
                    {c.mobile}
                  </a>
                  <CopyButton value={c.mobile} />
                </dd>
              </div>
            )}
          </dl>
        </Card>
      </div>

      {c.type === 'BUSINESS' && (
        <BusinessDataCard
          customer={c}
          canEdit={hasPermission('customers:update')}
          onUpdate={() => queryClient.invalidateQueries({ queryKey: ['customer', customerId] })}
        />
      )}

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

      <Card>
        <Tabs
          tabs={tabs}
          defaultTab={defaultTab}
          activeTab={activeTab}
          onTabChange={handleTabChange}
          tabHrefBuilder={(tabId) => `${location.pathname}?tab=${tabId}`}
        />
      </Card>

      <AddressModal
        isOpen={showAddressModal}
        onClose={() => setShowAddressModal(false)}
        customerId={customerId}
      />

      <AddressModal
        isOpen={!!editingAddress}
        onClose={() => setEditingAddress(null)}
        customerId={customerId}
        address={editingAddress}
      />

      <BankCardModal
        isOpen={showBankCardModal}
        onClose={() => setShowBankCardModal(false)}
        customerId={customerId}
      />

      <BankCardModal
        isOpen={!!editingBankCard}
        onClose={() => setEditingBankCard(null)}
        customerId={customerId}
        bankCard={editingBankCard}
      />

      <DocumentModal
        isOpen={showDocumentModal}
        onClose={() => setShowDocumentModal(false)}
        customerId={customerId}
      />

      <DocumentModal
        isOpen={!!editingDocument}
        onClose={() => setEditingDocument(null)}
        customerId={customerId}
        document={editingDocument}
      />

      <MeterModal
        isOpen={showMeterModal}
        onClose={() => setShowMeterModal(false)}
        customerId={customerId}
        addresses={c.addresses || []}
        existingMeters={c.meters || []}
      />

      <MeterModal
        isOpen={!!editingMeter}
        onClose={() => setEditingMeter(null)}
        customerId={customerId}
        meter={editingMeter}
        addresses={c.addresses || []}
        existingMeters={c.meters || []}
      />

      <StressfreiEmailModal
        isOpen={showStressfreiEmailModal}
        onClose={() => setShowStressfreiEmailModal(false)}
        customerId={customerId}
        customerEmail={customer?.data?.email}
      />

      <StressfreiEmailModal
        isOpen={!!editingStressfreiEmail}
        onClose={() => setEditingStressfreiEmail(null)}
        customerId={customerId}
        email={editingStressfreiEmail}
        customerEmail={customer?.data?.email}
      />

      {showBirthdayModal && c && (
        <BirthdayManagementModal
          customer={c}
          onClose={() => setShowBirthdayModal(false)}
        />
      )}
    </div>
  );
}

// Business Data Card with Document Uploads
function BusinessDataCard({
  customer,
  canEdit,
  onUpdate,
}: {
  customer: Customer;
  canEdit: boolean;
  onUpdate: () => void;
}) {
  const handleBusinessRegUpload = async (file: File) => {
    try {
      await uploadApi.uploadBusinessRegistration(customer.id, file);
      onUpdate();
    } catch (error) {
      console.error('Upload fehlgeschlagen:', error);
      alert('Upload fehlgeschlagen');
    }
  };

  const handleBusinessRegDelete = async () => {
    if (!confirm('Gewerbeanmeldung wirklich löschen?')) return;
    try {
      await uploadApi.deleteBusinessRegistration(customer.id);
      onUpdate();
    } catch (error) {
      console.error('Löschen fehlgeschlagen:', error);
      alert('Löschen fehlgeschlagen');
    }
  };

  const handleCommercialRegUpload = async (file: File) => {
    try {
      await uploadApi.uploadCommercialRegister(customer.id, file);
      onUpdate();
    } catch (error) {
      console.error('Upload fehlgeschlagen:', error);
      alert('Upload fehlgeschlagen');
    }
  };

  const handleCommercialRegDelete = async () => {
    if (!confirm('Handelsregisterauszug wirklich löschen?')) return;
    try {
      await uploadApi.deleteCommercialRegister(customer.id);
      onUpdate();
    } catch (error) {
      console.error('Löschen fehlgeschlagen:', error);
      alert('Löschen fehlgeschlagen');
    }
  };

  const hasData = customer.taxNumber || customer.commercialRegisterNumber ||
                  customer.businessRegistrationPath || customer.commercialRegisterPath;

  if (!hasData && !canEdit) return null;

  return (
    <Card title="Geschäftsdaten" className="mb-6">
      <dl className="grid grid-cols-1 md:grid-cols-2 gap-4">
        {customer.taxNumber && (
          <div>
            <dt className="text-sm text-gray-500">Steuernummer</dt>
            <dd className="flex items-center gap-1">
              {customer.taxNumber}
              <CopyButton value={customer.taxNumber} />
            </dd>
          </div>
        )}
        {customer.commercialRegisterNumber && (
          <div>
            <dt className="text-sm text-gray-500">Handelsregisternummer</dt>
            <dd className="flex items-center gap-1">
              {customer.commercialRegisterNumber}
              <CopyButton value={customer.commercialRegisterNumber} />
            </dd>
          </div>
        )}
      </dl>

      {/* Dokumente */}
      <div className="mt-4 pt-4 border-t grid grid-cols-1 md:grid-cols-2 gap-6">
        {/* Gewerbeanmeldung */}
        <div>
          <h4 className="text-sm font-medium text-gray-700 mb-2">Gewerbeanmeldung</h4>
          {customer.businessRegistrationPath ? (
            <div className="flex items-center gap-2 flex-wrap">
              <a
                href={viewUrl(customer.businessRegistrationPath)}
                target="_blank"
                rel="noopener noreferrer"
                className="text-blue-600 hover:underline text-sm flex items-center gap-1"
              >
                <Eye className="w-4 h-4" />
                Anzeigen
              </a>
              <a
                href={fileUrl(customer.businessRegistrationPath)}
                download
                className="text-blue-600 hover:underline text-sm flex items-center gap-1"
              >
                <Download className="w-4 h-4" />
                Download
              </a>
              {canEdit && (
                <>
                  <FileUpload
                    onUpload={handleBusinessRegUpload}
                    existingFile={customer.businessRegistrationPath}
                    accept=".pdf"
                    label="Ersetzen"
                  />
                  <button
                    onClick={handleBusinessRegDelete}
                    className="text-red-600 hover:underline text-sm flex items-center gap-1"
                  >
                    <Trash2 className="w-4 h-4" />
                    Löschen
                  </button>
                </>
              )}
            </div>
          ) : canEdit ? (
            <FileUpload
              onUpload={handleBusinessRegUpload}
              accept=".pdf"
              label="PDF hochladen"
            />
          ) : (
            <p className="text-sm text-gray-400">Nicht vorhanden</p>
          )}
        </div>

        {/* Handelsregisterauszug */}
        <div>
          <h4 className="text-sm font-medium text-gray-700 mb-2">Handelsregisterauszug</h4>
          {customer.commercialRegisterPath ? (
            <div className="flex items-center gap-2 flex-wrap">
              <a
                href={viewUrl(customer.commercialRegisterPath)}
                target="_blank"
                rel="noopener noreferrer"
                className="text-blue-600 hover:underline text-sm flex items-center gap-1"
              >
                <Eye className="w-4 h-4" />
                Anzeigen
              </a>
              <a
                href={fileUrl(customer.commercialRegisterPath)}
                download
                className="text-blue-600 hover:underline text-sm flex items-center gap-1"
              >
                <Download className="w-4 h-4" />
                Download
              </a>
              {canEdit && (
                <>
                  <FileUpload
                    onUpload={handleCommercialRegUpload}
                    existingFile={customer.commercialRegisterPath}
                    accept=".pdf"
                    label="Ersetzen"
                  />
                  <button
                    onClick={handleCommercialRegDelete}
                    className="text-red-600 hover:underline text-sm flex items-center gap-1"
                  >
                    <Trash2 className="w-4 h-4" />
                    Löschen
                  </button>
                </>
              )}
            </div>
          ) : canEdit ? (
            <FileUpload
              onUpload={handleCommercialRegUpload}
              accept=".pdf"
              label="PDF hochladen"
            />
          ) : (
            <p className="text-sm text-gray-400">Nicht vorhanden</p>
          )}
        </div>
      </div>
    </Card>
  );
}

// Tab Components
function AddressesTab({
  customerId,
  addresses,
  canEdit,
  onAdd,
  onEdit,
}: {
  customerId: number;
  addresses: Address[];
  canEdit: boolean;
  onAdd: () => void;
  onEdit: (address: Address) => void;
}) {
  const queryClient = useQueryClient();
  const deleteMutation = useMutation({
    mutationFn: addressApi.delete,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['customer', customerId] }),
  });

  return (
    <div>
      {canEdit && (
        <div className="mb-4">
          <Button size="sm" onClick={onAdd}>
            <Plus className="w-4 h-4 mr-2" />
            Adresse hinzufügen
          </Button>
        </div>
      )}

      {addresses.length > 0 ? (
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          {addresses.map((addr) => (
            <div key={addr.id} className="border rounded-lg p-4">
              <div className="flex items-start justify-between">
                <div className="flex items-center gap-2 mb-2">
                  <MapPin className="w-4 h-4 text-gray-400" />
                  <Badge variant={addr.type === 'BILLING' ? 'info' : 'default'}>
                    {addr.type === 'BILLING' ? 'Rechnung' : 'Liefer-/Meldeadresse'}
                  </Badge>
                  {addr.isDefault && <Badge variant="success">Standard</Badge>}
                </div>
                {canEdit && (
                  <div className="flex gap-1">
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => onEdit(addr)}
                      title="Bearbeiten"
                    >
                      <Edit className="w-4 h-4" />
                    </Button>
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => {
                        if (confirm('Adresse wirklich löschen?')) {
                          deleteMutation.mutate(addr.id);
                        }
                      }}
                      title="Löschen"
                    >
                      <Trash2 className="w-4 h-4 text-red-500" />
                    </Button>
                  </div>
                )}
              </div>
              <CopyableBlock
                values={[
                  `${addr.street} ${addr.houseNumber}`,
                  `${addr.postalCode} ${addr.city}`,
                  addr.country
                ]}
              >
                <p>
                  {addr.street} {addr.houseNumber}
                </p>
                <p>
                  {addr.postalCode} {addr.city}
                </p>
                <p className="text-gray-500">{addr.country}</p>
              </CopyableBlock>
              {(addr.ownerFirstName || addr.ownerLastName || addr.ownerCompany) && (
                <div className="mt-2 pt-2 border-t text-xs text-gray-500">
                  <span className="font-medium">Eigentümer: </span>
                  {addr.ownerCompany && <span>{addr.ownerCompany} – </span>}
                  {addr.ownerFirstName} {addr.ownerLastName}
                  {addr.ownerPhone && <span> · {addr.ownerPhone}</span>}
                </div>
              )}
            </div>
          ))}
        </div>
      ) : (
        <p className="text-gray-500">Keine Adressen vorhanden.</p>
      )}
    </div>
  );
}

function BankCardsTab({
  customerId,
  bankCards,
  canEdit,
  showInactive,
  onToggleInactive,
  onAdd,
  onEdit,
}: {
  customerId: number;
  bankCards: BankCard[];
  canEdit: boolean;
  showInactive: boolean;
  onToggleInactive: () => void;
  onAdd: () => void;
  onEdit: (card: BankCard) => void;
}) {
  const queryClient = useQueryClient();
  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<BankCard> }) =>
      bankCardApi.update(id, data),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['customer', customerId] }),
  });

  const deleteMutation = useMutation({
    mutationFn: bankCardApi.delete,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['customer', customerId] }),
  });

  const handleDocumentUpload = async (cardId: number, file: File) => {
    try {
      await uploadApi.uploadBankCardDocument(cardId, file);
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
    } catch (error) {
      console.error('Upload fehlgeschlagen:', error);
      alert('Upload fehlgeschlagen');
    }
  };

  const handleDocumentDelete = async (cardId: number) => {
    if (!confirm('Dokument wirklich löschen?')) return;
    try {
      await uploadApi.deleteBankCardDocument(cardId);
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
    } catch (error) {
      console.error('Löschen fehlgeschlagen:', error);
      alert('Löschen fehlgeschlagen');
    }
  };

  const filtered = showInactive ? bankCards : bankCards.filter((c) => c.isActive);

  return (
    <div>
      <div className="flex items-center gap-4 mb-4">
        {canEdit && (
          <Button size="sm" onClick={onAdd}>
            <Plus className="w-4 h-4 mr-2" />
            Bankkarte hinzufügen
          </Button>
        )}
        <label className="flex items-center gap-2 text-sm">
          <input
            type="checkbox"
            checked={showInactive}
            onChange={onToggleInactive}
            className="rounded"
          />
          Inaktive anzeigen
        </label>
      </div>

      {filtered.length > 0 ? (
        <div className="space-y-4">
          {filtered.map((card) => (
            <div
              key={card.id}
              className={`border rounded-lg p-4 ${!card.isActive ? 'opacity-50 bg-gray-50' : ''}`}
            >
              <div className="flex items-start justify-between">
                <div className="flex items-center gap-2 mb-2">
                  <CreditCard className="w-4 h-4 text-gray-400" />
                  {!card.isActive && <Badge variant="danger">Inaktiv</Badge>}
                  {card.expiryDate && new Date(card.expiryDate) < new Date() && (
                    <Badge variant="warning">Abgelaufen</Badge>
                  )}
                </div>
                {canEdit && (
                  <div className="flex gap-1">
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => onEdit(card)}
                      title="Bearbeiten"
                    >
                      <Edit className="w-4 h-4" />
                    </Button>
                    {card.isActive ? (
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => {
                          if (confirm('Bankkarte deaktivieren?')) {
                            updateMutation.mutate({ id: card.id, data: { isActive: false } });
                          }
                        }}
                        title="Deaktivieren"
                      >
                        <EyeOff className="w-4 h-4" />
                      </Button>
                    ) : (
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => {
                          if (confirm('Bankkarte wieder aktivieren?')) {
                            updateMutation.mutate({ id: card.id, data: { isActive: true } });
                          }
                        }}
                        title="Aktivieren"
                      >
                        <Eye className="w-4 h-4" />
                      </Button>
                    )}
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => {
                        if (confirm('Bankkarte wirklich löschen?')) {
                          deleteMutation.mutate(card.id);
                        }
                      }}
                      title="Löschen"
                    >
                      <Trash2 className="w-4 h-4 text-red-500" />
                    </Button>
                  </div>
                )}
              </div>
              <p className="font-medium flex items-center gap-1">
                {card.accountHolder}
                <CopyButton value={card.accountHolder} />
              </p>
              <p className="font-mono flex items-center gap-1">
                {card.iban}
                <CopyButton value={card.iban} />
              </p>
              {card.bic && (
                <p className="text-sm text-gray-500 flex items-center gap-1">
                  BIC: {card.bic}
                  <CopyButton value={card.bic} />
                </p>
              )}
              {card.bankName && (
                <p className="text-sm text-gray-500 flex items-center gap-1">
                  {card.bankName}
                  <CopyButton value={card.bankName} />
                </p>
              )}
              {card.expiryDate && (
                <p className="text-sm text-gray-500">
                  Gültig bis: {formatDate(card.expiryDate)}
                </p>
              )}
              {card.description && (
                <p className="text-sm text-gray-600 mt-1 italic whitespace-pre-line">
                  {card.description}
                </p>
              )}

              {/* Dokument-Upload Bereich */}
              <div className="mt-3 pt-3 border-t">
                {card.documentPath ? (
                  <div className="flex items-center gap-2 flex-wrap">
                    <a
                      href={viewUrl(card.documentPath)}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                    >
                      <Eye className="w-4 h-4" />
                      Anzeigen
                    </a>
                    <a
                      href={fileUrl(card.documentPath)}
                      download
                      className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                    >
                      <Download className="w-4 h-4" />
                      Download
                    </a>
                    {canEdit && (
                      <>
                        <FileUpload
                          onUpload={(file) => handleDocumentUpload(card.id, file)}
                          existingFile={card.documentPath}
                          accept=".pdf"
                          label="Ersetzen"
                          disabled={!card.isActive}
                        />
                        <button
                          onClick={() => handleDocumentDelete(card.id)}
                          className="text-red-600 hover:underline text-sm flex items-center gap-1"
                          title="Dokument löschen"
                        >
                          <Trash2 className="w-4 h-4" />
                          Löschen
                        </button>
                      </>
                    )}
                  </div>
                ) : (
                  canEdit && card.isActive && (
                    <FileUpload
                      onUpload={(file) => handleDocumentUpload(card.id, file)}
                      accept=".pdf"
                      label="PDF hochladen"
                    />
                  )
                )}
              </div>
            </div>
          ))}
        </div>
      ) : (
        <p className="text-gray-500">Keine Bankkarten vorhanden.</p>
      )}
    </div>
  );
}

function DocumentsTab({
  customerId,
  documents,
  canEdit,
  showInactive,
  onToggleInactive,
  onAdd,
  onEdit,
}: {
  customerId: number;
  documents: IdentityDocument[];
  canEdit: boolean;
  showInactive: boolean;
  onToggleInactive: () => void;
  onAdd: () => void;
  onEdit: (doc: IdentityDocument) => void;
}) {
  const queryClient = useQueryClient();
  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<IdentityDocument> }) =>
      documentApi.update(id, data),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['customer', customerId] }),
  });

  const deleteMutation = useMutation({
    mutationFn: documentApi.delete,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['customer', customerId] }),
  });

  const handleDocumentUpload = async (docId: number, file: File) => {
    try {
      await uploadApi.uploadIdentityDocument(docId, file);
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
    } catch (error) {
      console.error('Upload fehlgeschlagen:', error);
      alert('Upload fehlgeschlagen');
    }
  };

  const handleDocumentDelete = async (docId: number) => {
    if (!confirm('Dokument wirklich löschen?')) return;
    try {
      await uploadApi.deleteIdentityDocument(docId);
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
    } catch (error) {
      console.error('Löschen fehlgeschlagen:', error);
      alert('Löschen fehlgeschlagen');
    }
  };

  const filtered = showInactive ? documents : documents.filter((d) => d.isActive);

  const docTypeLabels: Record<string, string> = {
    ID_CARD: 'Personalausweis',
    PASSPORT: 'Reisepass',
    DRIVERS_LICENSE: 'Führerschein',
    OTHER: 'Sonstiges',
  };

  return (
    <div>
      <div className="flex items-center gap-4 mb-4">
        {canEdit && (
          <Button size="sm" onClick={onAdd}>
            <Plus className="w-4 h-4 mr-2" />
            Ausweis hinzufügen
          </Button>
        )}
        <label className="flex items-center gap-2 text-sm">
          <input
            type="checkbox"
            checked={showInactive}
            onChange={onToggleInactive}
            className="rounded"
          />
          Inaktive anzeigen
        </label>
      </div>

      {filtered.length > 0 ? (
        <div className="space-y-4">
          {filtered.map((doc) => (
            <div
              key={doc.id}
              className={`border rounded-lg p-4 ${!doc.isActive ? 'opacity-50 bg-gray-50' : ''}`}
            >
              <div className="flex items-start justify-between">
                <div className="flex items-center gap-2 mb-2">
                  <FileText className="w-4 h-4 text-gray-400" />
                  <Badge>{docTypeLabels[doc.type]}</Badge>
                  {!doc.isActive && <Badge variant="danger">Inaktiv</Badge>}
                  {doc.expiryDate && new Date(doc.expiryDate) < new Date() && (
                    <Badge variant="warning">Abgelaufen</Badge>
                  )}
                </div>
                {canEdit && (
                  <div className="flex gap-1">
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => onEdit(doc)}
                      title="Bearbeiten"
                    >
                      <Edit className="w-4 h-4" />
                    </Button>
                    {doc.isActive ? (
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => {
                          if (confirm('Ausweis deaktivieren?')) {
                            updateMutation.mutate({ id: doc.id, data: { isActive: false } });
                          }
                        }}
                        title="Deaktivieren"
                      >
                        <EyeOff className="w-4 h-4" />
                      </Button>
                    ) : (
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => {
                          if (confirm('Ausweis wieder aktivieren?')) {
                            updateMutation.mutate({ id: doc.id, data: { isActive: true } });
                          }
                        }}
                        title="Aktivieren"
                      >
                        <Eye className="w-4 h-4" />
                      </Button>
                    )}
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => {
                        if (confirm('Ausweis wirklich löschen?')) {
                          deleteMutation.mutate(doc.id);
                        }
                      }}
                      title="Löschen"
                    >
                      <Trash2 className="w-4 h-4 text-red-500" />
                    </Button>
                  </div>
                )}
              </div>
              <p className="font-mono flex items-center gap-1">
                {doc.documentNumber}
                <CopyButton value={doc.documentNumber} />
              </p>
              {doc.issuingAuthority && (
                <p className="text-sm text-gray-500 flex items-center gap-1">
                  Ausgestellt von: {doc.issuingAuthority}
                  <CopyButton value={doc.issuingAuthority} />
                </p>
              )}
              {doc.expiryDate && (
                <p className="text-sm text-gray-500">
                  Gültig bis: {new Date(doc.expiryDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })}
                </p>
              )}
              {/* Führerschein-spezifische Anzeige */}
              {doc.type === 'DRIVERS_LICENSE' && doc.licenseClasses && (
                <p className="text-sm text-gray-500 flex items-center gap-1">
                  Klassen: {doc.licenseClasses}
                  <CopyButton value={doc.licenseClasses} />
                </p>
              )}
              {doc.type === 'DRIVERS_LICENSE' && doc.licenseIssueDate && (
                <p className="text-sm text-gray-500">
                  Klasse B seit: {new Date(doc.licenseIssueDate).toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' })}
                </p>
              )}

              {/* Dokument-Upload Bereich */}
              <div className="mt-3 pt-3 border-t">
                {doc.documentPath ? (
                  <div className="flex items-center gap-2 flex-wrap">
                    <a
                      href={viewUrl(doc.documentPath)}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                    >
                      <Eye className="w-4 h-4" />
                      Anzeigen
                    </a>
                    <a
                      href={fileUrl(doc.documentPath)}
                      download
                      className="text-blue-600 hover:underline text-sm flex items-center gap-1"
                    >
                      <Download className="w-4 h-4" />
                      Download
                    </a>
                    {canEdit && (
                      <>
                        <FileUpload
                          onUpload={(file) => handleDocumentUpload(doc.id, file)}
                          existingFile={doc.documentPath}
                          accept=".pdf"
                          label="Ersetzen"
                          disabled={!doc.isActive}
                        />
                        <button
                          onClick={() => handleDocumentDelete(doc.id)}
                          className="text-red-600 hover:underline text-sm flex items-center gap-1"
                          title="Dokument löschen"
                        >
                          <Trash2 className="w-4 h-4" />
                          Löschen
                        </button>
                      </>
                    )}
                  </div>
                ) : (
                  canEdit && doc.isActive && (
                    <FileUpload
                      onUpload={(file) => handleDocumentUpload(doc.id, file)}
                      accept=".pdf"
                      label="PDF hochladen"
                    />
                  )
                )}
              </div>
            </div>
          ))}
        </div>
      ) : (
        <p className="text-gray-500">Keine Ausweise vorhanden.</p>
      )}
    </div>
  );
}

function MetersTab({
  customerId,
  meters,
  addresses,
  canEdit,
  showInactive,
  onToggleInactive,
  onAdd,
  onEdit,
}: {
  customerId: number;
  meters: Meter[];
  addresses: Address[];
  canEdit: boolean;
  showInactive: boolean;
  onToggleInactive: () => void;
  onAdd: () => void;
  onEdit: (meter: Meter) => void;
}) {
  const hasDeliveryAddress = addresses.some((a) => a.type === 'DELIVERY_RESIDENCE');
  const [showReadingModal, setShowReadingModal] = useState<{ meterId: number; meterType: 'ELECTRICITY' | 'GAS'; tariffModel?: string } | null>(null);
  const [expandedMeter, setExpandedMeter] = useState<number | null>(null);
  const [expandedContractsForMeter, setExpandedContractsForMeter] = useState<Set<number>>(new Set());
  const [editingReading, setEditingReading] = useState<{ meterId: number; meterType: 'ELECTRICITY' | 'GAS'; tariffModel?: string; reading: any } | null>(null);
  const queryClient = useQueryClient();

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<Meter> }) =>
      meterApi.update(id, data),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['customer', customerId] }),
  });

  const [deleteError, setDeleteError] = useState<string | null>(null);

  const deleteMutation = useMutation({
    mutationFn: meterApi.delete,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      setDeleteError(null);
    },
    onError: (err) => {
      setDeleteError(err instanceof Error ? err.message : 'Fehler beim Löschen');
    },
  });

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

  const [showWithoutContracts, setShowWithoutContracts] = useState(false);

  // Liefert true, wenn der Zähler mindestens einem Vertrag zugeordnet ist
  // (entweder als Hauptzähler oder über die Folgezähler-Kette).
  const hasAnyContract = (m: Meter) =>
    (m.energyDetails?.some((ed) => ed.contract) ?? false)
    || (m.contractMeters?.some((cm) => cm.energyContractDetails?.contract) ?? false);

  // Aktiv-Filter (Default: nur aktive) und "Nur Zähler ohne Verträge"-Filter
  // wirken unabhängig: erst Aktiv, dann optional auf orphans einschränken.
  // - beide aus: alle aktiven Zähler
  // - nur "Inaktive": alle Zähler (aktiv + inaktiv)
  // - nur "ohne Verträge": aktive Zähler OHNE Vertrag
  // - beide an: alle Zähler ohne Vertrag (aktiv + inaktiv)
  const filtered = meters
    .filter((m) => showInactive ? true : m.isActive)
    .filter((m) => showWithoutContracts ? !hasAnyContract(m) : true);

  // Sort readings by date (newest first)
  const getSortedReadings = (readings: any[] | undefined) => {
    if (!readings) return [];
    return [...readings].sort((a, b) =>
      new Date(b.readingDate).getTime() - new Date(a.readingDate).getTime()
    );
  };

  return (
    <div>
      <div className="flex items-center gap-4 mb-4">
        {canEdit && (
          <Button
            size="sm"
            onClick={onAdd}
            disabled={!hasDeliveryAddress}
            title={hasDeliveryAddress ? undefined : 'Erst Lieferadresse anlegen, dann Zähler hinzufügen'}
          >
            <Plus className="w-4 h-4 mr-2" />
            Zähler hinzufügen
          </Button>
        )}
        <label className="flex items-center gap-2 text-sm">
          <input
            type="checkbox"
            checked={showInactive}
            onChange={onToggleInactive}
            className="rounded"
          />
          Inaktive anzeigen
        </label>
        <label className="flex items-center gap-2 text-sm">
          <input
            type="checkbox"
            checked={showWithoutContracts}
            onChange={(e) => setShowWithoutContracts(e.target.checked)}
            className="rounded"
          />
          Zähler ohne Verträge anzeigen
        </label>
      </div>
      {canEdit && !hasDeliveryAddress && (
        <div className="mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-lg text-sm text-yellow-800">
          Es ist noch keine Lieferadresse hinterlegt. Bitte zunächst im Tab „Adressen" eine
          Lieferadresse anlegen, dann können hier Zähler erstellt werden.
        </div>
      )}

      {filtered.length > 0 ? (
        <div className="space-y-4">
          {filtered.map((meter) => {
            const sortedReadings = getSortedReadings(meter.readings);
            const isExpanded = expandedMeter === meter.id;

            return (
              <div
                key={meter.id}
                className={`border rounded-lg p-4 ${!meter.isActive ? 'opacity-50 bg-gray-50' : ''}`}
              >
                <div className="flex items-start justify-between">
                  <div className="flex items-center gap-2 mb-2">
                    <Gauge className="w-4 h-4 text-gray-400" />
                    <Badge variant={meter.type === 'ELECTRICITY' ? 'warning' : 'info'}>
                      {meter.type === 'ELECTRICITY' ? 'Strom' : 'Gas'}
                    </Badge>
                    {meter.tariffModel === 'DUAL' && (
                      <Badge variant="default">HT/NT</Badge>
                    )}
                    {!meter.isActive && <Badge variant="danger">Inaktiv</Badge>}
                  </div>
                  {canEdit && (
                    <div className="flex gap-1">
                      {meter.isActive && (
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => setShowReadingModal({ meterId: meter.id, meterType: meter.type, tariffModel: meter.tariffModel })}
                          title="Zählerstand hinzufügen"
                        >
                          <Plus className="w-4 h-4" />
                        </Button>
                      )}
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => onEdit(meter)}
                        title="Bearbeiten"
                      >
                        <Edit className="w-4 h-4" />
                      </Button>
                      {meter.isActive ? (
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => {
                            if (confirm('Zähler deaktivieren?')) {
                              updateMutation.mutate({ id: meter.id, data: { isActive: false } });
                            }
                          }}
                          title="Deaktivieren"
                        >
                          <EyeOff className="w-4 h-4" />
                        </Button>
                      ) : (
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => {
                            if (confirm('Zähler wieder aktivieren?')) {
                              updateMutation.mutate({ id: meter.id, data: { isActive: true } });
                            }
                          }}
                          title="Aktivieren"
                        >
                          <Eye className="w-4 h-4" />
                        </Button>
                      )}
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => {
                          if (confirm('Zähler wirklich löschen? Alle Zählerstände werden ebenfalls gelöscht.')) {
                            deleteMutation.mutate(meter.id);
                          }
                        }}
                        title="Löschen"
                      >
                        <Trash2 className="w-4 h-4 text-red-500" />
                      </Button>
                    </div>
                  )}
                </div>
                <p className="font-mono text-lg flex items-center gap-1">
                  {meter.meterNumber}
                  <CopyButton value={meter.meterNumber} />
                </p>
                {meter.address ? (
                  <p className="text-sm text-gray-500">
                    Lieferadresse: {meter.address.street} {meter.address.houseNumber},{' '}
                    {meter.address.postalCode} {meter.address.city}
                  </p>
                ) : (
                  <p className="text-sm text-yellow-700">
                    Lieferadresse: <em>nicht zugeordnet – bitte über „Bearbeiten" nachpflegen</em>
                  </p>
                )}
                {meter.location && (
                  <p className="text-sm text-gray-500 flex items-center gap-1">
                    Standort: {meter.location}
                    <CopyButton value={meter.location} />
                  </p>
                )}

                {(() => {
                  // Zugeordnete Verträge zusammenstellen: zum einen über
                  // energyDetails (aktueller Hauptzähler), zum anderen über
                  // contractMeters (Folgezähler-Kette). Dedupliziert auf
                  // contractId, da ein Zähler über beide Wege auftauchen kann.
                  const seen = new Set<number>();
                  const linkedContracts: Array<{ id: number; contractNumber: string; status: string; type: string; providerName?: string; via: 'main' | 'chain' }> = [];
                  for (const ed of meter.energyDetails || []) {
                    if (ed.contract && !seen.has(ed.contract.id)) {
                      seen.add(ed.contract.id);
                      linkedContracts.push({ ...ed.contract, via: 'main' });
                    }
                  }
                  for (const cm of meter.contractMeters || []) {
                    const ct = cm.energyContractDetails?.contract;
                    if (ct && !seen.has(ct.id)) {
                      seen.add(ct.id);
                      linkedContracts.push({ ...ct, via: 'chain' });
                    }
                  }
                  if (linkedContracts.length === 0) return null;
                  const isContractsExpanded = expandedContractsForMeter.has(meter.id);
                  return (
                    <div className="mt-3 pt-3 border-t">
                      <button
                        type="button"
                        className="flex items-center gap-2 text-sm font-medium text-gray-700 hover:text-gray-900 w-full text-left"
                        onClick={() => {
                          setExpandedContractsForMeter((prev) => {
                            const next = new Set(prev);
                            if (next.has(meter.id)) next.delete(meter.id);
                            else next.add(meter.id);
                            return next;
                          });
                        }}
                      >
                        {isContractsExpanded ? <ChevronDown className="w-4 h-4" /> : <ChevronRight className="w-4 h-4" />}
                        Verträge ({linkedContracts.length})
                      </button>
                      {isContractsExpanded && (
                        <div className="mt-2 space-y-1 ml-6">
                          {linkedContracts.map((ct) => (
                            <Link
                              key={ct.id}
                              to={`/contracts/${ct.id}`}
                              target="_blank"
                              rel="noopener noreferrer"
                              className="flex items-center gap-2 text-sm text-blue-600 hover:text-blue-800 hover:underline"
                            >
                              <FileText className="w-3 h-3 flex-shrink-0" />
                              <span className="font-mono">{ct.contractNumber}</span>
                              {ct.providerName && (
                                <span className="text-gray-500 font-sans">– {ct.providerName}</span>
                              )}
                              <Badge variant={
                                ct.status === 'ACTIVE' ? 'success'
                                : ct.status === 'CANCELLED' ? 'warning'
                                : ct.status === 'CANCELLED_CONFIRMED' ? 'danger'
                                : ct.status === 'EXPIRED' ? 'warning'
                                : 'default'
                              }>{ct.status}</Badge>
                              {ct.via === 'chain' && (
                                <span className="text-xs text-gray-400">(über Folgezähler-Kette)</span>
                              )}
                            </Link>
                          ))}
                        </div>
                      )}
                    </div>
                  );
                })()}

                {sortedReadings.length > 0 && (
                  <div className="mt-3 pt-3 border-t">
                    <div className="flex items-center justify-between mb-2">
                      <p className="text-sm font-medium">Zählerstände:</p>
                      {sortedReadings.length > 3 && (
                        <Button
                          variant="ghost"
                          size="sm"
                          onClick={() => setExpandedMeter(isExpanded ? null : meter.id)}
                        >
                          {isExpanded ? 'Weniger anzeigen' : `Alle ${sortedReadings.length} anzeigen`}
                        </Button>
                      )}
                    </div>
                    <div className="space-y-1">
                      {(isExpanded ? sortedReadings : sortedReadings.slice(0, 3)).map((reading) => (
                        <div key={reading.id} className="flex justify-between items-center text-sm group">
                          <span className="text-gray-500 flex items-center gap-1">
                            {formatDate(reading.readingDate)}
                            <CopyButton value={formatDate(reading.readingDate)} />
                          </span>
                          <div className="flex items-center gap-2">
                            <span className="font-mono flex items-center gap-1">
                              {reading.valueNt !== undefined && reading.valueNt !== null ? (
                                <>HT: {reading.value.toLocaleString('de-DE')} / NT: {reading.valueNt.toLocaleString('de-DE')} {reading.unit}</>
                              ) : (
                                <>{reading.value.toLocaleString('de-DE')} {reading.unit}</>
                              )}
                              <CopyButton value={reading.value.toString()} title="Wert kopieren" />
                            </span>
                            {canEdit && (
                              <div className="opacity-0 group-hover:opacity-100 flex gap-1">
                                <button
                                  onClick={() => setEditingReading({ meterId: meter.id, meterType: meter.type, tariffModel: meter.tariffModel, reading })}
                                  className="text-gray-400 hover:text-blue-600"
                                  title="Bearbeiten"
                                >
                                  <Edit className="w-3 h-3" />
                                </button>
                                <button
                                  onClick={() => {
                                    if (confirm('Zählerstand wirklich löschen?')) {
                                      deleteReadingMutation.mutate({ meterId: meter.id, readingId: reading.id });
                                    }
                                  }}
                                  className="text-gray-400 hover:text-red-600"
                                  title="Löschen"
                                >
                                  <Trash2 className="w-3 h-3" />
                                </button>
                              </div>
                            )}
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      ) : (
        <p className="text-gray-500">Keine Zähler vorhanden.</p>
      )}

      {showReadingModal && (
        <MeterReadingModal
          isOpen={true}
          onClose={() => setShowReadingModal(null)}
          meterId={showReadingModal.meterId}
          meterType={showReadingModal.meterType}
          tariffModel={showReadingModal.tariffModel as any}
          customerId={customerId}
        />
      )}

      {editingReading && (
        <MeterReadingModal
          isOpen={true}
          onClose={() => setEditingReading(null)}
          meterId={editingReading.meterId}
          meterType={editingReading.meterType}
          tariffModel={editingReading.tariffModel as any}
          customerId={customerId}
          reading={editingReading.reading}
        />
      )}

      {/* Fehler-Modal beim Löschen (z.B. Zähler noch an Vertrag) */}
      {deleteError && (
        <Modal isOpen={true} onClose={() => setDeleteError(null)} title="Zähler kann nicht gelöscht werden">
          <p className="text-sm text-gray-600 mb-4">
            Der Zähler ist noch folgenden Verträgen zugeordnet und kann daher nicht gelöscht werden:
          </p>
          <div className="space-y-2">
            {deleteError.match(/[A-Z]+-[A-Z0-9]+/g)?.map((contractNumber) => (
              <Link
                key={contractNumber}
                to={`/contracts?search=${contractNumber}`}
                onClick={() => setDeleteError(null)}
                className="flex items-center gap-2 p-3 bg-gray-50 border rounded-lg text-blue-600 hover:bg-blue-50 hover:border-blue-300 transition-colors"
              >
                <FileText className="w-4 h-4" />
                <span className="font-mono">{contractNumber}</span>
              </Link>
            )) ?? (
              <p className="text-sm text-red-600">{deleteError}</p>
            )}
          </div>
          <p className="text-xs text-gray-500 mt-4">
            Bitte entfernen Sie den Zähler zuerst aus den oben genannten Verträgen.
          </p>
          <div className="flex justify-end mt-4">
            <Button variant="secondary" onClick={() => setDeleteError(null)}>
              Schließen
            </Button>
          </div>
        </Modal>
      )}
    </div>
  );
}

function ContractsTab({
  customerId,
}: {
  customerId: number;
}) {
  const { hasPermission } = useAuth();
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const [expandedContracts, setExpandedContracts] = useState<Set<number>>(new Set());
  const [showStatusInfo, setShowStatusInfo] = useState(false);
  const [showDeactivated, setShowDeactivated] = useState(false);

  // Lade Vertragsbaum statt flacher Liste. showDeactivated ist Teil des
  // Query-Keys, damit der Toggle einen frischen Fetch auslöst.
  const { data: treeData, isLoading } = useQuery({
    queryKey: ['contract-tree', customerId, showDeactivated],
    queryFn: () => contractApi.getTreeForCustomer(customerId, showDeactivated),
  });

  const contractTree = treeData?.data || [];

  const deleteMutation = useMutation({
    mutationFn: contractApi.delete,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      queryClient.invalidateQueries({ queryKey: ['customers'] });
      queryClient.invalidateQueries({ queryKey: ['contracts'] });
      queryClient.invalidateQueries({ queryKey: ['contract-tree', customerId] });
    },
    onError: (error: any) => {
      alert(error?.message || 'Fehler beim Löschen des Vertrags');
    },
  });

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

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

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

  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' },
  ];

  const toggleExpand = (contractId: number) => {
    setExpandedContracts(prev => {
      const next = new Set(prev);
      if (next.has(contractId)) {
        next.delete(contractId);
      } else {
        next.add(contractId);
      }
      return next;
    });
  };

  // Rekursive Rendering-Funktion für Vorgänger
  const renderPredecessors = (predecessors: ContractTreeNode[], depth: number): React.ReactNode => {
    return predecessors.map(node => (
      <div key={node.contract.id}>
        {renderContractNode(node, depth)}
      </div>
    ));
  };

  // Einzelnen Vertragsknoten rendern
  const renderContractNode = (node: ContractTreeNode, depth: number = 0): React.ReactNode => {
    const { contract, predecessors, hasHistory } = node;
    const isExpanded = expandedContracts.has(contract.id);
    const isPredecessor = depth > 0;

    return (
      <div key={contract.id}>
        <div
          className={`
            border rounded-lg p-4 transition-colors
            ${isPredecessor ? 'ml-6 border-l-4 border-l-gray-300 bg-gray-50' : 'hover:bg-gray-50'}
          `}
        >
          <div className="flex items-center justify-between mb-2">
            <div className="flex items-center gap-2">
              {/* Aufklapp-Button nur bei Wurzelknoten mit Historie */}
              {!isPredecessor && hasHistory ? (
                <button
                  onClick={() => toggleExpand(contract.id)}
                  className="p-1 hover:bg-gray-200 rounded transition-colors"
                  title={isExpanded ? 'Einklappen' : 'Vorgänger anzeigen'}
                >
                  {isExpanded ? (
                    <ChevronDown className="w-4 h-4 text-gray-500" />
                  ) : (
                    <ChevronRight className="w-4 h-4 text-gray-500" />
                  )}
                </button>
              ) : !isPredecessor ? (
                <div className="w-6" /> // Platzhalter für Ausrichtung
              ) : null}

              <Link to={`/contracts/${contract.id}`} state={pushHistory(location.pathname + location.search, (location as any).state)} className="font-mono flex items-center gap-1 text-blue-600 hover:underline">
                {contract.contractNumber}
                <CopyButton value={contract.contractNumber} />
              </Link>
              <Badge>{typeLabels[contract.type] || contract.type}</Badge>
              <Badge variant={statusVariants[contract.status] || 'default'}>{statusLabels[contract.status] || contract.status}</Badge>
              {depth === 0 && !isPredecessor && (
                <button
                  onClick={(e) => { e.stopPropagation(); setShowStatusInfo(true); }}
                  className="text-gray-400 hover:text-blue-600 transition-colors"
                  title="Status-Erklärung"
                >
                  <Info className="w-4 h-4" />
                </button>
              )}

              {isPredecessor && (
                <span className="text-xs text-gray-500 ml-2">(Vorgänger)</span>
              )}
            </div>
            <div className="flex gap-2">
              <Button
                variant="ghost"
                size="sm"
                onClick={() => navigate(`/contracts/${contract.id}`, {
                  state: { from: 'customer', customerId: customerId.toString() }
                })}
                title="Ansehen"
              >
                <Eye className="w-4 h-4" />
              </Button>
              {hasPermission('contracts:update') && (
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => navigate(`/contracts/${contract.id}/edit`)}
                  title="Bearbeiten"
                >
                  <Edit className="w-4 h-4" />
                </Button>
              )}
              {hasPermission('contracts:delete') && (
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => {
                    if (confirm('Vertrag wirklich löschen?')) {
                      deleteMutation.mutate(contract.id);
                    }
                  }}
                  title="Löschen"
                >
                  <Trash2 className="w-4 h-4 text-red-500" />
                </Button>
              )}
            </div>
          </div>
          {(contract.providerName || contract.provider?.name) && (
            <p className={`flex items-center gap-1 ${isPredecessor ? 'ml-6' : ''}`}>
              {contract.providerName || contract.provider?.name}
              {(contract.tariffName || contract.tariff?.name) && ` - ${contract.tariffName || contract.tariff?.name}`}
              <CopyButton value={(contract.providerName || contract.provider?.name || '') + ((contract.tariffName || contract.tariff?.name) ? ` - ${contract.tariffName || contract.tariff?.name}` : '')} />
            </p>
          )}
          {(() => {
            const typeInfo = getContractTypeInfo(contract as any);
            return typeInfo ? (
              <p className={`text-sm text-gray-600 ${isPredecessor ? 'ml-6' : ''}`}>
                <span className="font-medium text-gray-700">{typeInfo.label}:</span> {typeInfo.value}
                {typeInfo.cardUser && (
                  <> · <span className="font-medium text-gray-700">Karteninhaber:</span> {typeInfo.cardUser}</>
                )}
                {typeInfo.network && (
                  <> · <span className="font-medium text-gray-700">Netz:</span> {typeInfo.network}</>
                )}
              </p>
            ) : null;
          })()}
          {contract.startDate && (
            <p className={`text-sm text-gray-500 ${isPredecessor ? 'ml-6' : ''}`}>
              Beginn: {formatDate(contract.startDate)}
              {contract.endDate &&
                ` | Ende: ${formatDate(contract.endDate)}`}
            </p>
          )}
          {contract.cancellationConfirmationDate && (
            <p className={`text-sm font-semibold text-red-600 ${isPredecessor ? 'ml-6' : ''}`}>
              Kündigungsbestätigung zum {formatDate(contract.cancellationConfirmationDate)}
            </p>
          )}
        </div>

        {/* Vorgänger rekursiv rendern - für Wurzel nur wenn aufgeklappt, für Vorgänger immer */}
        {((depth === 0 && isExpanded) || depth > 0) && predecessors.length > 0 && (
          <div className="mt-2">
            {renderPredecessors(predecessors, depth + 1)}
          </div>
        )}
      </div>
    );
  };

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-8">
        <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600"></div>
      </div>
    );
  }

  return (
    <div>
      <div className="mb-4 flex items-center justify-between gap-3 flex-wrap">
        {hasPermission('contracts:create') ? (
          <Link to={`/contracts/new?customerId=${customerId}`}>
            <Button size="sm">
              <Plus className="w-4 h-4 mr-2" />
              Vertrag anlegen
            </Button>
          </Link>
        ) : <span />}
        <Button
          size="sm"
          variant={showDeactivated ? 'secondary' : 'ghost'}
          onClick={() => setShowDeactivated((v) => !v)}
          title="Deaktivierte Verträge in der Liste ein-/ausblenden"
        >
          {showDeactivated ? <EyeOff className="w-4 h-4 mr-2" /> : <Eye className="w-4 h-4 mr-2" />}
          {showDeactivated ? 'Deaktivierte ausblenden' : 'Deaktivierte anzeigen'}
        </Button>
      </div>

      {contractTree.length > 0 ? (
        <div className="space-y-4">
          {contractTree.map(node => renderContractNode(node, 0))}
        </div>
      ) : (
        <p className="text-gray-500">Keine Verträge vorhanden.</p>
      )}

      {/* Status Info Modal */}
      {showStatusInfo && (
        <div className="fixed inset-0 z-50 flex items-center justify-center">
          <div className="fixed inset-0 bg-black/20" onClick={() => setShowStatusInfo(false)} />
          <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={() => setShowStatusInfo(false)} 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>
      )}
    </div>
  );
}

// Passwort-Komplexität – muss zur Backend-Regel in
// backend/src/utils/passwordGenerator.ts:validatePasswordComplexity passen.
function passwordMeetsComplexity(pw: string): boolean {
  return (
    pw.length >= 12 &&
    /[a-z]/.test(pw) &&
    /[A-Z]/.test(pw) &&
    /[0-9]/.test(pw) &&
    /[^A-Za-z0-9]/.test(pw)
  );
}

// Live-Hinweis welche Komplexitäts-Anforderungen noch fehlen
function PasswordComplexityHint({ password }: { password: string }) {
  const checks = [
    { ok: password.length >= 12, label: '≥ 12 Zeichen' },
    { ok: /[a-z]/.test(password), label: 'Kleinbuchstabe' },
    { ok: /[A-Z]/.test(password), label: 'Großbuchstabe' },
    { ok: /[0-9]/.test(password), label: 'Ziffer' },
    { ok: /[^A-Za-z0-9]/.test(password), label: 'Sonderzeichen' },
  ];
  return (
    <ul className="mt-2 text-xs space-y-0.5">
      {checks.map((c) => (
        <li key={c.label} className={c.ok ? 'text-green-600' : 'text-gray-500'}>
          {c.ok ? '✓' : '○'} {c.label}
        </li>
      ))}
    </ul>
  );
}

// Gespeichertes Passwort anzeigen
function StoredPasswordDisplay({ customerId }: { customerId: number }) {
  const [showStoredPassword, setShowStoredPassword] = useState(false);
  const [storedPassword, setStoredPassword] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(false);

  const handleShowPassword = async () => {
    if (showStoredPassword) {
      setShowStoredPassword(false);
      return;
    }
    setIsLoading(true);
    try {
      const result = await customerApi.getPortalPassword(customerId);
      setStoredPassword(result.data?.password || null);
      setShowStoredPassword(true);
    } catch (error) {
      console.error('Fehler beim Laden des Passworts:', error);
      alert('Fehler beim Laden des Passworts');
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <div className="flex items-center gap-2 mt-1">
      <p className="text-xs text-green-600">Passwort ist gesetzt</p>
      <button
        type="button"
        onClick={handleShowPassword}
        className="text-xs text-blue-600 hover:underline flex items-center gap-1"
        disabled={isLoading}
      >
        {isLoading ? (
          'Laden...'
        ) : showStoredPassword ? (
          <>
            <EyeOff className="w-3 h-3" />
            Verbergen
          </>
        ) : (
          <>
            <Eye className="w-3 h-3" />
            Anzeigen
          </>
        )}
      </button>
      {showStoredPassword && storedPassword && (
        <span className="text-xs font-mono bg-gray-100 px-2 py-1 rounded flex items-center gap-1">
          {storedPassword}
          <CopyButton value={storedPassword} />
        </span>
      )}
      {showStoredPassword && !storedPassword && (
        <span className="text-xs text-gray-500">(Passwort nicht verfügbar)</span>
      )}
    </div>
  );
}

// Portal Tab Component
function PortalTab({
  customerId,
  canEdit,
}: {
  customerId: number;
  canEdit: boolean;
}) {
  const queryClient = useQueryClient();
  const [showPassword, setShowPassword] = useState(false);
  const [newPassword, setNewPassword] = useState('');
  const [searchTerm, setSearchTerm] = useState('');
  const [searchResults, setSearchResults] = useState<CustomerSummary[]>([]);
  const [isSearching, setIsSearching] = useState(false);
  // Lokaler Eingabezustand für die Portal-E-Mail. Wenn wir den Input
  // direkt vom Server-State (`portal?.portalEmail`) speisen und auf
  // jedes Keystroke einen PUT feuern, lehnt der Backend-Validator
  // (Pentest 29.4) die Zwischenstände ("p", "po", "por") als
  // ungültige E-Mail mit 400 ab → Server-State bleibt unverändert,
  // Input rendert mit altem Wert → man konnte nur per Paste
  // tippen. Lokaler State + Commit on Blur löst das.
  const [emailDraft, setEmailDraft] = useState<string | null>(null);

  // Lade Portal-Einstellungen
  const { data: portalData, isLoading: portalLoading } = useQuery({
    queryKey: ['customer-portal', customerId],
    queryFn: () => customerApi.getPortalSettings(customerId),
  });

  // Lade Vertreter-Liste
  const { data: representativesData, isLoading: repLoading } = useQuery({
    queryKey: ['customer-representatives', customerId],
    queryFn: () => customerApi.getRepresentatives(customerId),
  });

  // Portal-Einstellungen aktualisieren
  const updatePortalMutation = useMutation({
    mutationFn: (data: { portalEnabled?: boolean; portalEmail?: string | null }) =>
      customerApi.updatePortalSettings(customerId, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer-portal', customerId] });
      // Lokalen Draft verwerfen – kommt jetzt frisch vom Server.
      setEmailDraft(null);
    },
    onError: (err: Error) => {
      toast.error(err.message || 'Speichern fehlgeschlagen');
    },
  });

  // Passwort setzen
  const setPasswordMutation = useMutation({
    mutationFn: (password: string) => customerApi.setPortalPassword(customerId, password),
    onSuccess: () => {
      setNewPassword('');
      queryClient.invalidateQueries({ queryKey: ['customer-portal', customerId] });
      toast.success('Passwort wurde gesetzt');
    },
    onError: (error: Error) => {
      toast.error(error.message);
    },
  });

  // Passwort generieren (16 Zeichen, komplex) – ins Input-Feld füllen
  const generatePasswordMutation = useMutation({
    mutationFn: () => customerApi.generatePortalPassword(customerId),
    onSuccess: (res) => {
      const generated = res.data?.password || '';
      setNewPassword(generated);
      setShowPassword(true);
      toast.success('Komplexes Passwort generiert – jetzt „Setzen" klicken.');
    },
    onError: (error: Error) => {
      toast.error(error.message);
    },
  });

  // Zugangsdaten per E-Mail an den Kunden senden
  const sendCredentialsMutation = useMutation({
    mutationFn: () => customerApi.sendPortalCredentials(customerId),
    onSuccess: (res) => {
      toast.success(res.message || 'Zugangsdaten gesendet');
    },
    onError: (error: Error) => {
      toast.error(error.message);
    },
  });

  // Vertreter hinzufügen
  const addRepMutation = useMutation({
    mutationFn: (representativeId: number) =>
      customerApi.addRepresentative(customerId, representativeId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer-representatives', customerId] });
      setSearchTerm('');
      setSearchResults([]);
    },
    onError: (error: Error) => {
      alert(error.message);
    },
  });

  // Vertreter entfernen
  const removeRepMutation = useMutation({
    mutationFn: (representativeId: number) =>
      customerApi.removeRepresentative(customerId, representativeId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer-representatives', customerId] });
    },
  });

  // Vertreter-Suche
  const handleSearch = async () => {
    if (searchTerm.length < 2) return;
    setIsSearching(true);
    try {
      const result = await customerApi.searchForRepresentative(customerId, searchTerm);
      setSearchResults(result.data || []);
    } catch (error) {
      console.error('Suche fehlgeschlagen:', error);
    } finally {
      setIsSearching(false);
    }
  };

  if (portalLoading || repLoading) {
    return <div className="text-center py-4 text-gray-500">Laden...</div>;
  }

  const portal = portalData?.data;
  const representatives = representativesData?.data || [];

  return (
    <div className="space-y-6">
      {/* Portal-Einstellungen */}
      <div className="border rounded-lg p-4">
        <div className="flex items-center gap-2 mb-4">
          <Globe className="w-5 h-5 text-gray-400" />
          <h3 className="font-medium">Portal-Zugang</h3>
        </div>

        <div className="space-y-4">
          {/* Portal aktiviert */}
          <label className="flex items-center gap-3">
            <input
              type="checkbox"
              checked={portal?.portalEnabled || false}
              onChange={(e) => updatePortalMutation.mutate({ portalEnabled: e.target.checked })}
              className="rounded w-5 h-5"
              disabled={!canEdit}
            />
            <span>Portal aktiviert</span>
            {portal?.portalEnabled && (
              <Badge variant="success">Aktiv</Badge>
            )}
          </label>

          {/* Portal E-Mail */}
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">Portal E-Mail</label>
            <div className="flex gap-2">
              <Input
                value={emailDraft ?? portal?.portalEmail ?? ''}
                onChange={(e) => setEmailDraft(e.target.value)}
                onBlur={() => {
                  if (emailDraft === null) return;
                  const trimmed = emailDraft.trim();
                  // Nur committen wenn sich was geändert hat – sonst
                  // hauen wir bei jedem Tab-Wechsel einen sinnlosen
                  // PUT raus.
                  if (trimmed === (portal?.portalEmail || '')) {
                    setEmailDraft(null);
                    return;
                  }
                  updatePortalMutation.mutate({ portalEmail: trimmed || null });
                }}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') {
                    e.preventDefault();
                    (e.target as HTMLInputElement).blur();
                  }
                  if (e.key === 'Escape') {
                    setEmailDraft(null);
                    (e.target as HTMLInputElement).blur();
                  }
                }}
                placeholder="portal@example.com"
                disabled={!canEdit || !portal?.portalEnabled}
                className="flex-1"
              />
            </div>
            <p className="text-xs text-gray-500 mt-1">
              Diese E-Mail wird für den Login ins Kundenportal verwendet.
              Speichern erfolgt automatisch beim Verlassen des Felds (oder Enter).
            </p>
          </div>

          {/* Passwort setzen */}
          {portal?.portalEnabled && (
            <div>
              <label className="block text-sm font-medium text-gray-700 mb-1">
                {portal?.hasPassword ? 'Neues Passwort setzen' : 'Passwort setzen'}
              </label>
              <div className="flex gap-2">
                <div className="relative flex-1">
                  <Input
                    type={showPassword ? 'text' : 'password'}
                    value={newPassword}
                    onChange={(e) => setNewPassword(e.target.value)}
                    placeholder="Mind. 12 Zeichen, Groß/Klein/Zahl/Sonderzeichen"
                    disabled={!canEdit}
                  />
                  <button
                    type="button"
                    onClick={() => setShowPassword(!showPassword)}
                    className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400"
                  >
                    {showPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                  </button>
                </div>
                <Button
                  variant="secondary"
                  onClick={() => generatePasswordMutation.mutate()}
                  disabled={!canEdit || generatePasswordMutation.isPending}
                  title='Komplexes Passwort generieren (16 Zeichen, Groß/Klein/Zahl/Sonderzeichen). Wird ins Feld geschrieben – danach "Setzen" klicken.'
                >
                  {generatePasswordMutation.isPending ? 'Generieren...' : 'Generieren'}
                </Button>
                <Button
                  onClick={() => setPasswordMutation.mutate(newPassword)}
                  disabled={!canEdit || !passwordMeetsComplexity(newPassword) || setPasswordMutation.isPending}
                  title={passwordMeetsComplexity(newPassword) ? 'Passwort speichern' : 'Komplexität nicht erfüllt'}
                >
                  {setPasswordMutation.isPending ? 'Speichern...' : 'Setzen'}
                </Button>
              </div>
              {/* Komplexitäts-Hinweise: zeigt live welche Anforderungen erfüllt sind */}
              {newPassword.length > 0 && !passwordMeetsComplexity(newPassword) && (
                <PasswordComplexityHint password={newPassword} />
              )}
              {portal?.hasPassword && (
                <>
                  <StoredPasswordDisplay customerId={customerId} />
                  <div className="mt-3">
                    <Button
                      variant="secondary"
                      size="sm"
                      onClick={() => {
                        if (confirm(
                          'Aktuelles Portal-Passwort und Login-URL per E-Mail an den Kunden senden?\n\n' +
                          'Hinweis: Das Passwort wird im Klartext in der E-Mail enthalten sein.'
                        )) {
                          sendCredentialsMutation.mutate();
                        }
                      }}
                      disabled={!canEdit || sendCredentialsMutation.isPending}
                      title="Login-URL + E-Mail + Passwort an die Kunden-E-Mail versenden"
                    >
                      {sendCredentialsMutation.isPending ? 'Sende...' : 'Zugangsdaten per E-Mail versenden'}
                    </Button>
                  </div>
                </>
              )}
            </div>
          )}

          {/* Letzte Anmeldung */}
          {portal?.portalLastLogin && (
            <p className="text-sm text-gray-500">
              Letzte Anmeldung: {new Date(portal.portalLastLogin).toLocaleString('de-DE')}
            </p>
          )}
        </div>
      </div>

      {/* Vertreter-Verwaltung */}
      <div className="border rounded-lg p-4">
        <div className="flex items-center gap-2 mb-4">
          <UserPlus className="w-5 h-5 text-gray-400" />
          <h3 className="font-medium">Vertreter (können Verträge einsehen)</h3>
        </div>

        <p className="text-sm text-gray-500 mb-4">
          Hier können Sie anderen Kunden erlauben, die Verträge dieses Kunden einzusehen.
          Beispiel: Der Sohn kann die Verträge seiner Mutter einsehen.
        </p>

        {/* Vertreter-Suche */}
        {canEdit && (
          <div className="mb-4">
            <div className="flex gap-2">
              <Input
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
                placeholder="Kunden suchen (Name, Kundennummer)..."
                onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
                className="flex-1"
              />
              <Button
                variant="secondary"
                onClick={handleSearch}
                disabled={searchTerm.length < 2 || isSearching}
              >
                <Search className="w-4 h-4" />
              </Button>
            </div>
            <p className="text-xs text-gray-500 mt-1">
              Vertreter ohne Portal-Zugang können bereits hinterlegt werden – der Zugriff
              wird erst wirksam, sobald das Portal aktiviert ist.
            </p>

            {/* Suchergebnisse */}
            {searchResults.length > 0 && (
              <div className="mt-2 border rounded-lg divide-y">
                {searchResults.map((customer) => (
                  <div key={customer.id} className="flex items-center justify-between p-3 hover:bg-gray-50">
                    <div>
                      <p className="font-medium flex items-center gap-2">
                        {customer.companyName || `${customer.firstName} ${customer.lastName}`}
                        {!customer.portalEnabled && (
                          <Badge variant="warning" className="text-xs">
                            Portal inaktiv
                          </Badge>
                        )}
                      </p>
                      <p className="text-sm text-gray-500">{customer.customerNumber}</p>
                    </div>
                    <Button
                      size="sm"
                      onClick={() => addRepMutation.mutate(customer.id)}
                      disabled={addRepMutation.isPending}
                    >
                      <Plus className="w-4 h-4 mr-1" />
                      Hinzufügen
                    </Button>
                  </div>
                ))}
              </div>
            )}
          </div>
        )}

        {/* Aktuelle Vertreter */}
        {representatives.length > 0 ? (
          <div className="space-y-2">
            {representatives.map((rep: CustomerRepresentative) => (
              <div key={rep.id} className="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
                <div>
                  <p className="font-medium flex items-center gap-2">
                    {rep.representative?.companyName ||
                      `${rep.representative?.firstName} ${rep.representative?.lastName}`}
                    {rep.representative && rep.representative.portalEnabled === false && (
                      <Badge variant="warning" className="text-xs">
                        Portal inaktiv
                      </Badge>
                    )}
                  </p>
                  <p className="text-sm text-gray-500">{rep.representative?.customerNumber}</p>
                </div>
                {canEdit && (
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => {
                      if (confirm('Vertreter wirklich entfernen?')) {
                        removeRepMutation.mutate(rep.representativeId);
                      }
                    }}
                  >
                    <X className="w-4 h-4 text-red-500" />
                  </Button>
                )}
              </div>
            ))}
          </div>
        ) : (
          <p className="text-gray-500 text-sm">Keine Vertreter konfiguriert.</p>
        )}
      </div>
    </div>
  );
}

// Modal Components
function AddressModal({
  isOpen,
  onClose,
  customerId,
  address,
}: {
  isOpen: boolean;
  onClose: () => void;
  customerId: number;
  address?: Address | null;
}) {
  const queryClient = useQueryClient();
  const isEditing = !!address;

  const getInitialFormData = () => ({
    type: address?.type || 'DELIVERY_RESIDENCE' as const,
    street: address?.street || '',
    houseNumber: address?.houseNumber || '',
    postalCode: address?.postalCode || '',
    city: address?.city || '',
    country: address?.country || 'Deutschland',
    isDefault: address?.isDefault || false,
    maloIdElectricity: address?.maloIdElectricity || '',
    maloIdGas: address?.maloIdGas || '',
    ownerCompany: address?.ownerCompany || '',
    ownerFirstName: address?.ownerFirstName || '',
    ownerLastName: address?.ownerLastName || '',
    ownerStreet: address?.ownerStreet || '',
    ownerHouseNumber: address?.ownerHouseNumber || '',
    ownerPostalCode: address?.ownerPostalCode || '',
    ownerCity: address?.ownerCity || '',
    ownerPhone: address?.ownerPhone || '',
    ownerMobile: address?.ownerMobile || '',
    ownerEmail: address?.ownerEmail || '',
  });

  const [formData, setFormData] = useState(getInitialFormData);

  const createMutation = useMutation({
    mutationFn: (data: typeof formData) => addressApi.create(customerId, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      onClose();
      setFormData(getInitialFormData());
    },
  });

  const updateMutation = useMutation({
    mutationFn: (data: typeof formData) => addressApi.update(address!.id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      onClose();
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (isEditing) {
      updateMutation.mutate(formData);
    } else {
      createMutation.mutate(formData);
    }
  };

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

  // Beim Öffnen / Wechsel zwischen Adressen aus den Props re-initialisieren.
  // Guard `if (!isOpen)`: Modal bleibt dauerhaft gemountet – ohne Reset beim
  // Öffnen blieben nach „Abbrechen" die vorher getippten Daten stehen.
  // Deps nur isOpen + Adress-ID → kein Reset bei jedem Tastendruck.
  useEffect(() => {
    if (!isOpen) return;
    setFormData(getInitialFormData());
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isOpen, address?.id]);

  return (
    <Modal isOpen={isOpen} onClose={onClose} title={isEditing ? 'Adresse bearbeiten' : 'Adresse hinzufügen'}>
      <form onSubmit={handleSubmit} className="space-y-4">
        <Select
          label="Adresstyp"
          value={formData.type}
          onChange={(e) => setFormData({ ...formData, type: e.target.value as any })}
          options={[
            { value: 'DELIVERY_RESIDENCE', label: 'Liefer-/Meldeadresse' },
            { value: 'BILLING', label: 'Rechnungsadresse' },
          ]}
        />

        <div className="grid grid-cols-3 gap-4">
          <div className="col-span-2">
            <Input
              label="Straße"
              value={formData.street}
              onChange={(e) => setFormData({ ...formData, street: e.target.value })}
              required
            />
          </div>
          <Input
            label="Hausnr."
            value={formData.houseNumber}
            onChange={(e) => setFormData({ ...formData, houseNumber: e.target.value })}
            required
          />
        </div>

        <div className="grid grid-cols-3 gap-4">
          <Input
            label="PLZ"
            value={formData.postalCode}
            onChange={(e) => setFormData({ ...formData, postalCode: e.target.value })}
            required
          />
          <div className="col-span-2">
            <Input
              label="Ort"
              value={formData.city}
              onChange={(e) => setFormData({ ...formData, city: e.target.value })}
              required
            />
          </div>
        </div>

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

        <label className="flex items-center gap-2">
          <input
            type="checkbox"
            checked={formData.isDefault}
            onChange={(e) => setFormData({ ...formData, isDefault: e.target.checked })}
            className="rounded"
          />
          Als Standard setzen
        </label>

        {/* Marktlokations-IDs (nur Lieferadresse) – gehören zur Adresse, nicht
            zum Vertrag; im Vertrag werden sie je Sparte nur noch angezeigt. */}
        {formData.type === 'DELIVERY_RESIDENCE' && (
          <div className="pt-4 border-t">
            <h4 className="text-sm font-medium text-gray-700 mb-1">Marktlokations-IDs (MaLo)</h4>
            <p className="text-xs text-gray-500 mb-3">
              Je Sparte getrennt. Wird im Strom-/Gasvertrag automatisch aus dieser Lieferadresse angezeigt.
            </p>
            <div className="grid grid-cols-2 gap-3">
              <Input
                label="MaLo-ID Strom"
                value={formData.maloIdElectricity}
                onChange={(e) => setFormData({ ...formData, maloIdElectricity: e.target.value })}
                placeholder="z.B. 11XXXXXXXXXXX"
              />
              <Input
                label="MaLo-ID Gas"
                value={formData.maloIdGas}
                onChange={(e) => setFormData({ ...formData, maloIdGas: e.target.value })}
                placeholder="z.B. 11XXXXXXXXXXX"
              />
            </div>
          </div>
        )}

        {/* Eigentümer (optional, nur bei Liefer-/Meldeadresse) */}
        {formData.type === 'DELIVERY_RESIDENCE' && (
        <div className="pt-4 border-t">
          <h4 className="text-sm font-medium text-gray-700 mb-1">Eigentümer</h4>
          <p className="text-xs text-gray-500 mb-3">
            Nur ausfüllen wenn der Kunde nicht selbst Eigentümer ist (z.B. Mietwohnung).
          </p>
          <div className="space-y-3">
            <Input
              label="Firma (optional)"
              value={formData.ownerCompany}
              onChange={(e) => setFormData({ ...formData, ownerCompany: e.target.value })}
              placeholder="z.B. Wohnungsbaugesellschaft"
            />
            <div className="grid grid-cols-2 gap-3">
              <Input
                label="Vorname"
                value={formData.ownerFirstName}
                onChange={(e) => setFormData({ ...formData, ownerFirstName: e.target.value })}
              />
              <Input
                label="Nachname"
                value={formData.ownerLastName}
                onChange={(e) => setFormData({ ...formData, ownerLastName: e.target.value })}
              />
            </div>
            <div className="grid grid-cols-3 gap-3">
              <div className="col-span-2">
                <Input
                  label="Straße"
                  value={formData.ownerStreet}
                  onChange={(e) => setFormData({ ...formData, ownerStreet: e.target.value })}
                />
              </div>
              <Input
                label="Hausnr."
                value={formData.ownerHouseNumber}
                onChange={(e) => setFormData({ ...formData, ownerHouseNumber: e.target.value })}
              />
            </div>
            <div className="grid grid-cols-3 gap-3">
              <Input
                label="PLZ"
                value={formData.ownerPostalCode}
                onChange={(e) => setFormData({ ...formData, ownerPostalCode: e.target.value })}
              />
              <div className="col-span-2">
                <Input
                  label="Ort"
                  value={formData.ownerCity}
                  onChange={(e) => setFormData({ ...formData, ownerCity: e.target.value })}
                />
              </div>
            </div>
            <div className="grid grid-cols-3 gap-3">
              <Input
                label="Telefon"
                value={formData.ownerPhone}
                onChange={(e) => setFormData({ ...formData, ownerPhone: e.target.value })}
              />
              <Input
                label="Mobil"
                value={formData.ownerMobile}
                onChange={(e) => setFormData({ ...formData, ownerMobile: e.target.value })}
              />
              <Input
                label="E-Mail"
                value={formData.ownerEmail}
                onChange={(e) => setFormData({ ...formData, ownerEmail: e.target.value })}
                type="email"
              />
            </div>
          </div>
        </div>
        )}

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

function BankCardModal({
  isOpen,
  onClose,
  customerId,
  bankCard,
}: {
  isOpen: boolean;
  onClose: () => void;
  customerId: number;
  bankCard?: BankCard | null;
}) {
  const queryClient = useQueryClient();
  const isEditing = !!bankCard;

  const getInitialFormData = () => ({
    accountHolder: bankCard?.accountHolder || '',
    iban: bankCard?.iban || '',
    cardNumber: bankCard?.cardNumber || '',
    bic: bankCard?.bic || '',
    bankName: bankCard?.bankName || '',
    expiryDate: bankCard?.expiryDate ? new Date(bankCard.expiryDate).toISOString().split('T')[0] : '',
    description: bankCard?.description || '',
    isActive: bankCard?.isActive ?? true,
  });

  const [formData, setFormData] = useState(getInitialFormData);
  const [ibanLookupLoading, setIbanLookupLoading] = useState(false);
  const [showIbanRequired, setShowIbanRequired] = useState(false);

  // BIC + Bankname aus der IBAN ableiten (offline über Bundesbank-BLZ im
  // Backend). Ist das IBAN-Feld leer, kommt eine OK-Messagebox statt einer
  // Anfrage. Gleichzeitig prüft der Server die IBAN-Prüfziffer (Tippfehler).
  const handleIbanLookup = async () => {
    const iban = formData.iban.replace(/\s+/g, '').trim();
    if (!iban) {
      setShowIbanRequired(true);
      return;
    }
    setIbanLookupLoading(true);
    try {
      const res = await bankCardApi.ibanLookup(iban);
      const d = res.data;
      if (!d) {
        toast.error('IBAN-Prüfung fehlgeschlagen.');
        return;
      }
      if (!d.valid) {
        toast.error('Die IBAN ist ungültig – bitte Eingabe/Prüfziffer kontrollieren.');
        return;
      }
      if (d.bic || d.bankName) {
        setFormData((prev) => ({
          ...prev,
          bic: d.bic || prev.bic,
          bankName: d.bankName || prev.bankName,
        }));
        toast.success('IBAN gültig – BIC und Bank übernommen.');
      } else {
        toast('IBAN ist gültig, aber es wurden keine Bankdaten gefunden (nur deutsche IBANs werden aufgelöst).', {
          icon: 'ℹ️',
        });
      }
    } catch (err: any) {
      toast.error(err?.response?.data?.error || 'Fehler beim IBAN-Nachschlagen.');
    } finally {
      setIbanLookupLoading(false);
    }
  };

  const createMutation = useMutation({
    mutationFn: (data: any) => bankCardApi.create(customerId, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      onClose();
      setFormData({ accountHolder: '', iban: '', cardNumber: '', bic: '', bankName: '', expiryDate: '', description: '', isActive: true });
    },
  });

  const updateMutation = useMutation({
    mutationFn: (data: any) => bankCardApi.update(bankCard!.id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      onClose();
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const data = {
      ...formData,
      expiryDate: formData.expiryDate ? new Date(formData.expiryDate) : undefined,
    };
    if (isEditing) {
      updateMutation.mutate(data);
    } else {
      createMutation.mutate(data);
    }
  };

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

  // Formular zurücksetzen, sobald die Modal geöffnet wird (Neuanlage: leer,
  // Bearbeiten: Kartendaten). Nötig, weil beide Modal-Instanzen dauerhaft
  // gemountet bleiben und nur per isOpen umgeschaltet werden – ohne diesen
  // Reset blieben nach „Abbrechen" die vorher getippten Daten stehen.
  // Läuft NICHT bei jedem Tastendruck (Deps nur isOpen + Karten-ID), sonst
  // würde jede Eingabe wieder auf den DB-Wert zurückspringen.
  useEffect(() => {
    if (!isOpen) return;
    setFormData(getInitialFormData());
    setIbanLookupLoading(false);
    setShowIbanRequired(false);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isOpen, bankCard?.id]);

  return (
    <>
    <Modal isOpen={isOpen} onClose={onClose} title={isEditing ? 'Bankkarte bearbeiten' : 'Bankkarte hinzufügen'}>
      <form onSubmit={handleSubmit} className="space-y-4">
        <Input
          label="Kontoinhaber"
          value={formData.accountHolder}
          onChange={(e) => setFormData({ ...formData, accountHolder: e.target.value })}
          required
        />

        <div>
          <Input
            label="IBAN"
            value={formData.iban}
            onChange={(e) => setFormData({ ...formData, iban: e.target.value })}
            required
          />
          <div className="flex justify-end mt-1.5">
            <button
              type="button"
              onClick={handleIbanLookup}
              disabled={ibanLookupLoading}
              className="inline-flex items-center gap-1.5 text-sm font-medium text-blue-600 hover:text-blue-800 disabled:opacity-50 disabled:cursor-not-allowed"
              title="Prüft die IBAN und füllt BIC + Bank aus (offline, Bundesbank-Bankleitzahlen)"
            >
              {ibanLookupLoading ? (
                <RefreshCw className="w-4 h-4 animate-spin" />
              ) : (
                <Search className="w-4 h-4" />
              )}
              BIC &amp; Bank aus IBAN abrufen
            </button>
          </div>
        </div>

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

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

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

        <Input
          label="Ablaufdatum"
          type="date"
          value={formData.expiryDate}
          onChange={(e) => setFormData({ ...formData, expiryDate: e.target.value })}
          onClear={() => setFormData({ ...formData, expiryDate: '' })}
        />

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">Beschreibung</label>
          <textarea
            value={formData.description}
            onChange={(e) => setFormData({ ...formData, description: e.target.value })}
            rows={2}
            placeholder="z.B. Geschäftskonto, gemeinsames Konto mit Partner…"
            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"
          />
        </div>

        {isEditing && (
          <label className="flex items-center gap-2">
            <input
              type="checkbox"
              checked={formData.isActive}
              onChange={(e) => setFormData({ ...formData, isActive: e.target.checked })}
              className="rounded"
            />
            Aktiv
          </label>
        )}

        {!isEditing && (
          <p className="text-sm text-gray-500 bg-gray-50 p-3 rounded">
            Dokument-Upload ist nach dem Speichern in der Übersicht möglich.
          </p>
        )}

        <div className="flex justify-end gap-2">
          <Button type="button" variant="secondary" onClick={onClose}>
            Abbrechen
          </Button>
          <Button type="submit" disabled={isPending}>
            {isPending ? 'Speichern...' : 'Speichern'}
          </Button>
        </div>
      </form>
    </Modal>

    {showIbanRequired && (
      <Modal isOpen onClose={() => setShowIbanRequired(false)} title="IBAN erforderlich" size="sm">
        <div className="space-y-4">
          <p className="text-sm text-gray-700">
            Bitte trage zuerst eine IBAN im Feld „IBAN“ ein. BIC und Bank werden daraus ermittelt.
          </p>
          <div className="flex justify-end">
            <Button onClick={() => setShowIbanRequired(false)}>OK</Button>
          </div>
        </div>
      </Modal>
    )}
    </>
  );
}

function DocumentModal({
  isOpen,
  onClose,
  customerId,
  document,
}: {
  isOpen: boolean;
  onClose: () => void;
  customerId: number;
  document?: IdentityDocument | null;
}) {
  const queryClient = useQueryClient();
  const isEditing = !!document;

  const getInitialFormData = () => ({
    type: document?.type || 'ID_CARD' as const,
    documentNumber: document?.documentNumber || '',
    issuingAuthority: document?.issuingAuthority || '',
    issueDate: document?.issueDate ? new Date(document.issueDate).toISOString().split('T')[0] : '',
    expiryDate: document?.expiryDate ? new Date(document.expiryDate).toISOString().split('T')[0] : '',
    isActive: document?.isActive ?? true,
    licenseClasses: document?.licenseClasses || '',
    licenseIssueDate: document?.licenseIssueDate ? new Date(document.licenseIssueDate).toISOString().split('T')[0] : '',
  });

  const [formData, setFormData] = useState(getInitialFormData);

  const createMutation = useMutation({
    mutationFn: (data: any) => documentApi.create(customerId, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      onClose();
      setFormData({
        type: 'ID_CARD',
        documentNumber: '',
        issuingAuthority: '',
        issueDate: '',
        expiryDate: '',
        isActive: true,
        licenseClasses: '',
        licenseIssueDate: '',
      });
    },
  });

  const updateMutation = useMutation({
    mutationFn: (data: any) => documentApi.update(document!.id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      onClose();
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const data: any = {
      ...formData,
      issueDate: formData.issueDate ? new Date(formData.issueDate) : undefined,
      expiryDate: formData.expiryDate ? new Date(formData.expiryDate) : undefined,
    };
    // Führerschein-spezifische Felder nur bei Führerschein senden
    if (formData.type === 'DRIVERS_LICENSE') {
      data.licenseClasses = formData.licenseClasses || undefined;
      data.licenseIssueDate = formData.licenseIssueDate ? new Date(formData.licenseIssueDate) : undefined;
    } else {
      delete data.licenseClasses;
      delete data.licenseIssueDate;
    }
    if (isEditing) {
      updateMutation.mutate(data);
    } else {
      createMutation.mutate(data);
    }
  };

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

  // Reset beim Öffnen (Guard `if (!isOpen)`): Modal bleibt gemountet, sonst
  // blieben nach „Abbrechen" die vorher getippten Daten stehen. Deps nur
  // isOpen + Ausweis-ID → kein Reset bei jedem Tastendruck.
  useEffect(() => {
    if (!isOpen) return;
    setFormData(getInitialFormData());
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isOpen, document?.id]);

  return (
    <Modal isOpen={isOpen} onClose={onClose} title={isEditing ? 'Ausweis bearbeiten' : 'Ausweis hinzufügen'}>
      <form onSubmit={handleSubmit} className="space-y-4">
        <Select
          label="Ausweistyp"
          value={formData.type}
          onChange={(e) => setFormData({ ...formData, type: e.target.value as any })}
          options={[
            { value: 'ID_CARD', label: 'Personalausweis' },
            { value: 'PASSPORT', label: 'Reisepass' },
            { value: 'DRIVERS_LICENSE', label: 'Führerschein' },
            { value: 'OTHER', label: 'Sonstiges' },
          ]}
        />

        <Input
          label="Ausweisnummer"
          value={formData.documentNumber}
          onChange={(e) => setFormData({ ...formData, documentNumber: e.target.value })}
          required
        />

        <Input
          label="Ausstellende Behörde"
          value={formData.issuingAuthority}
          onChange={(e) => setFormData({ ...formData, issuingAuthority: e.target.value })}
        />

        <div className="grid grid-cols-2 gap-4">
          <Input
            label="Ausstellungsdatum"
            type="date"
            value={formData.issueDate}
            onChange={(e) => setFormData({ ...formData, issueDate: e.target.value })}
            onClear={() => setFormData({ ...formData, issueDate: '' })}
          />

          <Input
            label="Ablaufdatum"
            type="date"
            value={formData.expiryDate}
            onChange={(e) => setFormData({ ...formData, expiryDate: e.target.value })}
            onClear={() => setFormData({ ...formData, expiryDate: '' })}
          />
        </div>

        {formData.type === 'DRIVERS_LICENSE' && (
          <>
            <Input
              label="Führerscheinklassen"
              value={formData.licenseClasses}
              onChange={(e) => setFormData({ ...formData, licenseClasses: e.target.value })}
              placeholder="z.B. B, BE, AM, L"
            />

            <Input
              label="Erwerb Klasse B (Pkw)"
              type="date"
              value={formData.licenseIssueDate}
              onChange={(e) => setFormData({ ...formData, licenseIssueDate: e.target.value })}
              onClear={() => setFormData({ ...formData, licenseIssueDate: '' })}
            />
          </>
        )}

        {isEditing && (
          <label className="flex items-center gap-2">
            <input
              type="checkbox"
              checked={formData.isActive}
              onChange={(e) => setFormData({ ...formData, isActive: e.target.checked })}
              className="rounded"
            />
            Aktiv
          </label>
        )}

        {!isEditing && (
          <p className="text-sm text-gray-500 bg-gray-50 p-3 rounded">
            Dokument-Upload ist nach dem Speichern in der Übersicht möglich.
          </p>
        )}

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

function MeterModal({
  isOpen,
  onClose,
  customerId,
  meter,
  addresses,
  existingMeters,
}: {
  isOpen: boolean;
  onClose: () => void;
  customerId: number;
  meter?: Meter | null;
  addresses: Address[];
  existingMeters: Meter[];
}) {
  const queryClient = useQueryClient();
  const isEditing = !!meter;
  const deliveryAddresses = addresses.filter((a) => a.type === 'DELIVERY_RESIDENCE');
  const today = new Date().toISOString().split('T')[0];

  const getInitialFormData = () => ({
    meterNumber: meter?.meterNumber || '',
    type: meter?.type || 'ELECTRICITY' as const,
    tariffModel: meter?.tariffModel || 'SINGLE' as const,
    location: meter?.location || '',
    isActive: meter?.isActive ?? true,
    addressId: meter?.addressId?.toString() || '',
    isSuccessor: false,
    predecessorMeterId: '',
    installedAt: today,
    finalReadingPrevious: '',
    deactivatePredecessor: true,
  });

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

  const predecessor = formData.predecessorMeterId
    ? existingMeters.find((m) => m.id.toString() === formData.predecessorMeterId)
    : null;

  // Wenn Vorgänger gewählt: Typ + Adresse + Tarifmodell vom Vorgänger übernehmen
  useEffect(() => {
    if (!formData.isSuccessor || !predecessor) return;
    setFormData((prev) => ({
      ...prev,
      type: predecessor.type,
      tariffModel: predecessor.tariffModel,
      addressId: predecessor.addressId ? predecessor.addressId.toString() : prev.addressId,
    }));
  }, [formData.isSuccessor, formData.predecessorMeterId, predecessor?.id]);

  const createMutation = useMutation({
    mutationFn: (data: any) => meterApi.create(customerId, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      onClose();
      setFormData(getInitialFormData());
    },
    onError: (err) => setError(err instanceof Error ? err.message : 'Fehler beim Speichern'),
  });

  const updateMutation = useMutation({
    mutationFn: (data: any) => meterApi.update(meter!.id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      onClose();
    },
    onError: (err) => setError(err instanceof Error ? err.message : 'Fehler beim Speichern'),
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    setError(null);
    if (!formData.addressId) {
      setError('Bitte eine Lieferadresse auswählen');
      return;
    }
    if (formData.isSuccessor && !formData.predecessorMeterId) {
      setError('Bitte einen Vorgänger-Zähler auswählen');
      return;
    }
    const payload: any = {
      meterNumber: formData.meterNumber,
      type: formData.type,
      tariffModel: formData.tariffModel,
      location: formData.location,
      isActive: formData.isActive,
      addressId: parseInt(formData.addressId),
    };
    if (!isEditing && formData.isSuccessor && formData.predecessorMeterId) {
      payload.successorOf = {
        predecessorMeterId: parseInt(formData.predecessorMeterId),
        installedAt: formData.installedAt || undefined,
        finalReadingPrevious: formData.finalReadingPrevious
          ? parseFloat(formData.finalReadingPrevious)
          : undefined,
        deactivatePredecessor: formData.deactivatePredecessor,
      };
    }
    if (isEditing) {
      updateMutation.mutate(payload);
    } else {
      createMutation.mutate(payload);
    }
  };

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

  // Reset beim Öffnen (Guard `if (!isOpen)`): Modal bleibt gemountet, sonst
  // blieben nach „Abbrechen" die vorher getippten Daten stehen. Deps nur
  // isOpen + Zähler-ID → kein Reset bei jedem Tastendruck.
  useEffect(() => {
    if (!isOpen) return;
    setFormData(getInitialFormData());
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isOpen, meter?.id]);

  const noDeliveryAddresses = deliveryAddresses.length === 0;
  const successorLocked = !isEditing && formData.isSuccessor && !!predecessor;

  return (
    <Modal isOpen={isOpen} onClose={onClose} title={isEditing ? 'Zähler bearbeiten' : 'Zähler hinzufügen'}>
      <form onSubmit={handleSubmit} className="space-y-4">
        {noDeliveryAddresses && (
          <div className="p-3 bg-yellow-50 border border-yellow-200 rounded-lg text-sm text-yellow-800">
            <strong>Keine Lieferadresse vorhanden.</strong> Bitte zunächst im Tab „Adressen" eine
            Lieferadresse anlegen, bevor ein Zähler erstellt werden kann.
          </div>
        )}

        <Select
          label="Lieferadresse"
          value={formData.addressId}
          onChange={(e) => setFormData({ ...formData, addressId: e.target.value })}
          options={deliveryAddresses.map((a) => ({
            value: a.id,
            label: `${a.street} ${a.houseNumber}, ${a.postalCode} ${a.city}`,
          }))}
          placeholder="Lieferadresse wählen..."
          required
          disabled={successorLocked && !!predecessor?.addressId}
        />

        <Input
          label="Zählernummer"
          value={formData.meterNumber}
          onChange={(e) => setFormData({ ...formData, meterNumber: e.target.value })}
          required
        />

        <Select
          label="Zählertyp"
          value={formData.type}
          onChange={(e) => setFormData({ ...formData, type: e.target.value as any })}
          options={[
            { value: 'ELECTRICITY', label: 'Strom' },
            { value: 'GAS', label: 'Gas' },
          ]}
          disabled={successorLocked}
        />

        {formData.type === 'ELECTRICITY' && (
          <Select
            label="Tarifmodell"
            value={formData.tariffModel}
            onChange={(e) => setFormData({ ...formData, tariffModel: e.target.value as any })}
            options={[
              { value: 'SINGLE', label: 'Eintarifzähler (Standard)' },
              { value: 'DUAL', label: 'Zweitarifzähler (HT/NT)' },
            ]}
            disabled={successorLocked}
          />
        )}

        <Input
          label="Standort"
          value={formData.location}
          onChange={(e) => setFormData({ ...formData, location: e.target.value })}
          placeholder="z.B. Keller, Wohnung"
        />

        {!isEditing && existingMeters.length > 0 && (
          <div className="border-t pt-4">
            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                checked={formData.isSuccessor}
                onChange={(e) => setFormData({ ...formData, isSuccessor: e.target.checked })}
                className="rounded"
              />
              <span className="text-sm font-medium">Diesen Zähler als Folgezähler deklarieren</span>
            </label>

            {formData.isSuccessor && (
              <div className="mt-3 ml-6 space-y-3 bg-blue-50 border border-blue-200 rounded-lg p-3">
                <Select
                  label="Vorgänger-Zähler *"
                  value={formData.predecessorMeterId}
                  onChange={(e) => setFormData({ ...formData, predecessorMeterId: e.target.value })}
                  options={existingMeters.map((m) => ({
                    value: m.id,
                    label: `${m.meterNumber} (${m.type === 'ELECTRICITY' ? 'Strom' : 'Gas'})${m.location ? ` – ${m.location}` : ''}${!m.isActive ? ' – deaktiviert' : ''}`,
                  }))}
                  placeholder="Bitte wählen..."
                />
                <Input
                  label="Wechseldatum"
                  type="date"
                  value={formData.installedAt}
                  onChange={(e) => setFormData({ ...formData, installedAt: e.target.value })}
                />
                <Input
                  label="Endstand alter Zähler (optional)"
                  type="number"
                  step="0.01"
                  value={formData.finalReadingPrevious}
                  onChange={(e) => setFormData({ ...formData, finalReadingPrevious: e.target.value })}
                  placeholder="Optional"
                />
                <label className="flex items-center gap-2 text-sm">
                  <input
                    type="checkbox"
                    checked={formData.deactivatePredecessor}
                    onChange={(e) => setFormData({ ...formData, deactivatePredecessor: e.target.checked })}
                    className="rounded"
                  />
                  Alten Zähler deaktivieren
                </label>
                <p className="text-xs text-blue-700">
                  Typ, Adresse und Tarifmodell werden vom Vorgänger übernommen. Alle Verträge,
                  die den Vorgänger-Zähler verwenden, werden automatisch auf diesen neuen Zähler
                  umgestellt. Der Endstand wird als Zählerstand des alten Zählers zum Wechseldatum
                  erfasst und fließt damit in die Verbrauchsberechnung ein.
                </p>
              </div>
            )}
          </div>
        )}

        {isEditing && (
          <label className="flex items-center gap-2">
            <input
              type="checkbox"
              checked={formData.isActive}
              onChange={(e) => setFormData({ ...formData, isActive: e.target.checked })}
              className="rounded"
            />
            Aktiv
          </label>
        )}

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

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

function MeterReadingModal({
  isOpen,
  onClose,
  meterId,
  meterType,
  tariffModel,
  customerId,
  reading,
}: {
  isOpen: boolean;
  onClose: () => void;
  meterId: number;
  meterType: 'ELECTRICITY' | 'GAS';
  tariffModel?: 'SINGLE' | 'DUAL';
  customerId: number;
  reading?: { id: number; readingDate: string; value: number; valueNt?: number; unit: string; notes?: string } | null;
}) {
  const queryClient = useQueryClient();
  const isEditing = !!reading;
  const defaultUnit = meterType === 'ELECTRICITY' ? 'kWh' : 'm³';
  const isDualTariff = tariffModel === 'DUAL';

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

  const [formData, setFormData] = useState(getInitialFormData);

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

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

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

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

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

  // Reset beim Öffnen (Guard `if (!isOpen)`): Modal bleibt gemountet, sonst
  // blieben nach „Abbrechen" die vorher getippten Daten stehen. Deps nur
  // isOpen + Zählerstand-ID → kein Reset bei jedem Tastendruck.
  useEffect(() => {
    if (!isOpen) return;
    setFormData(getInitialFormData());
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isOpen, reading?.id]);

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

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

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

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

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

// ==================== KUNDEN-E-MAIL TAB ====================

function StressfreiEmailsTab({
  customerId,
  emails,
  canEdit,
  showInactive,
  onToggleInactive,
  onAdd,
  onEdit,
}: {
  customerId: number;
  emails: StressfreiEmail[];
  canEdit: boolean;
  showInactive: boolean;
  onToggleInactive: () => void;
  onAdd: () => void;
  onEdit: (email: StressfreiEmail) => void;
}) {
  const queryClient = useQueryClient();
  const { customerEmailLabel } = useProviderSettings();

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<StressfreiEmail> }) =>
      stressfreiEmailApi.update(id, data),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['customer', customerId] }),
  });

  const deleteMutation = useMutation({
    mutationFn: stressfreiEmailApi.delete,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['customer', customerId] }),
  });

  // Weiterleitungen am Provider neu setzen (Stamm-Email-Wechsel-Use-Case).
  // Wenn die Adresse hasMailbox=true ist, wird zusätzlich das im CRM
  // hinterlegte Passwort am Provider neu gesetzt (Self-Healing nach
  // manuellen Eingriffen am Provider).
  const syncForwardingMutation = useMutation({
    mutationFn: stressfreiEmailApi.syncForwarding,
    onSuccess: (res) => {
      const targets = res?.data?.forwardTargets || [];
      const passwordReset = res?.data?.passwordReset;
      const lines = [
        'Weiterleitungen aktualisiert:',
        ...targets.map((t) => `• ${t}`),
      ];
      if (passwordReset) lines.push('Mailbox-Passwort am Provider neu gesetzt.');
      toast.success(lines.join('\n'), { duration: 5000 });
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
    },
    onError: (err: any) => {
      toast.error(
        err?.response?.data?.error || err?.message || 'Fehler beim Aktualisieren der Weiterleitungen',
        { duration: 6000 },
      );
    },
  });

  const filtered = showInactive ? emails : emails.filter((e) => e.isActive);

  return (
    <div>
      <div className="flex items-center gap-4 mb-4">
        {canEdit && (
          <Button size="sm" onClick={onAdd}>
            <Plus className="w-4 h-4 mr-2" />
            Adresse hinzufügen
          </Button>
        )}
        <label className="flex items-center gap-2 text-sm">
          <input
            type="checkbox"
            checked={showInactive}
            onChange={onToggleInactive}
            className="rounded"
          />
          Inaktive anzeigen
        </label>
      </div>

      <p className="text-sm text-gray-500 mb-4 bg-blue-50 border border-blue-200 rounded-lg p-3">
        <strong>Hinweis:</strong> Hier werden E-Mail-Weiterleitungsadressen verwaltet, die für die Registrierung bei Anbietern verwendet werden.
        E-Mails an diese Adressen werden sowohl an den Kunden als auch an Sie weitergeleitet.
      </p>

      {filtered.length > 0 ? (
        <div className="space-y-3">
          {filtered.map((emailItem) => (
            <div
              key={emailItem.id}
              className={`border rounded-lg p-4 ${!emailItem.isActive ? 'opacity-50 bg-gray-50' : ''}`}
            >
              <div className="flex items-start justify-between">
                <div className="flex-1">
                  <div className="flex items-center gap-2">
                    <Mail className="w-4 h-4 text-gray-400" />
                    <span className="font-mono text-sm">{emailItem.email}</span>
                    <CopyButton value={emailItem.email} />
                    {!emailItem.isActive && <Badge variant="danger">Inaktiv</Badge>}
                  </div>
                  {emailItem.notes && (
                    <div className="flex items-center gap-2 mt-1 text-sm text-gray-500">
                      <FileText className="w-4 h-4 flex-shrink-0" />
                      <span>{emailItem.notes}</span>
                    </div>
                  )}
                </div>
                {canEdit && (
                  <div className="flex gap-1">
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => onEdit(emailItem)}
                      title="Bearbeiten"
                    >
                      <Edit className="w-4 h-4" />
                    </Button>
                    {emailItem.isProvisioned && (
                      <Button
                        variant="ghost"
                        size="sm"
                        disabled={syncForwardingMutation.isPending}
                        onClick={() => {
                          const lines = [
                            `Weiterleitungen für ${emailItem.email} jetzt neu setzen?`,
                            '',
                            'Alle bestehenden Weiterleitungen am Provider werden ersetzt durch:',
                            '• die aktuelle Stamm-E-Mail des Kunden',
                            '• unsere Service-Weiterleitungsadresse aus den Provider-Einstellungen',
                          ];
                          if (emailItem.hasMailbox) {
                            lines.push(
                              '',
                              'Zusätzlich wird das im CRM hinterlegte Mailbox-Passwort am Provider neu gesetzt.',
                            );
                          }
                          if (confirm(lines.join('\n'))) {
                            syncForwardingMutation.mutate(emailItem.id);
                          }
                        }}
                        title={
                          emailItem.hasMailbox
                            ? 'Weiterleitungen + Mailbox-Passwort synchronisieren. Nützlich nach Änderung der Kunden-Stamm-E-Mail oder nach manuellem Eingriff am Provider.'
                            : 'Weiterleitungen synchronisieren – ersetzt die Forwards am Provider durch (Kunden-Stamm-E-Mail + Service-Adresse). Nützlich nach Änderung der Stamm-E-Mail.'
                        }
                      >
                        <RefreshCw
                          className={`w-4 h-4 ${syncForwardingMutation.isPending ? 'animate-spin' : ''}`}
                        />
                      </Button>
                    )}
                    {emailItem.isActive ? (
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => {
                          if (confirm('Adresse deaktivieren?')) {
                            updateMutation.mutate({ id: emailItem.id, data: { isActive: false } });
                          }
                        }}
                        title="Deaktivieren"
                      >
                        <EyeOff className="w-4 h-4" />
                      </Button>
                    ) : (
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => {
                          if (confirm('Adresse wieder aktivieren?')) {
                            updateMutation.mutate({ id: emailItem.id, data: { isActive: true } });
                          }
                        }}
                        title="Aktivieren"
                      >
                        <Eye className="w-4 h-4" />
                      </Button>
                    )}
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => {
                        if (confirm('Adresse wirklich löschen?')) {
                          deleteMutation.mutate(emailItem.id);
                        }
                      }}
                      title="Löschen"
                    >
                      <Trash2 className="w-4 h-4 text-red-500" />
                    </Button>
                  </div>
                )}
              </div>
            </div>
          ))}
        </div>
      ) : (
        <p className="text-gray-500">Keine {customerEmailLabel} Adressen vorhanden.</p>
      )}
    </div>
  );
}

// ==================== CREDENTIALS DISPLAY ====================

function CredentialsDisplay({
  credentials,
  onHide,
  onResetPassword,
  isResettingPassword,
}: {
  credentials: {
    email: string;
    password: string;
    imap: { server: string; port: number; encryption: string } | null;
    smtp: { server: string; port: number; encryption: string } | null;
  };
  onHide: () => void;
  onResetPassword: () => void;
  isResettingPassword: boolean;
}) {
  const [copiedField, setCopiedField] = useState<string | null>(null);

  const copyToClipboard = async (text: string, fieldName: string) => {
    try {
      await navigator.clipboard.writeText(text);
      setCopiedField(fieldName);
      setTimeout(() => setCopiedField(null), 2000);
    } catch {
      // Fallback für ältere Browser
      const textArea = document.createElement('textarea');
      textArea.value = text;
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand('copy');
      document.body.removeChild(textArea);
      setCopiedField(fieldName);
      setTimeout(() => setCopiedField(null), 2000);
    }
  };

  const CopyButton = ({ text, fieldName }: { text: string; fieldName: string }) => (
    <button
      type="button"
      onClick={() => copyToClipboard(text, fieldName)}
      className="p-1.5 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded transition-colors"
      title="In Zwischenablage kopieren"
    >
      {copiedField === fieldName ? (
        <Check className="w-4 h-4 text-green-600" />
      ) : (
        <Copy className="w-4 h-4" />
      )}
    </button>
  );

  const imapString = credentials.imap
    ? `${credentials.imap.server}:${credentials.imap.port}`
    : '';
  const smtpString = credentials.smtp
    ? `${credentials.smtp.server}:${credentials.smtp.port}`
    : '';

  return (
    <div className="bg-gray-50 border border-gray-200 rounded-lg p-4 space-y-3">
      <div className="flex justify-between items-center">
        <span className="text-xs font-semibold text-gray-500 uppercase tracking-wide">
          Zugangsdaten
        </span>
        <button
          type="button"
          onClick={onHide}
          className="text-gray-400 hover:text-gray-600 p-1 hover:bg-gray-200 rounded"
          title="Zugangsdaten ausblenden"
        >
          <EyeOff className="w-4 h-4" />
        </button>
      </div>

      {/* Benutzername & Passwort */}
      <div className="grid grid-cols-2 gap-3">
        <div className="bg-white rounded-lg p-3 border border-gray-100">
          <label className="text-xs text-gray-500 block mb-1">Benutzername</label>
          <div className="flex items-center gap-2">
            <code className="text-sm text-gray-900 font-mono flex-1 break-all">
              {credentials.email}
            </code>
            <CopyButton text={credentials.email} fieldName="email" />
          </div>
        </div>
        <div className="bg-white rounded-lg p-3 border border-gray-100">
          <label className="text-xs text-gray-500 block mb-1">Passwort</label>
          <div className="flex items-center gap-2">
            <code className="text-sm text-gray-900 font-mono flex-1 break-all">
              {credentials.password}
            </code>
            <CopyButton text={credentials.password} fieldName="password" />
          </div>
          <button
            type="button"
            onClick={onResetPassword}
            disabled={isResettingPassword}
            className="mt-2 text-xs text-blue-600 hover:text-blue-800 disabled:opacity-50"
          >
            {isResettingPassword ? 'Generiere...' : 'Neu generieren'}
          </button>
        </div>
      </div>

      {/* Server-Einstellungen */}
      <div className="grid grid-cols-2 gap-3">
        {credentials.imap && (
          <div className="bg-white rounded-lg p-3 border border-gray-100">
            <label className="text-xs text-gray-500 block mb-1">
              IMAP (Empfang)
            </label>
            <div className="flex items-center gap-2">
              <code className="text-sm text-gray-900 font-mono flex-1">
                {imapString}
              </code>
              <CopyButton text={imapString} fieldName="imap" />
            </div>
            <span className="text-xs text-gray-400 mt-1 block">
              {credentials.imap.encryption}
            </span>
          </div>
        )}
        {credentials.smtp && (
          <div className="bg-white rounded-lg p-3 border border-gray-100">
            <label className="text-xs text-gray-500 block mb-1">
              SMTP (Versand)
            </label>
            <div className="flex items-center gap-2">
              <code className="text-sm text-gray-900 font-mono flex-1">
                {smtpString}
              </code>
              <CopyButton text={smtpString} fieldName="smtp" />
            </div>
            <span className="text-xs text-gray-400 mt-1 block">
              {credentials.smtp.encryption}
            </span>
          </div>
        )}
      </div>
    </div>
  );
}

// ==================== STRESSFREI-EMAIL MODAL ====================

function StressfreiEmailModal({
  isOpen,
  onClose,
  customerId,
  email,
  customerEmail,
}: {
  isOpen: boolean;
  onClose: () => void;
  customerId: number;
  email?: StressfreiEmail | null;
  customerEmail?: string;
}) {
  const [localPart, setLocalPart] = useState('');
  const [notes, setNotes] = useState('');
  const [provisionAtProvider, setProvisionAtProvider] = useState(false);
  const [createMailbox, setCreateMailbox] = useState(false);
  const [provisionError, setProvisionError] = useState<string | null>(null);
  const [providerStatus, setProviderStatus] = useState<'idle' | 'checking' | 'exists' | 'not_exists' | 'error'>('idle');
  const [isProvisioning, setIsProvisioning] = useState(false);

  // Domain dynamisch vom Provider (mit Fallback)
  const { domain: providerDomain } = useProviderSettings();
  const domainSuffix = `@${providerDomain || 'stressfrei-wechseln.de'}`;
  const [isEnablingMailbox, setIsEnablingMailbox] = useState(false);
  const [mailboxEnabled, setMailboxEnabled] = useState(false);
  const [showCredentials, setShowCredentials] = useState(false);
  const [credentials, setCredentials] = useState<{
    email: string;
    password: string;
    imap: { server: string; port: number; encryption: string } | null;
    smtp: { server: string; port: number; encryption: string } | null;
  } | null>(null);
  const [isLoadingCredentials, setIsLoadingCredentials] = useState(false);
  const [isResettingPassword, setIsResettingPassword] = useState(false);
  const [showForwardsModal, setShowForwardsModal] = useState(false);
  const [additionalForwards, setAdditionalForwards] = useState<string[]>([]);
  const queryClient = useQueryClient();
  const isEditing = !!email;

  // Prüfe ob ein Provider konfiguriert ist
  const { data: configsData } = useQuery({
    queryKey: ['email-provider-configs'],
    queryFn: () => emailProviderApi.getConfigs(),
    enabled: isOpen, // Immer laden wenn Modal offen
  });
  const hasProvider = (configsData?.data || []).some(c => c.isActive && c.isDefault);

  // Helper: Extrahiert den lokalen Teil einer E-Mail-Adresse (vor dem @)
  const extractLocalPart = (fullEmail: string) => {
    if (!fullEmail) return '';
    const atIndex = fullEmail.indexOf('@');
    return atIndex > 0 ? fullEmail.substring(0, atIndex) : fullEmail;
  };

  // Prüft ob E-Mail beim Provider existiert
  const checkProviderStatus = async (emailLocalPart: string) => {
    if (!hasProvider || !emailLocalPart) return;
    setProviderStatus('checking');
    try {
      const result = await emailProviderApi.checkEmailExists(emailLocalPart);
      setProviderStatus(result.data?.exists ? 'exists' : 'not_exists');
    } catch {
      setProviderStatus('error');
    }
  };

  // E-Mail nachträglich beim Provider anlegen
  const handleProvisionNow = async () => {
    if (!customerEmail || !localPart) return;
    setIsProvisioning(true);
    setProvisionError(null);
    try {
      const result = await emailProviderApi.provisionEmail(localPart, customerEmail);
      if (result.data?.success) {
        setProviderStatus('exists');
      } else {
        setProvisionError(result.data?.error || 'Provisionierung fehlgeschlagen');
      }
    } catch (error) {
      setProvisionError(error instanceof Error ? error.message : 'Fehler bei der Provisionierung');
    } finally {
      setIsProvisioning(false);
    }
  };

  // Mailbox nachträglich aktivieren
  const handleEnableMailbox = async () => {
    if (!email) return;
    setIsEnablingMailbox(true);
    setProvisionError(null);
    try {
      const result = await stressfreiEmailApi.enableMailbox(email.id);
      if (result.success) {
        setMailboxEnabled(true);
        queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
        queryClient.invalidateQueries({ queryKey: ['mailbox-accounts', customerId] });
      } else {
        setProvisionError(result.error || 'Mailbox-Aktivierung fehlgeschlagen');
      }
    } catch (error) {
      setProvisionError(error instanceof Error ? error.message : 'Fehler bei der Mailbox-Aktivierung');
    } finally {
      setIsEnablingMailbox(false);
    }
  };

  // Mailbox-Status mit Provider synchronisieren
  const syncMailboxStatusFromProvider = async () => {
    if (!email) return;
    try {
      const result = await stressfreiEmailApi.syncMailboxStatus(email.id);
      if (result.success && result.data) {
        setMailboxEnabled(result.data.hasMailbox);
        if (result.data.wasUpdated) {
          // DB wurde aktualisiert, Query invalidieren
          queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
        }
      }
    } catch (error) {
      console.error('Fehler beim Synchronisieren des Mailbox-Status:', error);
    }
  };

  // Mailbox-Zugangsdaten laden
  const loadCredentials = async () => {
    if (!email) return;
    setIsLoadingCredentials(true);
    try {
      const result = await stressfreiEmailApi.getMailboxCredentials(email.id);
      if (result.success && result.data) {
        setCredentials(result.data);
        setShowCredentials(true);
      }
    } catch (error) {
      console.error('Fehler beim Laden der Zugangsdaten:', error);
    } finally {
      setIsLoadingCredentials(false);
    }
  };

  // Passwort zurücksetzen
  const handleResetPassword = async () => {
    if (!email) return;
    if (!confirm('Neues Passwort generieren? Das alte Passwort wird ungültig.')) return;

    setIsResettingPassword(true);
    try {
      const result = await stressfreiEmailApi.resetPassword(email.id);
      if (result.success && result.data) {
        // Credentials mit neuem Passwort aktualisieren
        if (credentials) {
          setCredentials({ ...credentials, password: result.data.password });
        }
        alert('Passwort wurde erfolgreich zurückgesetzt.');
      } else {
        alert(result.error || 'Fehler beim Zurücksetzen des Passworts');
      }
    } catch (error) {
      console.error('Fehler beim Zurücksetzen des Passworts:', error);
      alert(error instanceof Error ? error.message : 'Fehler beim Zurücksetzen des Passworts');
    } finally {
      setIsResettingPassword(false);
    }
  };

  // Reset form when modal opens or email changes
  useEffect(() => {
    if (isOpen) {
      if (email) {
        const emailLocalPart = extractLocalPart(email.email);
        setLocalPart(emailLocalPart);
        setNotes(email.notes || '');
        setProviderStatus('idle');
        setMailboxEnabled(email.hasMailbox || false);
        // Aktuelle Zusatz-Weiterleitungen aus dem JSON-Feld parsen.
        let parsed: string[] = [];
        if (email.additionalForwardingEmails) {
          try {
            const x = JSON.parse(email.additionalForwardingEmails);
            if (Array.isArray(x)) parsed = x.filter((s): s is string => typeof s === 'string');
          } catch {/* fällt auf [] zurück */}
        }
        setAdditionalForwards(parsed);
        // Status beim Provider prüfen wenn Provider vorhanden
        if (hasProvider) {
          checkProviderStatus(emailLocalPart);
          // Mailbox-Status synchronisieren
          syncMailboxStatusFromProvider();
        }
      } else {
        setLocalPart('');
        setNotes('');
        setProvisionAtProvider(false);
        setCreateMailbox(false);
        setProviderStatus('idle');
        setMailboxEnabled(false);
        setAdditionalForwards([]);
      }
      setProvisionError(null);
      // Zugangsdaten zurücksetzen
      setShowCredentials(false);
      setCredentials(null);
    }
  }, [isOpen, email, hasProvider]);

  const createMutation = useMutation({
    mutationFn: async (data: { email: string; notes?: string; provision?: boolean; createMailbox?: boolean }) => {
      // Verwendet die neue API-Funktion, die Provisioning und Mailbox-Erstellung unterstützt
      const result = await stressfreiEmailApi.create(customerId, {
        email: data.email,
        notes: data.notes,
        provisionAtProvider: data.provision,
        createMailbox: data.createMailbox,
      });
      // Wenn der User zusätzliche Weiterleitungen im Sub-Modal gepflegt
      // hat: nach der Erstellung gleich am Provider nachziehen. Das
      // sorgt für einen `set:`-Sync mit der vollen Liste, kein
      // Edit-Modus-Roundtrip nötig.
      if (data.provision && additionalForwards.length > 0 && result.data?.id) {
        try {
          await stressfreiEmailApi.updateAdditionalForwards(result.data.id, additionalForwards);
        } catch (e) {
          console.error('Zusatz-Weiterleitungen konnten nicht gesetzt werden:', e);
          // Adresse selbst wurde angelegt – nicht hart fehlschlagen.
        }
      }
      return result;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      queryClient.invalidateQueries({ queryKey: ['mailbox-accounts', customerId] });
      setLocalPart('');
      setNotes('');
      setProvisionAtProvider(false);
      setCreateMailbox(false);
      setAdditionalForwards([]);
      onClose();
    },
    onError: (error) => {
      setProvisionError(error instanceof Error ? error.message : 'Fehler bei der Provisionierung');
    },
  });

  const updateMutation = useMutation({
    mutationFn: (data: Partial<StressfreiEmail>) =>
      stressfreiEmailApi.update(email!.id, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer', customerId] });
      onClose();
    },
    onError: (err) => {
      setProvisionError(err instanceof Error ? err.message : 'Fehler beim Speichern');
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    setProvisionError(null);
    const fullEmail = localPart + domainSuffix;

    if (isEditing) {
      updateMutation.mutate({
        email: fullEmail,
        notes: notes || undefined,
      });
    } else {
      createMutation.mutate({
        email: fullEmail,
        notes: notes || undefined,
        provision: provisionAtProvider,
        createMailbox: provisionAtProvider && createMailbox,
      });
    }
  };

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

  return (
    <Modal isOpen={isOpen} onClose={onClose} title={isEditing ? 'Adresse bearbeiten' : 'Adresse hinzufügen'}>
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            E-Mail-Adresse
          </label>
          <div className="flex">
            <input
              type="text"
              value={localPart}
              onChange={(e) => setLocalPart(e.target.value.toLowerCase().replace(/[^a-z0-9._-]/g, ''))}
              placeholder="kunde-freenet"
              required
              className="block w-full px-3 py-2 border border-gray-300 rounded-l-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
            />
            <span className="inline-flex items-center px-3 py-2 border border-l-0 border-gray-300 bg-gray-100 text-gray-600 rounded-r-lg text-sm">
              {domainSuffix}
            </span>
          </div>
          <p className="text-xs text-gray-500 mt-1">
            Vollständige Adresse: <span className="font-mono">{localPart || '...'}{domainSuffix}</span>
          </p>
        </div>

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            Notizen (optional)
          </label>
          <textarea
            value={notes}
            onChange={(e) => setNotes(e.target.value)}
            rows={3}
            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="z.B. für Freenet-Konten, für Klarmobil..."
          />
        </div>

        {/* Provisionierung - beim Erstellen: Checkbox, beim Bearbeiten: Status + Button */}
        {hasProvider && customerEmail && (
          <div className="bg-blue-50 p-3 rounded-lg">
            {!isEditing ? (
              // Erstellen-Modus: Checkboxen
              <div className="space-y-3">
                <label className="flex items-start gap-2 cursor-pointer">
                  <input
                    type="checkbox"
                    checked={provisionAtProvider}
                    onChange={(e) => {
                      setProvisionAtProvider(e.target.checked);
                      // Sobald "Beim Provider anlegen" aktiv ist, wollen wir
                      // per Default direkt eine echte Mailbox mit Passwort –
                      // sonst müsste man zwei Häkchen setzen, um ein
                      // vollwertiges Postfach zu bekommen.
                      setCreateMailbox(e.target.checked);
                    }}
                    className="mt-1 rounded border-gray-300"
                  />
                  <div>
                    <span className="text-sm font-medium text-gray-700">
                      Beim E-Mail-Provider anlegen
                    </span>
                    <p className="text-xs text-gray-500 mt-1">
                      Die E-Mail-Weiterleitung wird automatisch auf dem konfigurierten Server erstellt.
                      Weiterleitungsziel: {customerEmail}
                    </p>
                  </div>
                </label>

                {provisionAtProvider && (
                  <label className="flex items-start gap-2 cursor-pointer ml-6">
                    <input
                      type="checkbox"
                      checked={createMailbox}
                      onChange={(e) => setCreateMailbox(e.target.checked)}
                      className="mt-1 rounded border-gray-300"
                    />
                    <div>
                      <span className="text-sm font-medium text-gray-700">
                        Echte Mailbox erstellen (IMAP/SMTP-Zugang)
                      </span>
                      <p className="text-xs text-gray-500 mt-1">
                        Ermöglicht E-Mails direkt im CRM zu empfangen und zu versenden.
                      </p>
                    </div>
                  </label>
                )}
              </div>
            ) : (
              // Bearbeiten-Modus: Status anzeigen
              <div className="space-y-2">
                <div className="flex items-center justify-between">
                  <span className="text-sm font-medium text-gray-700">
                    E-Mail-Provider Status
                  </span>
                  {providerStatus === 'checking' && (
                    <span className="text-xs text-gray-500">Prüfe...</span>
                  )}
                  {providerStatus === 'exists' && (
                    <span className="text-xs text-green-600 flex items-center gap-1">
                      <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                        <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
                      </svg>
                      Beim Provider vorhanden
                    </span>
                  )}
                  {providerStatus === 'not_exists' && (
                    <span className="text-xs text-orange-600">Nicht beim Provider angelegt</span>
                  )}
                  {providerStatus === 'error' && (
                    <span className="text-xs text-red-600">Status konnte nicht geprüft werden</span>
                  )}
                </div>

                {/* Jetzt anlegen Button wenn nicht vorhanden */}
                {providerStatus === 'not_exists' && (
                  <div className="pt-2 border-t border-blue-100">
                    <p className="text-xs text-gray-500 mb-2">
                      Die E-Mail-Weiterleitung ist noch nicht auf dem Server eingerichtet.
                      Weiterleitungsziel: {customerEmail}
                    </p>
                    <Button
                      type="button"
                      size="sm"
                      onClick={handleProvisionNow}
                      disabled={isProvisioning}
                    >
                      {isProvisioning ? 'Wird angelegt...' : 'Jetzt beim Provider anlegen'}
                    </Button>
                  </div>
                )}

                {/* Erneut prüfen bei Fehler */}
                {providerStatus === 'error' && (
                  <Button
                    type="button"
                    size="sm"
                    variant="secondary"
                    onClick={() => checkProviderStatus(localPart)}
                  >
                    Erneut prüfen
                  </Button>
                )}

                {/* Mailbox-Status anzeigen wenn Provider vorhanden */}
                {providerStatus === 'exists' && (
                  <div className="pt-3 mt-3 border-t border-blue-100">
                    <div className="flex items-center justify-between">
                      <span className="text-sm font-medium text-gray-700">
                        Mailbox (IMAP/SMTP)
                      </span>
                      {mailboxEnabled ? (
                        <span className="text-xs text-green-600 flex items-center gap-1">
                          <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                            <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
                          </svg>
                          Mailbox aktiv
                        </span>
                      ) : (
                        <span className="text-xs text-orange-600">Keine Mailbox</span>
                      )}
                    </div>
                    {!mailboxEnabled && (
                      <div className="mt-2">
                        <p className="text-xs text-gray-500 mb-2">
                          Aktiviere eine echte Mailbox um E-Mails direkt im CRM zu empfangen und zu versenden.
                        </p>
                        <Button
                          type="button"
                          size="sm"
                          onClick={handleEnableMailbox}
                          disabled={isEnablingMailbox}
                        >
                          {isEnablingMailbox ? 'Wird aktiviert...' : 'Mailbox aktivieren'}
                        </Button>
                      </div>
                    )}
                    {/* Zugangsdaten anzeigen wenn Mailbox aktiv */}
                    {mailboxEnabled && (
                      <div className="mt-3">
                        {!showCredentials ? (
                          <Button
                            type="button"
                            size="sm"
                            variant="secondary"
                            onClick={loadCredentials}
                            disabled={isLoadingCredentials}
                          >
                            {isLoadingCredentials ? (
                              'Laden...'
                            ) : (
                              <>
                                <Eye className="w-4 h-4 mr-1" />
                                Zugangsdaten anzeigen
                              </>
                            )}
                          </Button>
                        ) : credentials && (
                          <CredentialsDisplay
                            credentials={credentials}
                            onHide={() => setShowCredentials(false)}
                            onResetPassword={handleResetPassword}
                            isResettingPassword={isResettingPassword}
                          />
                        )}
                      </div>
                    )}
                  </div>
                )}
              </div>
            )}
          </div>
        )}

        {/* Fehleranzeige für Provisionierung */}
        {provisionError && (
          <div className="bg-red-50 p-3 rounded-lg text-red-700 text-sm">
            {provisionError}
          </div>
        )}

        <div className="flex justify-between items-center gap-2">
          <div>
            {((isEditing && email && providerStatus === 'exists') ||
              (!isEditing && provisionAtProvider)) && (
              <Button
                type="button"
                variant="ghost"
                size="sm"
                onClick={() => setShowForwardsModal(true)}
                title="Zusätzliche Weiterleitungs-Adressen pflegen"
              >
                <Mail className="w-4 h-4 mr-1" />
                Weitere Weiterleitungen
                {additionalForwards.length > 0 && (
                  <span className="ml-1 text-xs bg-blue-100 text-blue-700 rounded-full px-1.5">
                    {additionalForwards.length}
                  </span>
                )}
              </Button>
            )}
          </div>
          <div className="flex gap-2">
            <Button type="button" variant="secondary" onClick={onClose}>
              Abbrechen
            </Button>
            <Button type="submit" disabled={isPending || !localPart}>
              {isPending ? 'Speichern...' : 'Speichern'}
            </Button>
          </div>
        </div>
      </form>

      <AdditionalForwardsModal
        isOpen={showForwardsModal}
        onClose={() => setShowForwardsModal(false)}
        email={email ?? undefined}
        customerEmail={customerEmail}
        selfEmail={localPart ? localPart + domainSuffix : undefined}
        value={additionalForwards}
        onChange={setAdditionalForwards}
      />
    </Modal>
  );
}

// Untermodal: zusätzliche Weiterleitungs-E-Mails verwalten.
// Edit-Modus: `email` prop gesetzt → jede Änderung wird sofort am
//   Provider gesynct.
// Create-Modus: `email` undefined → reine lokale Verwaltung über
//   `value`/`onChange`. Wird beim createEmail-Submit mitgegeben.
function AdditionalForwardsModal({
  isOpen,
  onClose,
  email,
  customerEmail,
  selfEmail,
  value,
  onChange,
}: {
  isOpen: boolean;
  onClose: () => void;
  email?: StressfreiEmail;
  customerEmail?: string;
  /** Die Stressfrei-Adresse selbst (für Self-Forward-Check im Create-Modus,
   *  wo es noch kein `email`-Prop gibt). Edit-Modus zieht's aus `email`. */
  selfEmail?: string;
  /** Aktuelle Liste – im Create-Modus controlled, im Edit-Modus initialer Wert. */
  value: string[];
  onChange: (next: string[]) => void;
}) {
  const queryClient = useQueryClient();
  const [newEmail, setNewEmail] = useState('');
  const [error, setError] = useState<string | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    setNewEmail('');
    setError(null);
  }, [isOpen]);

  const EMAIL_REGEX = /^[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}$/;

  const persist = async (next: string[]) => {
    setError(null);
    if (email) {
      // Edit-Modus: sofort am Provider syncen.
      setIsSubmitting(true);
      try {
        await stressfreiEmailApi.updateAdditionalForwards(email.id, next);
        onChange(next);
        queryClient.invalidateQueries({ queryKey: ['stressfrei-emails', email.customerId] });
      } catch (e) {
        const msg = e instanceof Error ? e.message : 'Speichern fehlgeschlagen';
        setError(msg);
        throw e;
      } finally {
        setIsSubmitting(false);
      }
    } else {
      // Create-Modus: nur lokal updaten. Persistierung beim Submit
      // des Haupt-Modals.
      onChange(next);
    }
  };

  // Plus-Tag wegstrippen + lowercase, identisch zum Backend-canonicalEmailKey.
  // Dann landen `billing+x@y` und `billing@y` im selben Key.
  const canonicalize = (raw: string) => {
    const lower = raw.trim().toLowerCase();
    const at = lower.lastIndexOf('@');
    if (at < 1) return lower;
    const local = lower.slice(0, at);
    const plus = local.indexOf('+');
    return (plus === -1 ? local : local.slice(0, plus)) + '@' + lower.slice(at + 1);
  };

  const handleAdd = async (e: React.FormEvent) => {
    e.preventDefault();
    const candidate = newEmail.trim().toLowerCase();
    if (!candidate) return;
    if (!EMAIL_REGEX.test(candidate)) {
      setError('Bitte eine gültige E-Mail-Adresse eingeben.');
      return;
    }
    const candidateKey = canonicalize(candidate);
    if (customerEmail && candidateKey === canonicalize(customerEmail)) {
      setError('Die Stamm-E-Mail des Kunden ist bereits Weiterleitungsziel.');
      return;
    }
    const ownAddress = email?.email ?? selfEmail;
    if (ownAddress && candidateKey === canonicalize(ownAddress)) {
      setError(`"${candidate}" zeigt auf die Adresse selbst – das würde einen Mail-Loop erzeugen.`);
      return;
    }
    if (value.some((f) => canonicalize(f) === candidateKey)) {
      setError('Diese Adresse ist schon in der Liste.');
      return;
    }
    try {
      await persist([...value, candidate]);
      setNewEmail('');
    } catch {
      /* error wird oben gesetzt */
    }
  };

  const handleRemove = async (target: string) => {
    try {
      await persist(value.filter((f) => f !== target));
    } catch {
      /* error wird oben gesetzt */
    }
  };

  const title = email
    ? `Weiterleitungen für ${email.email}`
    : 'Weitere Weiterleitungen';

  return (
    <Modal isOpen={isOpen} onClose={onClose} title={title}>
      <div className="space-y-4">
        <p className="text-sm text-gray-600">
          Posteingänge gehen immer an die Stamm-E-Mail des Kunden
          {customerEmail && (
            <> (<span className="font-mono">{customerEmail}</span>)</>
          )}
          . Hier kannst du zusätzliche Adressen hinterlegen, die ebenfalls eine Kopie bekommen.
          {email
            ? ' Änderungen werden sofort am E-Mail-Provider übernommen.'
            : ' Sie werden zusammen mit der Adresse angelegt, sobald du speicherst.'}
        </p>

        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            Aktuelle zusätzliche Ziele
          </label>
          {value.length === 0 ? (
            <p className="text-sm text-gray-500 italic">Noch keine zusätzlichen Adressen.</p>
          ) : (
            <ul className="space-y-1">
              {value.map((f) => (
                <li
                  key={f}
                  className="flex items-center justify-between bg-gray-50 border border-gray-200 rounded px-3 py-2"
                >
                  <span className="font-mono text-sm">{f}</span>
                  <button
                    type="button"
                    onClick={() => handleRemove(f)}
                    className="text-red-600 hover:text-red-800 disabled:opacity-50"
                    disabled={isSubmitting}
                    title="Entfernen"
                  >
                    <Trash2 className="w-4 h-4" />
                  </button>
                </li>
              ))}
            </ul>
          )}
        </div>

        <form onSubmit={handleAdd} className="border-t pt-3 space-y-2">
          <label className="block text-sm font-medium text-gray-700">
            Weitere Adresse hinzufügen
          </label>
          <div className="flex gap-2">
            <input
              type="email"
              value={newEmail}
              onChange={(e) => {
                setNewEmail(e.target.value);
                setError(null);
              }}
              placeholder="z.B. info@partner.de"
              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"
              disabled={isSubmitting}
              maxLength={254}
            />
            <Button type="submit" disabled={isSubmitting || !newEmail.trim()}>
              <Plus className="w-4 h-4 mr-1" />
              Hinzufügen
            </Button>
          </div>
        </form>

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

        <div className="flex justify-end">
          <Button type="button" variant="secondary" onClick={onClose} disabled={isSubmitting}>
            Schließen
          </Button>
        </div>
      </div>
    </Modal>
  );
}

// Sperrhinweis wenn Datenschutz-Einwilligung fehlt
function ConsentBlockedContent({
  onGoToConsentsTab,
}: {
  onGoToConsentsTab?: () => void;
}) {
  return (
    <div className="flex flex-col items-center justify-center py-12 px-6 text-center">
      <div className="bg-amber-50 border border-amber-200 rounded-full p-4 mb-4">
        <Lock className="w-8 h-8 text-amber-500" />
      </div>
      <h3 className="text-lg font-semibold text-gray-800 mb-2">
        Datenschutz-Einwilligung erforderlich
      </h3>
      <p className="text-sm text-gray-600 mb-6 max-w-md">
        Dieser Bereich ist erst verfügbar, wenn der Kunde der Datenschutzerklärung zugestimmt hat.
        Die Einwilligung kann in Papierform oder online über den Einwilligungslink eingeholt werden.
      </p>
      <div className="bg-gray-50 border rounded-lg p-4 w-full max-w-md text-left space-y-3">
        <div className="flex items-start gap-3">
          <FileText className="w-5 h-5 text-gray-400 mt-0.5 flex-shrink-0" />
          <div>
            <p className="text-sm font-medium text-gray-700">Papierform</p>
            <p className="text-xs text-gray-500">
              Datenschutzerklärung ausdrucken, unterschreiben lassen und als PDF im Tab "Einwilligungen / Datenschutz" hochladen.
            </p>
          </div>
        </div>
        <div className="flex items-start gap-3">
          <Mail className="w-5 h-5 text-gray-400 mt-0.5 flex-shrink-0" />
          <div>
            <p className="text-sm font-medium text-gray-700">Online per Link</p>
            <p className="text-xs text-gray-500">
              Einwilligungslink im Tab "Einwilligungen / Datenschutz" per E-Mail, WhatsApp, Telegram oder Signal an den Kunden senden.
            </p>
          </div>
        </div>
      </div>
      {onGoToConsentsTab && (
        <button
          onClick={onGoToConsentsTab}
          className="mt-6 inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm"
        >
          <Shield className="w-4 h-4" />
          Zum Tab "Einwilligungen / Datenschutz"
        </button>
      )}
    </div>
  );
}

// Consent Tab Component (DSGVO Einwilligungen)
const CONSENT_TYPE_LABELS: Record<ConsentType, { label: string; description: string }> = {
  DATA_PROCESSING: {
    label: 'Datenverarbeitung',
    description: 'Grundlegende Verarbeitung personenbezogener Daten zur Vertragserfüllung',
  },
  MARKETING_EMAIL: {
    label: 'Elektronisches Marketing',
    description: 'Zusendung von Werbung und Angeboten über elektronische Kommunikationswege (E-Mail, Messenger etc.)',
  },
  MARKETING_PHONE: {
    label: 'Telefonmarketing',
    description: 'Kontaktaufnahme zu Werbezwecken per Telefon',
  },
  DATA_SHARING_PARTNER: {
    label: 'Datenweitergabe',
    description: 'Weitergabe von Daten an Partnerunternehmen',
  },
};

function ConsentTab({
  customerId,
  canEdit,
  customerEmail,
  customer,
  onUpdate,
}: {
  customerId: number;
  canEdit: boolean;
  customerEmail?: string;
  customer?: Customer;
  onUpdate?: () => void;
}) {
  const queryClient = useQueryClient();
  const { user } = useAuth();
  const [showSendDropdown, setShowSendDropdown] = useState(false);

  const { data: consentsData, isLoading } = useQuery({
    queryKey: ['customer-consents', customerId],
    queryFn: () => gdprApi.getCustomerConsents(customerId),
  });

  const sendLinkMutation = useMutation({
    mutationFn: (channel: string) => gdprApi.sendConsentLink(customerId, channel),
    onSuccess: (result, channel) => {
      const url = result.data?.url;

      if (channel === 'email') {
        alert('Datenschutz-Link wurde per E-Mail gesendet.');
      } else if (channel === 'whatsapp' && url) {
        const text = encodeURIComponent(`Bitte stimmen Sie unserer Datenschutzerklärung zu: ${url}`);
        window.open(`https://wa.me/?text=${text}`, '_blank');
      } else if (channel === 'telegram' && url) {
        const text = encodeURIComponent(`Bitte stimmen Sie unserer Datenschutzerklärung zu: ${url}`);
        window.open(`https://t.me/share/url?url=${encodeURIComponent(url)}&text=${text}`, '_blank');
      } else if (channel === 'signal' && url) {
        const text = encodeURIComponent(`Bitte stimmen Sie unserer Datenschutzerklärung zu: ${url}`);
        window.open(`signal://send?text=${text}`, '_blank');
      }
      setShowSendDropdown(false);
    },
    onError: (error) => {
      alert(`Fehler beim Senden: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}`);
      setShowSendDropdown(false);
    },
  });

  const updateMutation = useMutation({
    mutationFn: ({ consentType, status, source }: { consentType: ConsentType; status: ConsentStatus; source: string }) =>
      gdprApi.updateConsent(customerId, consentType, { status, source }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['customer-consents', customerId] });
    },
  });

  const handleToggle = (consent: CustomerConsent) => {
    const newStatus: ConsentStatus = consent.status === 'GRANTED' ? 'WITHDRAWN' : 'GRANTED';
    updateMutation.mutate({
      consentType: consent.consentType,
      status: newStatus,
      source: 'crm-backend',
    });
  };

  const getStatusIcon = (status: ConsentStatus) => {
    switch (status) {
      case 'GRANTED':
        return <ShieldCheck className="w-5 h-5 text-green-500" />;
      case 'WITHDRAWN':
        return <ShieldX className="w-5 h-5 text-red-500" />;
      case 'PENDING':
        return <ShieldAlert className="w-5 h-5 text-yellow-500" />;
      default:
        return <Shield className="w-5 h-5 text-gray-400" />;
    }
  };

  const getStatusBadge = (status: ConsentStatus) => {
    switch (status) {
      case 'GRANTED':
        return <Badge variant="success">Erteilt</Badge>;
      case 'WITHDRAWN':
        return <Badge variant="danger">Widerrufen</Badge>;
      case 'PENDING':
        return <Badge variant="warning">Ausstehend</Badge>;
      default:
        return <Badge>{status}</Badge>;
    }
  };

  const formatDate = (date?: string) => {
    if (!date) return '-';
    return new Date(date).toLocaleDateString('de-DE', {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    });
  };

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

  const consents = consentsData?.data || [];

  // Messaging-Kanäle basierend auf den Feldern des aktuellen Users
  const userAny = user as any;
  const channels: { key: string; label: string; icon: string; available: boolean }[] = [
    { key: 'email', label: 'Per E-Mail', icon: '✉️', available: !!customerEmail },
    { key: 'whatsapp', label: 'Per WhatsApp', icon: '💬', available: !!userAny?.whatsappNumber },
    { key: 'telegram', label: 'Per Telegram', icon: '📨', available: !!userAny?.telegramUsername },
    { key: 'signal', label: 'Per Signal', icon: '📱', available: !!userAny?.signalNumber },
  ];

  const handlePrivacyPolicyUpload = async (file: File) => {
    try {
      await uploadApi.uploadPrivacyPolicy(customerId, file);
      onUpdate?.();
      queryClient.invalidateQueries({ queryKey: ['customer-consents', customerId] });
    } catch (error) {
      console.error('Upload fehlgeschlagen:', error);
      alert('Upload fehlgeschlagen');
    }
  };

  const handlePrivacyPolicyDelete = async () => {
    if (!confirm('Datenschutzerklärung wirklich löschen?')) return;
    try {
      await uploadApi.deletePrivacyPolicy(customerId);
      onUpdate?.();
      queryClient.invalidateQueries({ queryKey: ['customer-consents', customerId] });
    } catch (error) {
      console.error('Löschen fehlgeschlagen:', error);
      alert('Löschen fehlgeschlagen');
    }
  };

  return (
    <div className="space-y-6">
      {/* Datenschutzerklärung PDF (Papierform) */}
      {customer && (
        <div className="border rounded-lg p-4 bg-gray-50">
          <div className="flex items-center gap-2 mb-3">
            <FileText className="w-5 h-5 text-gray-400" />
            <h3 className="font-medium">Datenschutzerklärung (Papierform)</h3>
            {customer.privacyPolicyPath && (
              <span className="text-xs px-2 py-0.5 rounded-full bg-green-100 text-green-700">Vorhanden</span>
            )}
          </div>
          {customer.privacyPolicyPath ? (
            <div className="flex items-center gap-3 flex-wrap">
              <a
                href={viewUrl(customer.privacyPolicyPath)}
                target="_blank"
                rel="noopener noreferrer"
                className="text-blue-600 hover:underline text-sm flex items-center gap-1"
              >
                <Eye className="w-4 h-4" />
                Anzeigen
              </a>
              <a
                href={fileUrl(customer.privacyPolicyPath)}
                download
                className="text-blue-600 hover:underline text-sm flex items-center gap-1"
              >
                <Download className="w-4 h-4" />
                Download
              </a>
              <FileUpload
                onUpload={handlePrivacyPolicyUpload}
                existingFile={customer.privacyPolicyPath}
                accept=".pdf"
                label="Ersetzen"
              />
              <button
                onClick={handlePrivacyPolicyDelete}
                className="text-red-600 hover:underline text-sm flex items-center gap-1"
              >
                <Trash2 className="w-4 h-4" />
                Löschen
              </button>
            </div>
          ) : (
            <div>
              <p className="text-sm text-gray-500 mb-2">
                Unterschriebene Datenschutzerklärung als PDF hochladen. Dies gilt als vollständige Einwilligung.
              </p>
              <div className="flex flex-wrap items-center gap-3">
                <a
                  href={gdprApi.getSignablePrivacyPdfUrl(customerId)}
                  download
                  className="inline-flex items-center gap-1 text-sm text-blue-600 hover:underline"
                  title="PDF mit personalisiertem Kopf + Unterschriftsfeld zum Ausdrucken"
                >
                  <Download className="w-4 h-4" />
                  Vorlage zum Unterschreiben
                </a>
                <span className="text-gray-300">·</span>
                <FileUpload
                  onUpload={handlePrivacyPolicyUpload}
                  accept=".pdf"
                  label="Unterschriebene PDF hochladen"
                />
              </div>
            </div>
          )}
        </div>
      )}

      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center gap-2">
          <Shield className="w-5 h-5 text-gray-400" />
          <h3 className="font-medium">Online-Einwilligungen</h3>
        </div>
        {/* Datenschutz senden Button */}
        <div className="relative">
          <Button
            variant="secondary"
            size="sm"
            onClick={() => setShowSendDropdown(!showSendDropdown)}
          >
            <Mail className="w-4 h-4 mr-2" />
            Datenschutz senden
            <ChevronDown className="w-3 h-3 ml-1" />
          </Button>
          {showSendDropdown && (
            <>
              <div className="fixed inset-0 z-10" onClick={() => setShowSendDropdown(false)} />
              <div className="absolute right-0 mt-1 w-56 bg-white border rounded-lg shadow-lg z-20 py-1">
                {channels.filter((ch) => ch.available).map((ch) => (
                  <button
                    key={ch.key}
                    className="w-full text-left px-4 py-2 text-sm hover:bg-gray-50 flex items-center gap-2"
                    onClick={() => sendLinkMutation.mutate(ch.key)}
                    disabled={sendLinkMutation.isPending}
                  >
                    <span>{ch.icon}</span>
                    <span>{ch.label}</span>
                  </button>
                ))}
                {channels.filter((ch) => ch.available).length === 0 && (
                  <p className="px-4 py-2 text-xs text-gray-400">
                    Kanäle in Benutzereinstellungen konfigurieren (E-Mail, WhatsApp, Telegram, Signal)
                  </p>
                )}
              </div>
            </>
          )}
        </div>
      </div>

      <p className="text-sm text-gray-500 mb-4">
        Einwilligungen können nur vom Kunden selbst erteilt oder widerrufen werden (Kundenportal oder Datenschutz-Link).
      </p>

      <div className="space-y-4">
        {consents.map((consent) => {
          const typeInfo = CONSENT_TYPE_LABELS[consent.consentType] || { label: consent.consentType, description: '' };

          return (
            <div key={consent.consentType} className="border rounded-lg p-4">
              <div className="flex items-start justify-between">
                <div className="flex items-start gap-3">
                  {getStatusIcon(consent.status)}
                  <div>
                    <h4 className="font-medium">{typeInfo.label}</h4>
                    <p className="text-sm text-gray-500">{typeInfo.description}</p>
                    <div className="mt-2 flex items-center gap-4 text-xs text-gray-500">
                      {consent.grantedAt && (
                        <span>Erteilt am: {formatDate(consent.grantedAt)}</span>
                      )}
                      {consent.withdrawnAt && (
                        <span>Widerrufen am: {formatDate(consent.withdrawnAt)}</span>
                      )}
                      {consent.source && (
                        <span>Quelle: {consent.source}</span>
                      )}
                    </div>
                  </div>
                </div>
                <div className="flex items-center gap-3">
                  {getStatusBadge(consent.status)}
                  {canEdit && (
                    <label className="relative inline-flex items-center cursor-pointer">
                      <input
                        type="checkbox"
                        checked={consent.status === 'GRANTED'}
                        onChange={() => handleToggle(consent)}
                        disabled={updateMutation.isPending}
                        className="sr-only peer"
                      />
                      <div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-600"></div>
                    </label>
                  )}
                </div>
              </div>
            </div>
          );
        })}
      </div>

      {consents.length === 0 && (
        <p className="text-gray-500 text-center py-4">Keine Einwilligungen konfiguriert.</p>
      )}

      {/* Vollmachten */}
      <AuthorizationsSection customerId={customerId} customerEmail={customerEmail} />
    </div>
  );
}

// ==================== Vollmachten-Bereich ====================

function AuthorizationsSection({ customerId, customerEmail }: { customerId: number; customerEmail?: string }) {
  const queryClient = useQueryClient();
  const { user } = useAuth();
  const [sendDropdownFor, setSendDropdownFor] = useState<number | null>(null);
  const [jpgModalFor, setJpgModalFor] = useState<number | null>(null);

  const { data: authData, isLoading } = useQuery({
    queryKey: ['authorizations', customerId],
    queryFn: () => gdprApi.getAuthorizations(customerId),
  });

  const uploadMutation = useMutation({
    mutationFn: ({ representativeId, file }: { representativeId: number; file: File }) =>
      gdprApi.uploadAuthorizationDocument(customerId, representativeId, file),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['authorizations', customerId] }),
  });

  const deleteDocMutation = useMutation({
    mutationFn: (representativeId: number) =>
      gdprApi.deleteAuthorizationDocument(customerId, representativeId),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['authorizations', customerId] }),
  });

  const sendMutation = useMutation({
    mutationFn: ({ representativeId, channel }: { representativeId: number; channel: string }) =>
      gdprApi.sendAuthorizationRequest(customerId, representativeId, channel),
    onSuccess: (result, { channel }) => {
      const messageText = result.data?.messageText;
      const portalUrl = result.data?.portalUrl;

      if (channel === 'email') {
        alert('Vollmacht-Anfrage wurde per E-Mail gesendet.');
      } else if (channel === 'whatsapp') {
        const text = encodeURIComponent(messageText || `Bitte erteilen Sie die Vollmacht: ${portalUrl}`);
        window.open(`https://wa.me/?text=${text}`, '_blank');
      } else if (channel === 'telegram') {
        const text = encodeURIComponent(messageText || '');
        window.open(`https://t.me/share/url?url=${encodeURIComponent(portalUrl || '')}&text=${text}`, '_blank');
      } else if (channel === 'signal') {
        const text = encodeURIComponent(messageText || '');
        window.open(`signal://send?text=${text}`, '_blank');
      }
      setSendDropdownFor(null);
    },
    onError: (error) => {
      alert(`Fehler beim Senden: ${error instanceof Error ? error.message : 'Unbekannter Fehler'}`);
      setSendDropdownFor(null);
    },
  });

  const authorizations: RepresentativeAuthorization[] = authData?.data || [];

  if (isLoading) return <div className="text-center py-4 text-gray-500">Laden...</div>;

  if (authorizations.length === 0) return null;

  const handleFileUpload = (representativeId: number, e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      uploadMutation.mutate({ representativeId, file });
    }
  };

  // Messaging-Kanäle
  const userAny = user as any;
  const channels: { key: string; label: string; icon: string; available: boolean }[] = [
    { key: 'email', label: 'Per E-Mail', icon: '✉️', available: !!customerEmail },
    { key: 'whatsapp', label: 'Per WhatsApp', icon: '💬', available: !!userAny?.whatsappNumber },
    { key: 'telegram', label: 'Per Telegram', icon: '📨', available: !!userAny?.telegramUsername },
    { key: 'signal', label: 'Per Signal', icon: '📱', available: !!userAny?.signalNumber },
  ];

  return (
    <div className="pt-6 border-t mt-6">
      <div className="flex items-center gap-2 mb-3">
        <FileText className="w-5 h-5 text-gray-400" />
        <h3 className="font-medium">Vollmachten (Vertreterregelung)</h3>
      </div>
      <p className="text-sm text-gray-500 mb-4">
        Damit ein Vertreter die Verträge dieses Kunden einsehen kann, muss eine Vollmacht vorliegen.
        Diese kann als PDF hochgeladen oder vom Kunden im Portal erteilt werden.
      </p>

      <div className="space-y-3">
        {authorizations.map((auth) => (
          <div key={auth.id} className="border rounded-lg p-4">
            <div className="flex items-start justify-between">
              <div className="flex items-start gap-3">
                {auth.isGranted ? (
                  <ShieldCheck className="w-5 h-5 text-green-500 mt-0.5" />
                ) : (
                  <ShieldAlert className="w-5 h-5 text-yellow-500 mt-0.5" />
                )}
                <div>
                  <h4 className="font-medium">
                    Vollmacht für: {auth.representative?.firstName} {auth.representative?.lastName}
                  </h4>
                  <p className="text-xs text-gray-500">
                    {auth.representative?.customerNumber && `Kd.-Nr.: ${auth.representative.customerNumber}`}
                  </p>
                  {auth.grantedAt && auth.isGranted && (
                    <p className="text-xs text-gray-400 mt-1">
                      Erteilt am: {new Date(auth.grantedAt).toLocaleDateString('de-DE', {
                        day: '2-digit', month: '2-digit', year: 'numeric',
                      })}
                      {auth.source && ` (${auth.source})`}
                    </p>
                  )}
                </div>
              </div>
              <div className="flex items-center gap-2">
                <Badge variant={auth.isGranted ? 'success' : 'warning'}>
                  {auth.isGranted ? 'Erteilt' : 'Ausstehend'}
                </Badge>

                {/* Senden-Button mit Dropdown */}
                <div className="relative">
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => setSendDropdownFor(sendDropdownFor === auth.representativeId ? null : auth.representativeId)}
                  >
                    <Mail className="w-4 h-4 mr-1" />
                    Senden
                    <ChevronDown className="w-3 h-3 ml-1" />
                  </Button>
                  {sendDropdownFor === auth.representativeId && (
                    <>
                      <div className="fixed inset-0 z-10" onClick={() => setSendDropdownFor(null)} />
                      <div className="absolute right-0 mt-1 w-56 bg-white border rounded-lg shadow-lg z-20 py-1">
                        {channels.filter((ch) => ch.available).map((ch) => (
                          <button
                            key={ch.key}
                            className="w-full text-left px-4 py-2 text-sm hover:bg-gray-50 flex items-center gap-2"
                            onClick={() => sendMutation.mutate({ representativeId: auth.representativeId, channel: ch.key })}
                            disabled={sendMutation.isPending}
                          >
                            <span>{ch.icon}</span>
                            <span>{ch.label}</span>
                          </button>
                        ))}
                        {channels.filter((ch) => ch.available).length === 0 && (
                          <p className="px-4 py-2 text-xs text-gray-400">
                            Kanäle in Benutzereinstellungen konfigurieren
                          </p>
                        )}
                      </div>
                    </>
                  )}
                </div>
              </div>
            </div>

            {/* Dokument-Upload */}
            <div className="mt-3 pt-3 border-t flex items-center gap-3">
              {auth.documentPath ? (
                <>
                  <a
                    href={viewUrl(auth.documentPath)}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="text-blue-600 hover:underline text-xs flex items-center gap-1"
                  >
                    <Eye className="w-3 h-3" />
                    Vollmacht-PDF anzeigen
                  </a>
                  <button
                    onClick={() => deleteDocMutation.mutate(auth.representativeId)}
                    className="text-red-600 hover:underline text-xs flex items-center gap-1"
                  >
                    <Trash2 className="w-3 h-3" />
                    Löschen
                  </button>
                </>
              ) : (
                <>
                  <label className="text-xs text-blue-600 hover:underline cursor-pointer flex items-center gap-1">
                    <Plus className="w-3 h-3" />
                    Vollmacht-PDF hochladen
                    <input
                      type="file"
                      accept=".pdf"
                      className="hidden"
                      onChange={(e) => handleFileUpload(auth.representativeId, e)}
                    />
                  </label>
                  <button
                    type="button"
                    onClick={() => setJpgModalFor(auth.representativeId)}
                    className="text-xs text-blue-600 hover:underline cursor-pointer flex items-center gap-1"
                    title="Mehrere JPGs zu einer PDF kombinieren"
                  >
                    <Images className="w-3 h-3" />
                    JPGs → PDF
                  </button>
                </>
              )}
            </div>
          </div>
        ))}
      </div>
      <JpgToPdfModal
        isOpen={jpgModalFor !== null}
        onClose={() => setJpgModalFor(null)}
        onComplete={(file) => {
          if (jpgModalFor !== null) {
            uploadMutation.mutate({ representativeId: jpgModalFor, file });
          }
        }}
        fileNameHint="vollmacht"
      />
    </div>
  );
}

// ============================================================================
// SalutationPreferenceToggle – persönliche Du/Sie-Präferenz des Mitarbeiters
// ============================================================================
// User-Wunsch 2026-07-04: Stefan darf per Du sein mit einem Kunden, ohne dass
// das für andere Mitarbeiter gilt. Wenn kein Eintrag existiert, greift der
// Kunden-Default (`useInformalAddress`) – der Toggle zeigt das als "Standard".
function SalutationPreferenceToggle({
  customerId,
  customerDefaultInformal,
}: {
  customerId: number;
  customerDefaultInformal: boolean;
}) {
  const queryClient = useQueryClient();
  const { data, isLoading } = useQuery({
    queryKey: ['salutation-preference', customerId],
    queryFn: () => customerApi.getSalutationPreference(customerId),
  });
  const setMutation = useMutation({
    mutationFn: (preference: 'DU' | 'SIE') =>
      customerApi.setSalutationPreference(customerId, preference),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['salutation-preference', customerId] });
    },
  });
  const clearMutation = useMutation({
    mutationFn: () => customerApi.clearSalutationPreference(customerId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['salutation-preference', customerId] });
    },
  });

  const isMutating = setMutation.isPending || clearMutation.isPending;
  const preference = data?.data?.preference;
  const source = data?.data?.source;
  const defaultLabel = customerDefaultInformal ? 'Du' : 'Sie';

  const btnClass = (active: boolean) =>
    `px-3 py-1 text-sm rounded-md transition-colors ${
      active
        ? 'bg-blue-100 text-blue-800 border border-blue-300'
        : 'bg-gray-100 text-gray-600 border border-gray-200 hover:bg-gray-200'
    } ${isMutating ? 'opacity-60 cursor-not-allowed' : ''}`;

  if (isLoading) {
    return <span className="text-xs text-gray-400">lädt…</span>;
  }

  return (
    <div className="flex items-center gap-2 flex-wrap">
      <button
        type="button"
        onClick={() => !isMutating && setMutation.mutate('DU')}
        className={btnClass(preference === 'DU')}
        disabled={isMutating}
      >
        Du
      </button>
      <button
        type="button"
        onClick={() => !isMutating && setMutation.mutate('SIE')}
        className={btnClass(preference === 'SIE')}
        disabled={isMutating}
      >
        Sie
      </button>
      {source === 'user' ? (
        <button
          type="button"
          onClick={() => !isMutating && clearMutation.mutate()}
          className="text-xs text-blue-600 hover:underline"
          disabled={isMutating}
          title={`Auf Kunden-Default (${defaultLabel}) zurücksetzen`}
        >
          Zurücksetzen
        </button>
      ) : (
        <span className="text-xs text-gray-400">Standard: {defaultLabel}</span>
      )}
    </div>
  );
}
