"use client";

import { useEffect, useState } from "react";
import {
  Loader2,
  Mail,
  Calendar,
  CreditCard,
  CalendarClock,
  ShieldOff,
  ShieldCheck,
  RotateCcw,
  AlertTriangle,
  Check,
} from "lucide-react";
import { useRepositories } from "@/di/repository-provider";
import { useApiQuery } from "@/presentation/hooks/use-api-query";
import { useApiMutation } from "@/presentation/hooks/use-api-mutation";
import { useT, useLocale } from "@/shared/i18n/client";
import { formatDate } from "@/shared/lib/format-date";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "@/presentation/components/ui/dialog";
import { Button } from "@/presentation/components/ui/button";
import { Input } from "@/presentation/components/ui/input";
import { Switch } from "@/presentation/components/ui/switch";
import { Slider } from "@/presentation/components/ui/slider";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/presentation/components/ui/select";
import { Skeleton } from "@/presentation/components/ui/skeleton";
import ConfirmationDialog from "@/presentation/components/shared/confirmation-dialog";
import { BillingStatusBadge } from "@/presentation/components/billing/billing-status-badge";
import { BillingMandatePanel } from "@/presentation/components/billing/billing-mandate-panel";
import { BillingContractPanel } from "@/presentation/components/billing/billing-contract-panel";
import { BillingPennylanePanel } from "@/presentation/components/billing/billing-pennylane-panel";
import { BillingVehiclePlansPanel } from "@/presentation/components/billing/billing-vehicle-plans-panel";
import { BILLING_TOLERANCE_MIN, BILLING_TOLERANCE_MAX } from "@/shared/constants/billing";
import type {
  BillingOptions,
  BillingOption,
  PaymentMode,
} from "@/domain/entities/billing";

interface BillingGererDialogProps {
  clientId: number | null;
  open: boolean;
  onOpenChange: (open: boolean) => void;
  options: BillingOptions | null;
  defaultTolerance: number | null;
  onChanged: () => void;
}

const optLabel = (
  list: BillingOption[] | undefined,
  value: string | null | undefined
) => list?.find((o) => o.value === value)?.label ?? value ?? "—";

const clamp = (n: number) =>
  Math.min(BILLING_TOLERANCE_MAX, Math.max(BILLING_TOLERANCE_MIN, n));

