"use client";

import { useState, useMemo, useTransition, useEffect } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import {
  saveOfferEditor,
  toggleOfferArchived,
  renameOfferOption,
  type SaveOfferEditorPayload,
} from "@/app/admin/offers/actions";
import { OptionSelect } from "@/components/ui/option-select";
import { OptionMultiSelect } from "@/components/ui/option-multi-select";
import { EditableCell } from "@/components/ui/editable-cell";
import type { OfferEditorData, OfferFieldOptions, OfferTierData } from "@/lib/offer-queries";

type TierLetter = "A" | "B" | "C";
const TIER_LETTERS: TierLetter[] = ["A", "B", "C"];

function emptyTier(letter: TierLetter): OfferTierData {
  return {
    id: "",
    tier_letter: letter,
    internal_name: "",
    public_name: "",
    duration_months: 1,
    public_price: null,
    assignedServiceIds: [],
    servicesTotal: "0",
  };
}

function padTiers(tiers: OfferTierData[]): OfferTierData[] {
  return TIER_LETTERS.map(
    (letter) => tiers.find((t) => t.tier_letter === letter) ?? emptyTier(letter)
  );
}

function formatEuro(value: number): string {
  return `€${value.toLocaleString("it-IT", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}

function formatUnitPrice(raw: string): string {
  const num = parseFloat(raw);
  return `€${(isNaN(num) ? 0 : num).toLocaleString("it-IT", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}

type OfferType = "una_tantum" | "retainer";

type MacroFields = {
  internal_name: string;
  public_name: string;
  description: string;
  category: string | null;
  ticket: string | null;
  offer_type: OfferType;
  cliente_ideale: string;
  risultato: string;
  tempo: string;
  pain: string;
  metodo: string;
};

export function OfferEditorClient({
  data,
  fieldOptions,
}: {
  data: OfferEditorData;
  fieldOptions: OfferFieldOptions;
}) {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();
  const [saveError, setSaveError] = useState<string | null>(null);

  const [macro, setMacro] = useState<MacroFields>({
    internal_name: data.macro.internal_name,
    public_name: data.macro.public_name,
    description: data.macro.description ?? "",
    category: data.macro.category,
    ticket: data.macro.ticket,
    offer_type: (data.macro.offer_type === "retainer" ? "retainer" : "una_tantum") as OfferType,
    cliente_ideale: data.macro.cliente_ideale ?? "",
    risultato: data.macro.risultato ?? "",
    tempo: data.macro.tempo ?? "",
    pain: data.macro.pain ?? "",
    metodo: data.macro.metodo ?? "",
  });

  const [tiers, setTiers] = useState<OfferTierData[]>(() => padTiers(data.tiers));
  const [tipoTags, setTipoTags] = useState<string[]>(data.tipoTags);
  const [obiettivoTags, setObiettivoTags] = useState<string[]>(data.obiettivoTags);

  // After first draft save router.refresh() assigns real DB IDs to new tiers.
  // Re-sync tiers state when those IDs arrive so subsequent saves UPDATE instead of INSERT.
  const tierIdKey = data.tiers.map((t) => t.id).sort().join(",");
  useEffect(() => {
    setTiers(padTiers(data.tiers));
  }, [tierIdKey]); // eslint-disable-line react-hooks/exhaustive-deps

  const [categoriaOptions, setCategoriaOptions] = useState<string[]>(fieldOptions.categoria);
  const [ticketOptions, setTicketOptions] = useState<string[]>(fieldOptions.ticket);
  const [tipoOptions, setTipoOptions] = useState<string[]>(fieldOptions.tipo);
  const [obiettivoOptions, setObiettivoOptions] = useState<string[]>(fieldOptions.obiettivo);

  const [initialArchived] = useState<boolean>(data.macro.is_archived);
  const [savedDraft, setSavedDraft] = useState(false);
  const [offerFilter, setOfferFilter] = useState<string | null>(null);

  const offerFilterOptions = useMemo(() => {
    const all = new Set<string>();
    for (const s of data.availableServices) s.offerTags.forEach((t) => all.add(t));
    return Array.from(all).sort();
  }, [data.availableServices]);

  const filteredServices = useMemo(
    () =>
      offerFilter
        ? data.availableServices.filter((s) => s.offerTags.includes(offerFilter))
        : data.availableServices,
    [data.availableServices, offerFilter]
  );

  // Totals use the full catalog (not filtered) so changing category doesn't zero them.
  const serviceById = useMemo(
    () => new Map(data.availableServices.map((s) => [s.id, s])),
    [data.availableServices]
  );

  const tierTotals = useMemo(() => {
    return tiers.map((tier) =>
      tier.assignedServiceIds.reduce((sum, id) => {
        const service = serviceById.get(id);
        return sum + Number(service?.unit_price ?? 0);
      }, 0)
    );
  }, [tiers, serviceById]);

  const isDraft = !tiers.some((t) => t.assignedServiceIds.length > 0);

  function updateMacro<K extends keyof MacroFields>(key: K, value: MacroFields[K]) {
    setMacro((prev) => ({ ...prev, [key]: value }));
  }

  function toggleService(tierIdx: number, serviceId: string) {
    setTiers((prev) =>
      prev.map((tier, idx) => {
        if (idx !== tierIdx) return tier;
        const has = tier.assignedServiceIds.includes(serviceId);
        return {
          ...tier,
          assignedServiceIds: has
            ? tier.assignedServiceIds.filter((id) => id !== serviceId)
            : [...tier.assignedServiceIds, serviceId],
        };
      })
    );
  }

  function updateTierPublicPrice(tierIdx: number, value: string) {
    setTiers((prev) =>
      prev.map((tier, idx) => (idx === tierIdx ? { ...tier, public_price: value } : tier))
    );
  }

  function updateTierName(tierIdx: number, value: string) {
    setTiers((prev) =>
      prev.map((tier, idx) => (idx === tierIdx ? { ...tier, public_name: value } : tier))
    );
  }

  function handleSave() {
    setSaveError(null);
    const payload: SaveOfferEditorPayload = {
      internal_name: macro.internal_name,
      public_name: macro.public_name || macro.internal_name,
      description: macro.description,
      category: macro.category ?? undefined,
      ticket: macro.ticket ?? undefined,
      offer_type: macro.offer_type,
      cliente_ideale: macro.cliente_ideale,
      risultato: macro.risultato,
      tempo: macro.tempo,
      pain: macro.pain,
      metodo: macro.metodo,
      tiers: tiers.map((t) => {
        const tierName = t.public_name?.trim();
        return {
          id: t.id || undefined,
          tier_letter: (t.tier_letter ?? "A") as "A" | "B" | "C",
          internal_name: tierName || `Tier ${t.tier_letter}`,
          public_name: tierName || t.tier_letter || "Tier",
          duration_months: t.duration_months || 1,
          public_price: t.public_price ? Number(t.public_price) : null,
          assignedServiceIds: t.assignedServiceIds,
        };
      }),
      tipoTags,
      obiettivoTags,
    };

    startTransition(async () => {
      try {
        await saveOfferEditor(data.macro.id, payload);
        if (isDraft) {
          setSavedDraft(true);
          router.refresh();
        } else {
          router.push("/admin/offers");
        }
      } catch {
        setSaveError("Errore nel salvataggio. Verifica i campi.");
      }
    });
  }

  function handleArchive() {
    if (!window.confirm("Sei sicuro? L'offerta non sarà visibile nella lista.")) return;
    startTransition(async () => {
      try {
        await toggleOfferArchived(data.macro.id, true);
        router.push("/admin/offers");
      } catch {
        setSaveError("Errore nel salvataggio. Verifica i campi.");
      }
    });
  }

  function handleRestore() {
    if (!window.confirm("Ripristinare l'offerta? Tornerà visibile nella lista.")) return;
    startTransition(async () => {
      try {
        await toggleOfferArchived(data.macro.id, false);
        router.push("/admin/offers");
      } catch {
        setSaveError("Errore nel salvataggio. Verifica i campi.");
      }
    });
  }

  function handleRenameCategoria(oldValue: string, newValue: string) {
    setCategoriaOptions((prev) => prev.map((o) => (o === oldValue ? newValue : o)));
    if (macro.category === oldValue) updateMacro("category", newValue);
    startTransition(async () => {
      try {
        await renameOfferOption("categoria", oldValue, newValue);
      } catch {
        setSaveError("Errore nel salvataggio. Verifica i campi.");
      }
    });
  }

  function handleRenameTicket(oldValue: string, newValue: string) {
    setTicketOptions((prev) => prev.map((o) => (o === oldValue ? newValue : o)));
    if (macro.ticket === oldValue) updateMacro("ticket", newValue);
    startTransition(async () => {
      try {
        await renameOfferOption("ticket", oldValue, newValue);
      } catch {
        setSaveError("Errore nel salvataggio. Verifica i campi.");
      }
    });
  }

  function handleRenameTipo(oldValue: string, newValue: string) {
    setTipoOptions((prev) => prev.map((o) => (o === oldValue ? newValue : o)));
    setTipoTags((prev) => prev.map((t) => (t === oldValue ? newValue : t)));
    startTransition(async () => {
      try {
        await renameOfferOption("tipo", oldValue, newValue);
      } catch {
        setSaveError("Errore nel salvataggio. Verifica i campi.");
      }
    });
  }

  function handleRenameObiettivo(oldValue: string, newValue: string) {
    setObiettivoOptions((prev) => prev.map((o) => (o === oldValue ? newValue : o)));
    setObiettivoTags((prev) => prev.map((t) => (t === oldValue ? newValue : t)));
    startTransition(async () => {
      try {
        await renameOfferOption("obiettivo", oldValue, newValue);
      } catch {
        setSaveError("Errore nel salvataggio. Verifica i campi.");
      }
    });
  }

  return (
    <div className="max-w-4xl mx-auto py-8 px-4 space-y-8">
      {/* Header & navigation */}
      <div>
        <Link href="/admin/offers" className="text-sm text-[#71717a] hover:text-[#1a1a1a]">
          ← Indietro
        </Link>
        <div className="mt-2 flex items-center justify-between">
          <h2 className="text-xl font-semibold text-[#1a1a1a]">Modifica Offerta</h2>
        </div>
        <div className="mt-2">
          <h3 className="text-base font-semibold text-[#1a1a1a]">
            <EditableCell
              value={macro.internal_name}
              type="text"
              required
              onSave={(v) => updateMacro("internal_name", v)}
            />
          </h3>
        </div>

        {/* Modalità toggle — directly under title */}
        <div className="mt-3 flex items-center gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0">Modalità</span>
          <div className="inline-flex rounded-lg border border-[#e5e7eb] bg-[#fafafa] p-0.5">
            {([
              { value: "una_tantum", label: "Una tantum" },
              { value: "retainer", label: "Retainer" },
            ] as const).map((opt) => (
              <button
                key={opt.value}
                type="button"
                onClick={() => updateMacro("offer_type", opt.value)}
                className={`px-3 py-1 text-sm rounded-md transition-colors ${
                  macro.offer_type === opt.value
                    ? "bg-[#1A463C] text-white font-medium"
                    : "text-[#71717a] hover:text-[#1a1a1a]"
                }`}
              >
                {opt.label}
              </button>
            ))}
          </div>
        </div>

        {/* Descrizione — nota interna, non visibile al cliente */}
        <div className="mt-3 flex items-start gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0 pt-2">Descrizione</span>
          <textarea
            value={macro.description}
            onChange={(e) => updateMacro("description", e.target.value)}
            placeholder="Descrizione interna dell'offerta (non visibile al cliente)..."
            rows={3}
            className="flex-1 text-sm border border-[#e5e7eb] rounded-lg px-3 py-2 bg-white resize-none focus:outline-none focus:ring-2 focus:ring-[#1A463C]/30 text-[#1a1a1a] placeholder:text-[#aaaaaa]"
          />
        </div>
      </div>

      {/* Tags block */}
      <section className="space-y-4">
        <h3 className="text-base font-semibold text-[#1a1a1a]">Tag</h3>

        <div className="flex items-center gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0">Categoria</span>
          <OptionSelect
            value={macro.category}
            options={categoriaOptions}
            onChange={(v) => updateMacro("category", v)}
            onRename={handleRenameCategoria}
            placeholder="Seleziona categoria..."
          />
        </div>

        <div className="flex items-center gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0">Ticket</span>
          <OptionSelect
            value={macro.ticket}
            options={ticketOptions}
            onChange={(v) => updateMacro("ticket", v)}
            onRename={handleRenameTicket}
            placeholder="Seleziona ticket..."
          />
        </div>

        <div className="flex items-center gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0">Tipo</span>
          <OptionMultiSelect
            values={tipoTags}
            options={tipoOptions}
            onAdd={(v) => {
              setTipoTags((prev) => [...prev, v]);
              if (!tipoOptions.includes(v)) setTipoOptions((prev) => [...prev, v]);
            }}
            onRemove={(v) => setTipoTags((prev) => prev.filter((t) => t !== v))}
            onRename={handleRenameTipo}
            placeholder="+ Crea Tipo"
          />
        </div>

        <div className="flex items-center gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0">Obiettivo</span>
          <OptionMultiSelect
            values={obiettivoTags}
            options={obiettivoOptions}
            onAdd={(v) => {
              setObiettivoTags((prev) => [...prev, v]);
              if (!obiettivoOptions.includes(v)) setObiettivoOptions((prev) => [...prev, v]);
            }}
            onRemove={(v) => setObiettivoTags((prev) => prev.filter((t) => t !== v))}
            onRename={handleRenameObiettivo}
            placeholder="+ Crea Obiettivo"
          />
        </div>
      </section>

      {/* Services matrix */}
      <section className="space-y-3">
        <h3 className="text-base font-semibold text-[#1a1a1a]">Servizi Inclusi</h3>

        {/* Offer filter chips */}
        <div className="flex flex-wrap gap-2">
          <button
            type="button"
            onClick={() => setOfferFilter(null)}
            className={`text-xs px-3 py-1 rounded-full border transition-colors duration-150 ${
              offerFilter === null
                ? "bg-[#1A463C] text-white border-[#1A463C]"
                : "border-[#e5e7eb] text-[#71717a] hover:border-[#1A463C] hover:text-[#1A463C]"
            }`}
          >
            Tutti
          </button>
          {offerFilterOptions.map((opt) => (
            <button
              key={opt}
              type="button"
              onClick={() => setOfferFilter(offerFilter === opt ? null : opt)}
              className={`text-xs px-3 py-1 rounded-full border transition-colors duration-150 ${
                offerFilter === opt
                  ? "bg-[#1A463C] text-white border-[#1A463C]"
                  : "border-[#e5e7eb] text-[#71717a] hover:border-[#1A463C] hover:text-[#1A463C]"
              }`}
            >
              {opt}
            </button>
          ))}
        </div>

        <div className="bg-white rounded-xl border border-[#e5e7eb] overflow-hidden">
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead className="bg-[#f9f9f9] border-b border-[#e5e7eb]">
                <tr>
                  <th className="text-left py-2 px-3 font-semibold text-[#71717a]">Servizio</th>
                  <th className="text-right py-2 px-3 font-semibold text-[#71717a]">Prezzo</th>
                  {TIER_LETTERS.map((letter) => (
                    <th
                      key={letter}
                      className="text-center py-2 px-3 font-semibold text-[#71717a] w-12"
                    >
                      {letter}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {filteredServices.length === 0 ? (
                  <tr>
                    <td colSpan={2 + TIER_LETTERS.length} className="py-3 px-3 text-[#71717a]">
                      Nessun servizio disponibile per questa categoria
                    </td>
                  </tr>
                ) : (
                  filteredServices.map((service) => (
                    <tr
                      key={service.id}
                      className="border-b border-[#e5e7eb] hover:bg-[#f9f9f9] transition-colors duration-150 h-10"
                    >
                      <td className="py-2 px-3 text-[#1a1a1a]">{service.name}</td>
                      <td className="py-2 px-3 text-right tabular-nums text-[#1a1a1a]">
                        {formatUnitPrice(service.unit_price)}
                      </td>
                      {tiers.map((tier, tierIdx) => (
                        <td key={tier.tier_letter} className="py-2 px-3 text-center">
                          <input
                            type="checkbox"
                            checked={tier.assignedServiceIds.includes(service.id)}
                            onChange={() => toggleService(tierIdx, service.id)}
                            style={{ accentColor: "#1A463C" }}
                            className="h-4 w-4 cursor-pointer"
                          />
                        </td>
                      ))}
                    </tr>
                  ))
                )}
              </tbody>
              <tfoot>
                <tr className="border-t border-[#e5e7eb]">
                  <td className="py-2 px-3 font-semibold text-[#1a1a1a]" colSpan={2}>
                    Nome Tier
                  </td>
                  {tiers.map((tier, tierIdx) => (
                    <td key={tier.tier_letter} className="py-2 px-3 text-center">
                      <input
                        type="text"
                        value={tier.public_name ?? ""}
                        onChange={(e) => updateTierName(tierIdx, e.target.value)}
                        placeholder="Nome…"
                        className="w-20 text-center text-sm border border-[#e5e7eb] rounded px-1 py-1 focus-visible:ring-1 focus-visible:ring-primary focus:outline-none"
                      />
                    </td>
                  ))}
                </tr>
                <tr className="border-t border-[#e5e7eb]">
                  <td className="py-2 px-3 font-semibold text-[#1a1a1a]" colSpan={2}>
                    Totale Servizi
                  </td>
                  {tierTotals.map((total, idx) => (
                    <td
                      key={tiers[idx].tier_letter}
                      className="py-2 px-3 text-center font-semibold text-[#1a1a1a] tabular-nums"
                    >
                      {formatEuro(total)}
                    </td>
                  ))}
                </tr>
                <tr>
                  <td className="py-2 px-3 font-semibold text-[#1a1a1a]" colSpan={2}>
                    Prezzo Pubblico
                  </td>
                  {tiers.map((tier, tierIdx) => (
                    <td key={tier.tier_letter} className="py-2 px-3 text-center">
                      <input
                        type="number"
                        min="0"
                        step="0.01"
                        value={tier.public_price ?? ""}
                        onChange={(e) => updateTierPublicPrice(tierIdx, e.target.value)}
                        placeholder="€0,00"
                        className="w-20 text-center text-sm border border-[#e5e7eb] rounded px-1 py-1 tabular-nums focus-visible:ring-1 focus-visible:ring-primary focus:outline-none"
                      />
                    </td>
                  ))}
                </tr>
              </tfoot>
            </table>
          </div>
        </div>
      </section>

      {/* Transformation promise block */}
      <section className="space-y-4">
        <h3 className="text-base font-semibold text-[#1a1a1a]">Promessa di Trasformazione</h3>

        <div className="flex items-center gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0">Aiuto</span>
          <div className="flex-1">
            <EditableCell
              value={macro.cliente_ideale}
              type="text"
              placeholder="Aggiungi cliente ideale"
              onSave={(v) => updateMacro("cliente_ideale", v)}
            />
          </div>
        </div>

        <div className="flex items-center gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0">A ottenere</span>
          <div className="flex-1">
            <EditableCell
              value={macro.risultato}
              type="text"
              placeholder="Aggiungi risultato"
              onSave={(v) => updateMacro("risultato", v)}
            />
          </div>
        </div>

        <div className="flex items-center gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0">In</span>
          <div className="flex-1">
            <EditableCell
              value={macro.tempo}
              type="text"
              placeholder="Aggiungi durata (es. 3 mesi)"
              onSave={(v) => updateMacro("tempo", v)}
            />
          </div>
        </div>

        <div className="flex items-center gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0">Senza</span>
          <div className="flex-1">
            <EditableCell
              value={macro.pain}
              type="text"
              placeholder="Aggiungi pain point"
              onSave={(v) => updateMacro("pain", v)}
            />
          </div>
        </div>

        <div className="flex items-center gap-3">
          <span className="text-xs text-[#71717a] w-24 shrink-0">Grazie a</span>
          <div className="flex-1">
            <EditableCell
              value={macro.metodo}
              type="text"
              placeholder="Aggiungi metodo"
              onSave={(v) => updateMacro("metodo", v)}
            />
          </div>
        </div>
      </section>

      {/* Action buttons */}
      {saveError && <p className="text-sm text-red-600">{saveError}</p>}
      {savedDraft && !saveError && (
        <p className="text-sm text-[#1A463C]">Bozza salvata.</p>
      )}
      <div className="flex items-center gap-2">
        {isDraft ? (
          <button
            type="button"
            onClick={handleSave}
            disabled={isPending}
            className="border border-[#e5e7eb] text-[#1a1a1a] text-sm font-semibold px-6 py-4 rounded disabled:opacity-50 disabled:cursor-not-allowed hover:bg-[#f9f9f9] transition-colors duration-150"
          >
            Salva Bozza
          </button>
        ) : (
          <button
            type="button"
            onClick={handleSave}
            disabled={isPending}
            className="bg-[#1A463C] text-white text-sm font-semibold px-6 py-4 rounded disabled:opacity-50 disabled:cursor-not-allowed hover:bg-[#163a31] transition-colors duration-150"
          >
            Salva Offerta
          </button>
        )}
        <Link
          href="/admin/offers"
          className="border border-[#e5e7eb] text-[#1a1a1a] text-sm font-semibold px-6 py-4 rounded hover:bg-[#f9f9f9] transition-colors duration-150"
        >
          Annulla
        </Link>
        {!initialArchived && (
          <button
            type="button"
            onClick={handleArchive}
            disabled={isPending}
            className="text-[#dc2626] text-sm font-semibold px-6 py-4 rounded hover:bg-red-50 transition-colors duration-150 disabled:opacity-50"
          >
            Archivia
          </button>
        )}
        {initialArchived && (
          <button
            type="button"
            onClick={handleRestore}
            disabled={isPending}
            className="text-[#1A463C] text-sm font-semibold px-6 py-4 rounded hover:bg-[#f0f7f4] transition-colors duration-150 disabled:opacity-50"
          >
            Ripristina
          </button>
        )}
      </div>
    </div>
  );
}
