"use client";

import { useCallback, useEffect, useState } from "react";
import Link from "next/link";
import { useParams, useRouter } from "next/navigation";
import { ArrowLeft, Edit, Plus, Trash2 } from "lucide-react";

import ConfirmDialog from "@/components/common/ConfirmDialog";
import DetailSection from "@/components/common/DetailSection";
import { useToast } from "@/components/common/ToastProvider";
import { Button } from "@/components/ui/button";
import CustomerContactFormDialog from "@/components/customers/CustomerContactFormDialog";
import CustomerFormDialog from "@/components/customers/CustomerFormDialog";
import CustomerStatusBadge from "@/components/customers/CustomerStatusBadge";
import { api } from "@/lib/api";
import { hasPermission } from "@/lib/permissions";
import type { CurrentUser } from "@/types/rbac";
import type { Customer, CustomerContact, CustomerContactPayload, CustomerPayload } from "@/types/customer";

function getErrorMessage(error: unknown) {
  if (typeof error === "object" && error !== null && "response" in error) {
    const response = (error as { response?: { data?: { detail?: string } } }).response;
    return response?.data?.detail ?? "Aktion konnte nicht abgeschlossen werden";
  }
  return "Aktion konnte nicht abgeschlossen werden";
}

function formatDateTime(value: string) {
  return new Intl.DateTimeFormat("de-DE", {
    dateStyle: "medium",
    timeStyle: "short",
  }).format(new Date(value));
}

