"use client";

import { useMemo, useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import Icon from "@/components/Icon";
import { useDialog } from "@/components/feedback/DialogProvider";
import { createInvoiceAdmin } from "../_actions";

export type ClientOption = {
  id: string;
  name: string;
  email: string;
  company: string | null;
  siret: string | null;
  addressStreet: string | null;
  addressZip: string | null;
  addressCity: string | null;
  addressCountry: string | null;
};

type EmitterDefaults = {
  name: string;
  tagline: string;
  email: string;
  addressLines: string;
  siret: string;
};

type LineItemState = {
  description: string;
  /** Saisi côté UI sous forme de string pour autoriser virgule + champ vide. */
  quantity: string;
  unitPriceHtEur: string;
};

type ClientState = {
  name: string;
  company: string;
  email: string;
  addressStreet: string;
  addressZip: string;
  addressCity: string;
  addressCountry: string;
  siret: string;
};

type EmitterState = EmitterDefaults;

type Status = "brouillon" | "envoyee" | "payee" | "annulee";

const STATUS_LABELS: Record<Status, string> = {
  brouillon: "Brouillon",
  envoyee: "Envoyée (à payer)",
  payee: "Payée",
  annulee: "Annulée",
};

function blankLine(): LineItemState {
  return { description: "", quantity: "1", unitPriceHtEur: "0" };
}

function todayIso(): string {
  return new Date().toISOString().slice(0, 10);
}

function plusDaysIso(days: number): string {
  const d = new Date();
  d.setDate(d.getDate() + days);
  return d.toISOString().slice(0, 10);
}

function parseNum(s: string): number {
  // Autorise la virgule en saisie française.
  const n = Number(s.replace(",", "."));
  return Number.isFinite(n) ? n : 0;
}

function formatEur(value: number): string {
  return new Intl.NumberFormat("fr-FR", {
    style: "currency",
    currency: "EUR",
  }).format(value);
}

export default function CreateInvoiceForm({
  clients,
  defaultEmitter,
}: {
  clients: ClientOption[];
  defaultEmitter: EmitterDefaults;
}) {
  const router = useRouter();
  const { toast } = useDialog();
  const [isSaving, startSaving] = useTransition();

  const [emitter, setEmitter] = useState<EmitterState>({ ...defaultEmitter });

  const [selectedClientId, setSelectedClientId] = useState<string>("");
  const [client, setClient] = useState<ClientState>({
    name: "",
    company: "",
    email: "",
    addressStreet: "",
    addressZip: "",
    addressCity: "",
    addressCountry: "France",
    siret: "",
  });

  const [lineItems, setLineItems] = useState<LineItemState[]>([blankLine()]);

  const [vatEnabled, setVatEnabled] = useState(false);
  const [vatRatePercent, setVatRatePercent] = useState("20");

  const [status, setStatus] = useState<Status>("brouillon");
  const [issuedAt, setIssuedAt] = useState(todayIso());
  const [dueAt, setDueAt] = useState(plusDaysIso(30));
  const [paidAt, setPaidAt] = useState("");
  const [paymentMethod, setPaymentMethod] = useState("");
  const [paymentReference, setPaymentReference] = useState("");

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

  const totals = useMemo(() => {
    const ht = lineItems.reduce(
      (acc, li) => acc + parseNum(li.quantity) * parseNum(li.unitPriceHtEur),
      0
    );
    const vat = vatEnabled ? ht * (parseNum(vatRatePercent) / 100) : 0;
    return { ht, vat, ttc: ht + vat };
  }, [lineItems, vatEnabled, vatRatePercent]);

  function onSelectClient(id: string) {
    setSelectedClientId(id);
    if (!id) return;
    const c = clients.find((x) => x.id === id);
    if (!c) return;
    setClient({
      name: c.name,
      company: c.company ?? "",
      email: c.email,
      addressStreet: c.addressStreet ?? "",
      addressZip: c.addressZip ?? "",
      addressCity: c.addressCity ?? "",
      addressCountry: c.addressCountry ?? "France",
      siret: c.siret ?? "",
    });
  }

  function updateLine(idx: number, patch: Partial<LineItemState>) {
    setLineItems((prev) =>
      prev.map((li, i) => (i === idx ? { ...li, ...patch } : li))
    );
  }

  function addLine() {
    setLineItems((prev) => [...prev, blankLine()]);
  }

  function removeLine(idx: number) {
    setLineItems((prev) =>
      prev.length === 1 ? prev : prev.filter((_, i) => i !== idx)
    );
  }

  function onSubmit() {
    setError(null);
    if (!client.name.trim()) {
      setError("Le nom du client est requis.");
      return;
    }
    if (lineItems.length === 0) {
      setError("Ajoutez au moins une ligne.");
      return;
    }
    if (lineItems.some((li) => !li.description.trim())) {
      setError("Chaque ligne doit avoir une description.");
      return;
    }
    startSaving(async () => {
      const result = await createInvoiceAdmin({
        clientUserId: selectedClientId || null,
        emitter: {
          name: emitter.name,
          tagline: emitter.tagline || null,
          email: emitter.email || null,
          addressLines: emitter.addressLines || null,
          siret: emitter.siret || null,
        },
        client: {
          name: client.name,
          company: client.company || null,
          email: client.email || null,
          addressStreet: client.addressStreet || null,
          addressZip: client.addressZip || null,
          addressCity: client.addressCity || null,
          addressCountry: client.addressCountry || null,
          siret: client.siret || null,
        },
        lineItems: lineItems.map((li) => ({
          description: li.description,
          quantity: parseNum(li.quantity),
          unitPriceHtEur: parseNum(li.unitPriceHtEur),
        })),
        vatEnabled,
        vatRatePercent: parseNum(vatRatePercent),
        status,
        issuedAt: issuedAt || null,
        dueAt: dueAt || null,
        paidAt: paidAt || null,
        paymentMethod: paymentMethod || null,
        paymentReference: paymentReference || null,
      });
      if (result.ok) {
        toast({
          message: `Facture ${result.invoiceNumber} créée.`,
          variant: "success",
        });
        router.push(`/socialexadmin/factures/${result.invoiceId}`);
        router.refresh();
      } else {
        setError(result.error);
      }
    });
  }

  return (
    <div className="space-y-8">
      {error && (
        <div
          role="alert"
          className="border border-error/40 px-5 py-4"
          style={{ backgroundColor: "rgba(186, 26, 26, 0.06)" }}
        >
          <p className="body-md text-error">{error}</p>
        </div>
      )}

      {/* Émetteur + client en deux colonnes */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
        <section className="bg-white border border-outline-variant p-8 space-y-6">
          <header>
            <span className="eyebrow">Émetteur</span>
            <h2 className="font-serif text-xl text-primary mt-1">
              Vos coordonnées
            </h2>
            <p className="text-xs text-on-surface-variant mt-2">
              Pré-rempli depuis Socialex. Éditable au cas par cas.
            </p>
          </header>

          <Field label="Nom / raison sociale">
            <Input
              value={emitter.name}
              onChange={(v) => setEmitter((p) => ({ ...p, name: v }))}
            />
          </Field>

          <Field label="Tagline (sous le nom)">
            <Input
              value={emitter.tagline}
              onChange={(v) => setEmitter((p) => ({ ...p, tagline: v }))}
            />
          </Field>

          <Field label="Email de contact">
            <Input
              value={emitter.email}
              onChange={(v) => setEmitter((p) => ({ ...p, email: v }))}
            />
          </Field>

          <Field label="Adresse (une ligne par ligne, facultatif)">
            <textarea
              value={emitter.addressLines}
              onChange={(e) =>
                setEmitter((p) => ({ ...p, addressLines: e.target.value }))
              }
              rows={3}
              className="w-full bg-transparent border border-outline-variant focus:border-secondary p-3 outline-none body-md transition-colors font-mono text-sm"
              placeholder="123 rue Exemple&#10;75001 Paris"
            />
          </Field>

          <Field label="SIRET (facultatif)">
            <Input
              value={emitter.siret}
              onChange={(v) => setEmitter((p) => ({ ...p, siret: v }))}
            />
          </Field>
        </section>

        <section className="bg-white border border-outline-variant p-8 space-y-6">
          <header>
            <span className="eyebrow">Client</span>
            <h2 className="font-serif text-xl text-primary mt-1">Facturé à</h2>
            <p className="text-xs text-on-surface-variant mt-2">
              Choisissez un client existant ou saisissez manuellement.
            </p>
          </header>

          <Field label="Client existant (facultatif)">
            <select
              value={selectedClientId}
              onChange={(e) => onSelectClient(e.target.value)}
              className="w-full bg-transparent border-0 border-b border-outline-variant focus:border-secondary py-3 outline-none body-md transition-colors"
            >
              <option value="">— Aucun (saisie manuelle) —</option>
              {clients.map((c) => (
                <option key={c.id} value={c.id}>
                  {c.name} · {c.email}
                  {c.company ? ` · ${c.company}` : ""}
                </option>
              ))}
            </select>
          </Field>

          <Field label="Nom / raison sociale">
            <Input
              value={client.name}
              onChange={(v) => setClient((p) => ({ ...p, name: v }))}
            />
          </Field>

          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <Field label="Société">
              <Input
                value={client.company}
                onChange={(v) => setClient((p) => ({ ...p, company: v }))}
              />
            </Field>
            <Field label="Email">
              <Input
                value={client.email}
                onChange={(v) => setClient((p) => ({ ...p, email: v }))}
              />
            </Field>
          </div>

          <Field label="Adresse">
            <Input
              value={client.addressStreet}
              onChange={(v) =>
                setClient((p) => ({ ...p, addressStreet: v }))
              }
            />
          </Field>

          <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
            <Field label="Code postal">
              <Input
                value={client.addressZip}
                onChange={(v) => setClient((p) => ({ ...p, addressZip: v }))}
              />
            </Field>
            <Field label="Ville">
              <Input
                value={client.addressCity}
                onChange={(v) =>
                  setClient((p) => ({ ...p, addressCity: v }))
                }
              />
            </Field>
            <Field label="Pays">
              <Input
                value={client.addressCountry}
                onChange={(v) =>
                  setClient((p) => ({ ...p, addressCountry: v }))
                }
              />
            </Field>
          </div>

          <Field label="SIRET (facultatif)">
            <Input
              value={client.siret}
              onChange={(v) => setClient((p) => ({ ...p, siret: v }))}
            />
          </Field>
        </section>
      </div>

      {/* Lignes */}
      <section className="bg-white border border-outline-variant p-8 space-y-6">
        <header className="flex items-center justify-between gap-4 flex-wrap">
          <div>
            <span className="eyebrow">Détail</span>
            <h2 className="font-serif text-xl text-primary mt-1">
              Lignes de facturation
            </h2>
          </div>
          <button
            type="button"
            onClick={addLine}
            className="inline-flex items-center gap-2 text-xs uppercase tracking-widest font-serif px-3 py-2 border border-outline-variant text-on-surface-variant hover:text-primary hover:border-primary transition-colors"
          >
            <Icon name="add" className="!text-base" />
            Ajouter une ligne
          </button>
        </header>

        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-outline-variant/60 text-left">
                <th className="eyebrow !text-on-surface-variant pb-3 pr-4 w-1/2">
                  Description
                </th>
                <th className="eyebrow !text-on-surface-variant pb-3 pr-4 w-24">
                  Quantité
                </th>
                <th className="eyebrow !text-on-surface-variant pb-3 pr-4 w-32">
                  Prix HT (€)
                </th>
                <th className="eyebrow !text-on-surface-variant pb-3 pr-4 w-32 text-right">
                  Total HT
                </th>
                <th className="pb-3 w-10" />
              </tr>
            </thead>
            <tbody>
              {lineItems.map((li, idx) => {
                const total =
                  parseNum(li.quantity) * parseNum(li.unitPriceHtEur);
                return (
                  <tr
                    key={idx}
                    className="border-b border-outline-variant/40 last:border-b-0 align-top"
                  >
                    <td className="py-3 pr-4">
                      <textarea
                        value={li.description}
                        onChange={(e) =>
                          updateLine(idx, { description: e.target.value })
                        }
                        rows={1}
                        placeholder="Désignation de la prestation"
                        className="w-full bg-transparent border-0 border-b border-outline-variant focus:border-secondary py-2 outline-none body-md transition-colors resize-y"
                      />
                    </td>
                    <td className="py-3 pr-4">
                      <input
                        type="text"
                        inputMode="decimal"
                        value={li.quantity}
                        onChange={(e) =>
                          updateLine(idx, { quantity: e.target.value })
                        }
                        className="w-full bg-transparent border-0 border-b border-outline-variant focus:border-secondary py-2 outline-none body-md transition-colors font-mono"
                      />
                    </td>
                    <td className="py-3 pr-4">
                      <input
                        type="text"
                        inputMode="decimal"
                        value={li.unitPriceHtEur}
                        onChange={(e) =>
                          updateLine(idx, { unitPriceHtEur: e.target.value })
                        }
                        className="w-full bg-transparent border-0 border-b border-outline-variant focus:border-secondary py-2 outline-none body-md transition-colors font-mono"
                      />
                    </td>
                    <td className="py-3 pr-4 text-right font-mono text-sm text-primary">
                      {formatEur(total)}
                    </td>
                    <td className="py-3 text-right">
                      <button
                        type="button"
                        onClick={() => removeLine(idx)}
                        disabled={lineItems.length === 1}
                        aria-label="Supprimer la ligne"
                        title="Supprimer la ligne"
                        className="p-2 text-on-surface-variant hover:text-error transition-colors disabled:opacity-30 disabled:cursor-not-allowed"
                      >
                        <Icon name="delete" className="!text-base" />
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        {/* TVA + totaux */}
        <div className="border-t border-outline-variant/40 pt-6 flex flex-col md:flex-row md:items-end gap-6 md:justify-between">
          <div className="flex items-center gap-4 flex-wrap">
            <label className="inline-flex items-center gap-3 text-sm cursor-pointer select-none">
              <input
                type="checkbox"
                checked={vatEnabled}
                onChange={(e) => setVatEnabled(e.target.checked)}
                className="size-4 accent-primary"
              />
              <span className="font-serif uppercase tracking-widest text-xs">
                Appliquer la TVA
              </span>
            </label>
            <div
              className={`flex items-center gap-2 transition-opacity ${
                vatEnabled ? "opacity-100" : "opacity-40 pointer-events-none"
              }`}
            >
              <input
                type="text"
                inputMode="decimal"
                value={vatRatePercent}
                onChange={(e) => setVatRatePercent(e.target.value)}
                className="w-20 bg-transparent border-0 border-b border-outline-variant focus:border-secondary py-2 outline-none body-md transition-colors font-mono text-right"
              />
              <span className="text-sm text-on-surface-variant">%</span>
            </div>
          </div>

          <dl className="text-sm space-y-1 min-w-[260px]">
            <div className="flex justify-between gap-8">
              <dt className="text-on-surface-variant">Total HT</dt>
              <dd className="font-mono">{formatEur(totals.ht)}</dd>
            </div>
            <div className="flex justify-between gap-8">
              <dt className="text-on-surface-variant">
                TVA{vatEnabled ? ` (${parseNum(vatRatePercent)} %)` : ""}
              </dt>
              <dd className="font-mono">
                {vatEnabled ? formatEur(totals.vat) : "—"}
              </dd>
            </div>
            <div className="flex justify-between gap-8 pt-2 border-t border-outline-variant/40">
              <dt className="font-serif uppercase tracking-widest text-xs pt-2">
                Total TTC
              </dt>
              <dd className="font-serif text-2xl text-secondary">
                {formatEur(totals.ttc)}
              </dd>
            </div>
          </dl>
        </div>
      </section>

      {/* Statut + dates */}
      <section className="bg-white border border-outline-variant p-8 space-y-6">
        <header>
          <span className="eyebrow">Métadonnées</span>
          <h2 className="font-serif text-xl text-primary mt-1">
            Statut et dates
          </h2>
        </header>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
          <Field label="Statut">
            <select
              value={status}
              onChange={(e) => setStatus(e.target.value as Status)}
              className="w-full bg-transparent border-0 border-b border-outline-variant focus:border-secondary py-3 outline-none body-md transition-colors"
            >
              {(Object.keys(STATUS_LABELS) as Status[]).map((s) => (
                <option key={s} value={s}>
                  {STATUS_LABELS[s]}
                </option>
              ))}
            </select>
          </Field>
          <Field label="Mode de paiement (facultatif)">
            <Input
              value={paymentMethod}
              onChange={setPaymentMethod}
              placeholder="Virement, CB, chèque…"
            />
          </Field>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
          <Field label="Date d'émission">
            <input
              type="date"
              value={issuedAt}
              onChange={(e) => setIssuedAt(e.target.value)}
              className="w-full bg-transparent border-0 border-b border-outline-variant focus:border-secondary py-3 outline-none body-md transition-colors"
            />
          </Field>
          <Field label="Échéance">
            <input
              type="date"
              value={dueAt}
              onChange={(e) => setDueAt(e.target.value)}
              className="w-full bg-transparent border-0 border-b border-outline-variant focus:border-secondary py-3 outline-none body-md transition-colors"
            />
          </Field>
          <Field label="Date de paiement (si payée)">
            <input
              type="date"
              value={paidAt}
              onChange={(e) => setPaidAt(e.target.value)}
              className="w-full bg-transparent border-0 border-b border-outline-variant focus:border-secondary py-3 outline-none body-md transition-colors"
            />
          </Field>
        </div>

        <Field label="Référence paiement (facultatif)">
          <Input value={paymentReference} onChange={setPaymentReference} />
        </Field>
      </section>

      <div className="flex items-center justify-end gap-3">
        <button
          type="button"
          onClick={onSubmit}
          disabled={isSaving}
          className="btn btn-primary disabled:opacity-50 disabled:cursor-not-allowed"
        >
          {isSaving ? "Création…" : "Créer la facture"}
        </button>
      </div>
    </div>
  );
}

function Field({
  label,
  children,
}: {
  label: string;
  children: React.ReactNode;
}) {
  return (
    <div>
      <label className="eyebrow !text-on-surface-variant block mb-2">
        {label}
      </label>
      {children}
    </div>
  );
}

function Input({
  value,
  onChange,
  placeholder,
}: {
  value: string;
  onChange: (v: string) => void;
  placeholder?: string;
}) {
  return (
    <input
      type="text"
      value={value}
      onChange={(e) => onChange(e.target.value)}
      placeholder={placeholder}
      className="w-full bg-transparent border-0 border-b border-outline-variant focus:border-secondary py-3 outline-none body-md transition-colors"
    />
  );
}