export function BillingGererDialog({
  clientId,
  open,
  onOpenChange,
  options,
  defaultTolerance,
  onChanged,
}: BillingGererDialogProps) {
  const t = useT();
  const locale = useLocale();
  const repo = useRepositories().billingRepository;

  const { data: detail, loading, refetch } = useApiQuery(
    () => repo.findClient(clientId as number),
    { enabled: open && !!clientId, deps: [clientId, open] }
  );

  const [autoLock, setAutoLock] = useState(false);
  const [inheritDefault, setInheritDefault] = useState(true);
  const [tolerance, setTolerance] = useState(BILLING_TOLERANCE_MIN);
  const [paymentMode, setPaymentMode] = useState<string>("");
  const [suspendConfirm, setSuspendConfirm] = useState(false);
  // The contract's previews and the vehicles' plans read each other's changes.
  const [plansVersion, setPlansVersion] = useState(0);
  const [contractVersion, setContractVersion] = useState(0);

  // Seed the editable config once per open / client. Reading lock/status straight
  // from `detail` afterwards keeps action buttons live without clobbering edits.
  useEffect(() => {
    if (!open || !detail) return;
    setAutoLock(detail.auto_lock);
    setInheritDefault(detail.tolerance_override == null);
    setTolerance(
      clamp(detail.tolerance_override ?? detail.tolerance_months ?? defaultTolerance ?? BILLING_TOLERANCE_MIN)
    );
    // The backend sends { value, label }: the select holds the value.
    setPaymentMode(detail.payment_mode?.value ?? "");
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open, detail?.id]);

  const fmtMoney = (amount: number, currency = "EUR") =>
    new Intl.NumberFormat(locale === "fr" ? "fr-FR" : "en-US", {
      style: "currency",
      currency,
      maximumFractionDigits: 0,
    }).format(amount);

  const saveMutation = useApiMutation(
    ({ id, payload }: { id: number; payload: Parameters<typeof repo.updateClientConfig>[1] }) =>
      repo.updateClientConfig(id, payload),
    {
      successMessage: t.billing.toasts.configSaved,
      onSuccess: () => {
        onChanged();
        onOpenChange(false);
      },
    }
  );

  const suspendMutation = useApiMutation((id: number) => repo.suspendClient(id), {
    successMessage: t.billing.toasts.suspended,
    onSuccess: () => {
      setSuspendConfirm(false);
      refetch();
      onChanged();
    },
  });

  const reactivateMutation = useApiMutation((id: number) => repo.reactivateClient(id), {
    successMessage: t.billing.toasts.reactivated,
    onSuccess: () => {
      refetch();
      onChanged();
    },
  });

  const backToAutoMutation = useApiMutation(
    (id: number) => repo.updateClientConfig(id, { billing_lock_override: "auto" }),
    {
      successMessage: t.billing.toasts.backToAuto,
      onSuccess: () => {
        refetch();
        onChanged();
      },
    }
  );

  const markPaidMutation = useApiMutation((invoiceId: number) => repo.markInvoicePaid(invoiceId), {
    successMessage: t.billing.toasts.invoicePaid,
    onSuccess: () => {
      refetch();
      onChanged();
    },
  });

  const handleSave = () => {
    if (!detail) return;
    saveMutation.mutate({
      id: detail.id,
      payload: {
        billing_auto_lock: autoLock,
        billing_tolerance_months: inheritDefault ? null : tolerance,
        ...(paymentMode ? { billing_payment_mode: paymentMode as PaymentMode } : {}),
      },
    });
  };

  const effTol = inheritDefault
    ? defaultTolerance ?? detail?.tolerance_months ?? BILLING_TOLERANCE_MIN
    : tolerance;
  const unpaid = detail?.unpaid_count ?? 0;
  const willLock = autoLock && unpaid >= effTol && unpaid > 0;

  const invoices = (detail?.invoices ?? []).filter((inv) => !inv.paid);
  const actionBusy =
    suspendMutation.loading || reactivateMutation.loading || backToAutoMutation.loading;

  return (
    <>
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent
          className="max-w-xl max-h-[90vh] overflow-y-auto"
          onOpenAutoFocus={(e) => e.preventDefault()}
        >
          <DialogHeader>
            <DialogTitle>{detail?.client.name ?? t.billing.manageButton}</DialogTitle>
            <DialogDescription>{t.billing.manage.title}</DialogDescription>
          </DialogHeader>

          {loading && !detail ? (
            <div className="space-y-3">
              <Skeleton className="h-24 rounded-lg" />
              <Skeleton className="h-20 rounded-lg" />
              <Skeleton className="h-28 rounded-lg" />
            </div>
          ) : !detail ? (
            <p className="py-8 text-center text-sm text-muted-foreground">
              {t.billing.manage.notFound}
            </p>
          ) : (
            <div className="space-y-5">
              {/* Info grid */}
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-3">
                <InfoItem icon={Mail} label={t.billing.manage.contact}>
                  {detail.client.email ?? detail.client.contact ?? "—"}
                </InfoItem>
                <InfoItem icon={CreditCard} label={t.billing.manage.paymentMode}>
                  <Select value={paymentMode} onValueChange={setPaymentMode}>
                    <SelectTrigger size="sm" className="h-7 mt-0.5">
                      <SelectValue placeholder="—" />
                    </SelectTrigger>
                    <SelectContent>
                      {options?.payment_modes.map((o) => (
                        <SelectItem key={o.value} value={o.value}>
                          {o.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </InfoItem>
                <InfoItem icon={Calendar} label={t.billing.manage.subscriptionStart}>
                  {detail.subscription_started_at
                    ? formatDate(detail.subscription_started_at, locale)
                    : "—"}
                </InfoItem>
                <InfoItem icon={CalendarClock} label={t.billing.manage.lastPayment}>
                  {detail.last_payment_at ? formatDate(detail.last_payment_at, locale) : "—"}
                </InfoItem>
              </div>

              {/* Status block */}
              <div className="grid grid-cols-3 gap-3 rounded-xl border border-border bg-muted/30 p-4">
                <div>
                  <p className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground mb-1.5">
                    {t.billing.manage.statut}
                  </p>
                  <BillingStatusBadge status={detail.status} />
                </div>
                <div className="text-center">
                  <p className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground mb-1.5">
                    {t.billing.manage.unpaidMonths}
                  </p>
                  <p className="text-2xl font-bold leading-none">{detail.unpaid_count}</p>
                </div>
                <div className="text-right">
                  <p className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground mb-1.5">
                    {t.billing.manage.amountDue}
                  </p>
                  <p
                    className={`text-2xl font-bold leading-none ${
                      detail.amount_due > 0 ? "text-red-600" : ""
                    }`}
                  >
                    {fmtMoney(detail.amount_due, detail.currency)}
                  </p>
                </div>
              </div>

              {/* What the client is invoiced and at what price (billing automation, part 1) */}
              <BillingContractPanel
                clientId={detail.id}
                version={plansVersion}
                onChanged={() => { refetch(); setContractVersion((v) => v + 1); onChanged(); }}
              />

              {/* The plans each vehicle is billed, and the client's price per plan (plans per vehicle) */}
              <BillingVehiclePlansPanel
                clientId={detail.id}
                version={contractVersion}
                onChanged={() => { refetch(); setPlansVersion((v) => v + 1); onChanged(); }}
              />

              {/* The Pennylane customer its invoices go to, linked by hand */}
              <BillingPennylanePanel clientId={detail.id} />

              {/* SEPA direct debit mandate (billing automation, part 3) */}
              <BillingMandatePanel clientId={detail.id} onChanged={onChanged} />

              {/* Policy form */}
              <div className="rounded-xl border border-border p-4 space-y-4">
                <div className="flex items-start justify-between gap-4">
                  <div className="min-w-0">
                    <p className="font-medium text-sm">{t.billing.manage.autoLockTitle}</p>
                    <p className="text-xs text-muted-foreground mt-0.5">
                      {t.billing.manage.autoLockHelp}
                    </p>
                  </div>
                  <Switch checked={autoLock} onCheckedChange={setAutoLock} />
                </div>

                <div className="border-t border-border pt-4">
                  <p className="font-medium text-sm">{t.billing.manage.toleranceTitle}</p>
                  <p className="text-xs text-muted-foreground mt-0.5 mb-3">
                    {t.billing.manage.toleranceHelp}
                  </p>
                  <div className="flex items-center gap-4">
                    <Slider
                      min={BILLING_TOLERANCE_MIN}
                      max={BILLING_TOLERANCE_MAX}
                      step={1}
                      value={[effTol]}
                      onValueChange={([v]) => {
                        setInheritDefault(false);
                        setTolerance(v);
                      }}
                      className="flex-1"
                    />
                    <Input
                      type="number"
                      min={BILLING_TOLERANCE_MIN}
                      max={BILLING_TOLERANCE_MAX}
                      value={effTol}
                      onChange={(e) => {
                        setInheritDefault(false);
                        setTolerance(clamp(parseInt(e.target.value, 10) || BILLING_TOLERANCE_MIN));
                      }}
                      className="w-16 text-center"
                    />
                    <span className="text-sm text-muted-foreground">
                      {t.billing.months(effTol).replace(/^\d+\s*/, "")}
                    </span>
                  </div>
                  {inheritDefault ? (
                    <p className="text-[11px] text-muted-foreground mt-2">
                      {t.billing.manage.inheritsDefault}
                    </p>
                  ) : (
                    defaultTolerance != null && (
                      <button
                        type="button"
                        className="text-[11px] text-primary hover:underline mt-2"
                        onClick={() => {
                          setInheritDefault(true);
                          setTolerance(clamp(defaultTolerance));
                        }}
                      >
                        {t.billing.manage.useDefault(defaultTolerance)}
                      </button>
                    )
                  )}
                </div>

                {/* Dynamic warning */}
                {!autoLock ? (
                  <div className="flex gap-2 rounded-lg bg-amber-50 dark:bg-amber-950/30 border border-amber-200 dark:border-amber-900 p-3 text-xs text-amber-800 dark:text-amber-300">
                    <AlertTriangle className="w-4 h-4 shrink-0 mt-0.5" />
                    <span>{t.billing.manage.warnDisabled}</span>
                  </div>
                ) : willLock ? (
                  <div className="flex gap-2 rounded-lg bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-900 p-3 text-xs text-red-700 dark:text-red-300">
                    <AlertTriangle className="w-4 h-4 shrink-0 mt-0.5" />
                    <span>{t.billing.manage.warnWillLock(unpaid, effTol)}</span>
                  </div>
                ) : null}
              </div>

              {/* Account access (manual override) */}
              <div className="rounded-xl border border-border p-4 space-y-3">
                <div className="flex items-center justify-between gap-3">
                  <p className="font-medium text-sm">{t.billing.manage.accessTitle}</p>
                  <span className="text-xs text-muted-foreground">
                    {t.billing.manage.lockState}:{" "}
                    <span className="font-medium text-foreground">
                      {optLabel(options?.lock_overrides, detail.lock_override)}
                    </span>
                  </span>
                </div>
                <div className="flex flex-wrap gap-2">
                  {detail.lock_override !== "locked" && (
                    <Button
                      size="sm"
                      variant="outline"
                      className="gap-1.5 text-red-600"
                      disabled={actionBusy}
                      onClick={() => setSuspendConfirm(true)}
                    >
                      <ShieldOff className="w-4 h-4" />
                      {t.billing.manage.suspend}
                    </Button>
                  )}
                  {(detail.lock_override === "locked" || detail.status.value === "suspendu") && (
                    <Button
                      size="sm"
                      variant="outline"
                      className="gap-1.5 text-emerald-600"
                      disabled={actionBusy}
                      onClick={() => reactivateMutation.mutate(detail.id)}
                    >
                      <ShieldCheck className="w-4 h-4" />
                      {t.billing.manage.reactivate}
                    </Button>
                  )}
                  {detail.lock_override !== "auto" && (
                    <Button
                      size="sm"
                      variant="ghost"
                      className="gap-1.5 text-muted-foreground"
                      disabled={actionBusy}
                      onClick={() => backToAutoMutation.mutate(detail.id)}
                    >
                      <RotateCcw className="w-4 h-4" />
                      {t.billing.manage.backToAuto}
                    </Button>
                  )}
                </div>
              </div>

              {/* Invoices to reconcile */}
              {invoices.length > 0 && (
                <div className="rounded-xl border border-border p-4 space-y-2">
                  <p className="font-medium text-sm">{t.billing.manage.invoicesTitle}</p>
                  <div className="space-y-2">
                    {invoices.map((inv) => (
                      <div
                        key={inv.id}
                        className="flex items-center justify-between gap-3 rounded-lg bg-muted/40 px-3 py-2"
                      >
                        <div className="min-w-0 text-sm">
                          <span className="font-medium">
                            {inv.reference ?? inv.period ?? `#${inv.id}`}
                          </span>
                          {(inv.issued_at || inv.due_date) && (
                            <span className="text-xs text-muted-foreground ml-2">
                              {formatDate((inv.due_date ?? inv.issued_at) as string, locale)}
                            </span>
                          )}
                        </div>
                        <div className="flex items-center gap-3 shrink-0">
                          <span className="text-sm font-medium">
                            {fmtMoney(inv.amount, inv.currency ?? detail.currency)}
                          </span>
                          <Button
                            size="sm"
                            variant="outline"
                            className="h-7 gap-1.5"
                            disabled={markPaidMutation.loading}
                            onClick={() => markPaidMutation.mutate(inv.id)}
                          >
                            <Check className="w-3.5 h-3.5" />
                            {t.billing.manage.markPaid}
                          </Button>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* Footer */}
              <div className="flex justify-end gap-2 pt-1">
                <Button variant="outline" onClick={() => onOpenChange(false)}>
                  {t.common.cancel}
                </Button>
                <Button disabled={saveMutation.loading} onClick={handleSave}>
                  {saveMutation.loading && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
                  {t.billing.manage.save}
                </Button>
              </div>
            </div>
          )}
        </DialogContent>
      </Dialog>

      {detail && (
        <ConfirmationDialog
          open={suspendConfirm}
          onOpenChange={setSuspendConfirm}
          title={t.billing.suspendConfirm.title}
          description={t.billing.suspendConfirm.description(detail.client.name)}
          confirmLabel={t.billing.manage.suspend}
          variant="destructive"
          loading={suspendMutation.loading}
          onConfirm={() => suspendMutation.mutate(detail.id)}
        />
      )}
    </>
  );
}

function InfoItem({
  icon: Icon,
  label,
  children,
}: {
  icon: React.ComponentType<{ className?: string }>;
  label: string;
  children: React.ReactNode;
}) {
  return (
    <div className="min-w-0">
      <p className="flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground mb-1">
        <Icon className="w-3.5 h-3.5" />
        {label}
      </p>
      <div className="text-sm truncate">{children}</div>
    </div>
  );
}