export default function CustomerDetailPage() {
  const { showToast } = useToast();
  const params = useParams<{ id: string }>();
  const router = useRouter();
  const [customer, setCustomer] = useState<Customer | null>(null);
  const [currentUser, setCurrentUser] = useState<CurrentUser | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");
  const [pending, setPending] = useState(false);
  const [formOpen, setFormOpen] = useState(false);
  const [formError, setFormError] = useState("");
  const [contactOpen, setContactOpen] = useState(false);
  const [contactError, setContactError] = useState("");
  const [selectedContact, setSelectedContact] = useState<CustomerContact | null>(null);
  const [deleteContact, setDeleteContact] = useState<CustomerContact | null>(null);
  const [deleteCustomerOpen, setDeleteCustomerOpen] = useState(false);
  const [deleteError, setDeleteError] = useState("");

  const loadCustomer = useCallback(async () => {
    try {
      const [customerResponse, meResponse] = await Promise.all([
        api.get<Customer>(`/customers/${params.id}`),
        api.get<CurrentUser>("/me"),
      ]);
      setCustomer(customerResponse.data);
      setCurrentUser(meResponse.data);
    } catch (err) {
      setError(getErrorMessage(err));
    } finally {
      setLoading(false);
    }
  }, [params.id]);

  useEffect(() => {
    queueMicrotask(() => {
      void loadCustomer();
    });
  }, [loadCustomer]);

  async function saveCustomer(payload: CustomerPayload) {
    if (!customer) {
      return;
    }
    setPending(true);
    setFormError("");
    try {
      const response = await api.put<Customer>(`/customers/${customer.id}`, payload);
      setCustomer(response.data);
      setFormOpen(false);
      showToast({ type: "success", title: "Kunde aktualisiert", description: response.data.company_name });
    } catch (err) {
      const message = getErrorMessage(err);
      setFormError(message);
      showToast({ type: "error", title: "Kunde konnte nicht gespeichert werden", description: message });
    } finally {
      setPending(false);
    }
  }

  function openContactDialog(contact: CustomerContact | null) {
    setSelectedContact(contact);
    setContactError("");
    setContactOpen(true);
  }

  async function saveContact(payload: CustomerContactPayload) {
    if (!customer) {
      return;
    }
    setPending(true);
    setContactError("");
    try {
      if (selectedContact) {
        await api.put<CustomerContact>(`/customers/${customer.id}/contacts/${selectedContact.id}`, payload);
        showToast({ type: "success", title: "Ansprechpartner aktualisiert" });
      } else {
        await api.post<CustomerContact>(`/customers/${customer.id}/contacts`, payload);
        showToast({ type: "success", title: "Ansprechpartner erstellt" });
      }
      const response = await api.get<Customer>(`/customers/${customer.id}`);
      setCustomer(response.data);
      setContactOpen(false);
    } catch (err) {
      const message = getErrorMessage(err);
      setContactError(message);
      showToast({ type: "error", title: "Ansprechpartner konnte nicht gespeichert werden", description: message });
    } finally {
      setPending(false);
    }
  }

  async function confirmContactDelete() {
    if (!customer || !deleteContact) {
      return;
    }
    setPending(true);
    setDeleteError("");
    try {
      await api.delete(`/customers/${customer.id}/contacts/${deleteContact.id}`);
      const response = await api.get<Customer>(`/customers/${customer.id}`);
      setCustomer(response.data);
      showToast({ type: "success", title: "Ansprechpartner gelöscht", description: `${deleteContact.first_name} ${deleteContact.last_name}` });
      setDeleteContact(null);
    } catch (err) {
      const message = getErrorMessage(err);
      setDeleteError(message);
      showToast({ type: "error", title: "Ansprechpartner konnte nicht gelöscht werden", description: message });
    } finally {
      setPending(false);
    }
  }

  async function confirmCustomerDelete() {
    if (!customer) {
      return;
    }
    setPending(true);
    setDeleteError("");
    try {
      const deletedCustomerName = customer.company_name;
      await api.delete(`/customers/${customer.id}`);
      showToast({ type: "success", title: "Kunde gelöscht", description: deletedCustomerName });
      router.push("/customers");
    } catch (err) {
      const message = getErrorMessage(err);
      setDeleteError(message);
      showToast({ type: "error", title: "Kunde konnte nicht gelöscht werden", description: message });
    } finally {
      setPending(false);
    }
  }

  if (loading) {
    return <div className="rounded-lg border bg-white p-8 text-slate-500">Kunde wird geladen...</div>;
  }

  if (error || !customer) {
    return (
      <div className="space-y-4">
        <Link href="/customers" className="inline-flex items-center gap-2 text-sm text-slate-500 hover:text-slate-900">
          <ArrowLeft size={16} />
          Zurück zur Kundenliste
        </Link>
        <div className="rounded-lg border bg-white p-8 text-red-600">{error || "Kunde nicht gefunden"}</div>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
        <div>
          <Link href="/customers" className="inline-flex items-center gap-2 text-sm text-slate-500 hover:text-slate-900">
            <ArrowLeft size={16} />
            Zurück zur Kundenliste
          </Link>
          <div className="mt-3 flex items-center gap-3">
            <h1 className="text-3xl font-bold text-slate-950">{customer.company_name}</h1>
            <CustomerStatusBadge status={customer.status} />
          </div>
          <p className="mt-1 text-sm text-slate-500">{customer.customer_number}</p>
        </div>

        <div className="flex gap-2">
          {hasPermission(currentUser, "customers.update") && (
            <Button type="button" onClick={() => setFormOpen(true)}>
              <Edit size={16} />
              Bearbeiten
            </Button>
          )}
          {hasPermission(currentUser, "customers.delete") && (
            <Button type="button" variant="destructive" onClick={() => setDeleteCustomerOpen(true)}>
              <Trash2 size={16} />
              Löschen
            </Button>
          )}
        </div>
      </div>

      <DetailSection title="Stammdaten">
        <dl className="grid gap-5 md:grid-cols-2">
          <Detail label="Kundennummer" value={customer.customer_number} />
          <Detail label="Typ" value={customer.customer_type} />
          <Detail label="Rechtlicher Name" value={customer.legal_name || "-"} />
          <Detail label="Branche" value={customer.industry || "-"} />
          <Detail label="E-Mail" value={customer.email || "-"} />
          <Detail label="Telefon" value={customer.phone || "-"} />
          <Detail label="Website" value={customer.website || "-"} />
          <Detail label="USt-ID" value={customer.vat_id || "-"} />
        </dl>
      </DetailSection>

      <DetailSection title="Adressen">
        {customer.addresses.length === 0 ? (
          <p className="text-sm text-slate-500">Noch keine Adressen vorhanden.</p>
        ) : (
          <div className="grid gap-3 md:grid-cols-2">
            {customer.addresses.map((address) => (
              <div key={address.id} className="rounded-lg border p-4 text-sm">
                <div className="mb-2 flex items-center justify-between">
                  <span className="font-medium capitalize">{address.type}</span>
                  {address.is_primary && <span className="rounded-full bg-slate-100 px-2 py-1 text-xs">Primär</span>}
                </div>
                <p>{address.street || "-"}</p>
                <p>{address.postal_code} {address.city}</p>
                <p>{address.state}</p>
                <p>{address.country}</p>
              </div>
            ))}
          </div>
        )}
      </DetailSection>

      <DetailSection
        title="Ansprechpartner"
        actions={hasPermission(currentUser, "customers.update") && (
          <Button type="button" size="sm" onClick={() => openContactDialog(null)}>
            <Plus size={16} />
            Ansprechpartner
          </Button>
        )}
      >
        {customer.contacts.length === 0 ? (
          <p className="text-sm text-slate-500">Noch keine Ansprechpartner vorhanden.</p>
        ) : (
          <div className="grid gap-3 md:grid-cols-2">
            {customer.contacts.map((contact) => (
              <div key={contact.id} className="rounded-lg border p-4 text-sm">
                <div className="mb-2 flex items-center justify-between gap-3">
                  <div>
                    <p className="font-medium text-slate-950">{contact.first_name} {contact.last_name}</p>
                    <p className="text-slate-500">{contact.position || "-"}</p>
                  </div>
                  {contact.is_primary && <span className="rounded-full bg-slate-100 px-2 py-1 text-xs">Primär</span>}
                </div>
                <p>{contact.email || "-"}</p>
                <p>{contact.phone || contact.mobile || "-"}</p>
                {hasPermission(currentUser, "customers.update") && (
                  <div className="mt-3 flex gap-2">
                    <Button type="button" variant="outline" size="sm" onClick={() => openContactDialog(contact)}>
                      Bearbeiten
                    </Button>
                    <Button type="button" variant="destructive" size="sm" onClick={() => setDeleteContact(contact)}>
                      Löschen
                    </Button>
                  </div>
                )}
              </div>
            ))}
          </div>
        )}
      </DetailSection>

      <DetailSection title="Notizen">
        <p className="whitespace-pre-wrap text-sm text-slate-700">{customer.notes || "Noch keine Notizen vorhanden."}</p>
      </DetailSection>

      <DetailSection title="Metadaten">
        <dl className="grid gap-5 md:grid-cols-2">
          <Detail label="Erstellt" value={formatDateTime(customer.created_at)} />
          <Detail label="Aktualisiert" value={formatDateTime(customer.updated_at)} />
        </dl>
      </DetailSection>

      <CustomerFormDialog
        open={formOpen}
        customer={customer}
        pending={pending}
        serverError={formError}
        onOpenChange={setFormOpen}
        onSubmit={saveCustomer}
      />

      <CustomerContactFormDialog
        open={contactOpen}
        contact={selectedContact}
        pending={pending}
        serverError={contactError}
        onOpenChange={setContactOpen}
        onSubmit={saveContact}
      />

      <ConfirmDialog
        open={Boolean(deleteContact)}
        title="Ansprechpartner löschen"
        description="Möchten Sie den Ansprechpartner wirklich löschen?"
        pending={pending}
        onOpenChange={(open) => {
          if (!open) {
            setDeleteContact(null);
            setDeleteError("");
          }
        }}
        onConfirm={confirmContactDelete}
      >
        {deleteContact && <p className="text-sm font-medium">{deleteContact.first_name} {deleteContact.last_name}</p>}
        {deleteError && <p className="mt-2 text-sm text-red-600">{deleteError}</p>}
      </ConfirmDialog>

      <ConfirmDialog
        open={deleteCustomerOpen}
        title="Kunde löschen"
        description="Möchten Sie den Kunden wirklich löschen?"
        pending={pending}
        onOpenChange={(open) => {
          setDeleteCustomerOpen(open);
          if (!open) {
            setDeleteError("");
          }
        }}
        onConfirm={confirmCustomerDelete}
      >
        <p className="text-sm font-medium">{customer.customer_number} · {customer.company_name}</p>
        {deleteError && <p className="mt-2 text-sm text-red-600">{deleteError}</p>}
      </ConfirmDialog>
    </div>
  );
}

function Detail({ label, value }: { label: string; value: string }) {
  return (
    <div>
      <dt className="text-sm text-slate-500">{label}</dt>
      <dd className="mt-1 font-medium text-slate-950">{value}</dd>
    </div>
  );
}
