"use client";

import { Fragment, useMemo, useState, useTransition } from "react";
import { useRouter } from "next/navigation";

import { Spinner } from "@/components/common/Spinner";
import { ModalPortal } from "@/components/admin/common/ModalPortal";

type VehicleModelItem = { id: string; name: string; slug: string };
type VehicleMakeItem = { id: string; name: string; slug: string; models: VehicleModelItem[] };
type ServerAction = (formData: FormData) => Promise<void>;

function slugify(value: string) {
  return value
    .toLowerCase()
    .replace(/đ/g, "dj")
    .normalize("NFKD")
    .replace(/[̀-ͯ]/g, "")
    .replace(/[^a-z0-9\s-]/g, "")
    .trim()
    .replace(/\s+/g, "-")
    .replace(/-+/g, "-");
}

function fd(values: Record<string, string | number | null | undefined>) {
  const form = new FormData();
  for (const [k, v] of Object.entries(values)) {
    if (v === null || v === undefined) continue;
    form.set(k, String(v));
  }
  return form;
}

export function VehicleMakeManager({
  items,
  createMakeAction,
  updateMakeAction,
  deleteMakeAction,
  createModelAction,
  updateModelAction,
  deleteModelAction,
}: {
  items: VehicleMakeItem[];
  createMakeAction: ServerAction;
  updateMakeAction: ServerAction;
  deleteMakeAction: ServerAction;
  createModelAction: ServerAction;
  updateModelAction: ServerAction;
  deleteModelAction: ServerAction;
}) {
  const router = useRouter();
  const [, startTransition] = useTransition();
  const [busy, setBusy] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [search, setSearch] = useState("");
  const [collapsed, setCollapsed] = useState<Set<string>>(new Set());
  const [addMake, setAddMake] = useState(false);
  const [editMake, setEditMake] = useState<VehicleMakeItem | null>(null);
  const [addModelFor, setAddModelFor] = useState<VehicleMakeItem | null>(null);
  const [editModel, setEditModel] = useState<{ makeId: string; model: VehicleModelItem } | null>(null);

  const q = search.trim().toLowerCase();
  const makes = useMemo(() => {
    const list = items
      .map((m) => ({
        ...m,
        models: q ? m.models.filter((x) => x.name.toLowerCase().includes(q)) : m.models,
      }))
      .filter(
        (m) =>
          !q ||
          m.name.toLowerCase().includes(q) ||
          m.slug.toLowerCase().includes(q) ||
          m.models.length > 0,
      )
      .sort((a, b) => a.name.localeCompare(b.name, "sr"));
    return list;
  }, [items, q]);

  const totalModels = items.reduce((s, m) => s + m.models.length, 0);

  function runAction(action: ServerAction, formData: FormData, key: string, onDone?: () => void) {
    if (busy) return;
    setBusy(key);
    setError(null);
    startTransition(async () => {
      try {
        await action(formData);
        onDone?.();
        router.refresh();
      } catch (err) {
        const raw = err instanceof Error ? err.message : "";
        setError(
          /unique|already exists|duplicate|p2002|slug/i.test(raw)
            ? "Već postoji stavka sa tim slug-om. Promeni naziv ili upiši drugačiji slug."
            : "Čuvanje nije uspelo. Pokušaj ponovo.",
        );
      } finally {
        setBusy(null);
      }
    });
  }

  function toggle(id: string) {
    setCollapsed((p) => {
      const n = new Set(p);
      if (n.has(id)) n.delete(id);
      else n.add(id);
      return n;
    });
  }

  return (
    <div className="space-y-5">
      {error ? (
        <div className="fixed left-1/2 top-4 z-[140] flex max-w-[90vw] -translate-x-1/2 items-center gap-3 rounded-xl border border-danger/30 bg-white px-4 py-3 text-sm font-semibold text-danger shadow-2xl">
          <span>{error}</span>
          <button type="button" onClick={() => setError(null)} className="text-danger/60 hover:text-danger" aria-label="Zatvori">✕</button>
        </div>
      ) : null}

      <div className="surface rounded-[1.6rem] p-4 sm:p-5">
        <div className="flex flex-wrap items-center gap-3">
          <div className="flex flex-wrap gap-2 text-xs">
            <span className="rounded-full bg-accent/55 px-3 py-1.5 font-bold text-primary">{items.length} marki</span>
            <span className="rounded-full border border-border bg-white px-3 py-1.5 font-semibold text-muted-foreground">
              {totalModels} modela
            </span>
          </div>
          <div className="relative ml-auto min-w-[200px] flex-1 sm:max-w-xs">
            <span className="pointer-events-none absolute left-3.5 top-1/2 -translate-y-1/2 text-muted-foreground">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
                <circle cx="11" cy="11" r="7" />
                <path d="m21 21-4.3-4.3" />
              </svg>
            </span>
            <input
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Pretraži marke i modele…"
              className="h-11 w-full rounded-full border border-border bg-white pl-10 pr-4 text-sm"
            />
          </div>
          <button type="button" onClick={() => setAddMake(true)} className="primary-button inline-flex items-center gap-2">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round">
              <path d="M12 5v14M5 12h14" />
            </svg>
            Nova marka
          </button>
        </div>
      </div>

      <div className="surface overflow-hidden rounded-[1.6rem]">
        <div className="overflow-x-auto">
          <table className="w-full min-w-[640px] text-sm">
            <thead>
              <tr className="border-b border-border text-left text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                <th className="px-4 py-3">Marka / Model</th>
                <th className="px-4 py-3">Slug</th>
                <th className="px-4 py-3 text-center">Modela</th>
                <th className="px-4 py-3 text-right">Akcije</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-border/70">
              {makes.map((make) => {
                const open = Boolean(q) || !collapsed.has(make.id);
                return (
                  <Fragment key={make.id}>
                    <tr className="bg-white">
                      <td className="px-4 py-3">
                        <div className="flex items-center gap-2">
                          <button
                            type="button"
                            onClick={() => toggle(make.id)}
                            className="text-muted-foreground transition hover:text-foreground"
                            aria-label={open ? "Skupi" : "Razvij"}
                          >
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" className={`transition-transform ${open ? "rotate-90" : ""}`}>
                              <path d="m9 6 6 6-6 6" />
                            </svg>
                          </button>
                          <span className="font-semibold text-foreground">{make.name}</span>
                        </div>
                      </td>
                      <td className="px-4 py-3">
                        <code className="rounded bg-muted/60 px-1.5 py-0.5 text-xs text-muted-foreground">{make.slug}</code>
                      </td>
                      <td className="px-4 py-3 text-center text-muted-foreground">{make.models.length}</td>
                      <td className="px-4 py-3">
                        <div className="flex items-center justify-end gap-1.5">
                          <button type="button" onClick={() => setAddModelFor(make)} className="rounded-lg border border-border px-2.5 py-1.5 text-xs font-semibold text-muted-foreground transition hover:border-primary/30 hover:text-primary">
                            + model
                          </button>
                          <button type="button" onClick={() => setEditMake(make)} className="rounded-lg border border-border px-2.5 py-1.5 text-xs font-semibold text-foreground transition hover:border-primary/30 hover:text-primary">
                            Izmeni
                          </button>
                          <button
                            type="button"
                            onClick={() => {
                              if (window.confirm(`Obrisati marku „${make.name}" i sve njene modele?`))
                                runAction(deleteMakeAction, fd({ id: make.id }), `delmake:${make.id}`);
                            }}
                            disabled={busy === `delmake:${make.id}`}
                            className="inline-flex items-center gap-1 rounded-lg border border-danger/25 bg-danger/5 px-2.5 py-1.5 text-xs font-semibold text-danger transition hover:bg-danger/10 disabled:opacity-60"
                          >
                            {busy === `delmake:${make.id}` ? <Spinner className="h-3.5 w-3.5" /> : null}
                            Obriši
                          </button>
                        </div>
                      </td>
                    </tr>
                    {open
                      ? make.models.map((model) => (
                          <tr key={model.id} className="bg-muted/25">
                            <td className="px-4 py-2.5">
                              <span className="ml-7 text-foreground/90">• {model.name}</span>
                            </td>
                            <td className="px-4 py-2.5">
                              <code className="rounded bg-muted/60 px-1.5 py-0.5 text-xs text-muted-foreground">{model.slug}</code>
                            </td>
                            <td className="px-4 py-2.5" />
                            <td className="px-4 py-2.5">
                              <div className="flex items-center justify-end gap-1.5">
                                <button type="button" onClick={() => setEditModel({ makeId: make.id, model })} className="rounded-lg border border-border px-2.5 py-1 text-xs font-semibold text-foreground transition hover:border-primary/30 hover:text-primary">
                                  Izmeni
                                </button>
                                <button
                                  type="button"
                                  onClick={() => {
                                    if (window.confirm(`Obrisati model „${model.name}"?`))
                                      runAction(deleteModelAction, fd({ id: model.id, makeId: make.id }), `delmodel:${model.id}`);
                                  }}
                                  disabled={busy === `delmodel:${model.id}`}
                                  className="inline-flex items-center gap-1 rounded-lg border border-danger/25 bg-danger/5 px-2.5 py-1 text-xs font-semibold text-danger transition hover:bg-danger/10 disabled:opacity-60"
                                >
                                  {busy === `delmodel:${model.id}` ? <Spinner className="h-3.5 w-3.5" /> : null}
                                  Obriši
                                </button>
                              </div>
                            </td>
                          </tr>
                        ))
                      : null}
                  </Fragment>
                );
              })}
              {makes.length === 0 ? (
                <tr>
                  <td colSpan={4} className="px-4 py-10 text-center text-sm text-muted-foreground">
                    {q ? `Nema rezultata za „${search}".` : "Nema marki. Dodaj prvu."}
                  </td>
                </tr>
              ) : null}
            </tbody>
          </table>
        </div>
      </div>

      {/* Modal: nova marka */}
      {addMake ? (
        <MakeModal
          title="Nova marka"
          withModels
          busy={busy === "addmake"}
          onClose={() => setAddMake(false)}
          onSubmit={(v) => runAction(createMakeAction, fd(v), "addmake", () => setAddMake(false))}
        />
      ) : null}
      {editMake ? (
        <MakeModal
          title={`Izmena marke: ${editMake.name}`}
          make={editMake}
          busy={busy === `editmake:${editMake.id}`}
          onClose={() => setEditMake(null)}
          onSubmit={(v) =>
            runAction(updateMakeAction, fd({ id: editMake.id, ...v }), `editmake:${editMake.id}`, () => setEditMake(null))
          }
        />
      ) : null}

      {/* Modal: novi model */}
      {addModelFor ? (
        <ModelModal
          title={`Novi model za ${addModelFor.name}`}
          busy={busy === "addmodel"}
          onClose={() => setAddModelFor(null)}
          onSubmit={(v) =>
            runAction(createModelAction, fd({ makeId: addModelFor.id, ...v }), "addmodel", () => setAddModelFor(null))
          }
        />
      ) : null}
      {editModel ? (
        <ModelModal
          title={`Izmena modela: ${editModel.model.name}`}
          model={editModel.model}
          busy={busy === `editmodel:${editModel.model.id}`}
          onClose={() => setEditModel(null)}
          onSubmit={(v) =>
            runAction(
              updateModelAction,
              fd({ id: editModel.model.id, makeId: editModel.makeId, ...v }),
              `editmodel:${editModel.model.id}`,
              () => setEditModel(null),
            )
          }
        />
      ) : null}
    </div>
  );
}

function ModalShell({ title, onClose, children }: { title: string; onClose: () => void; children: React.ReactNode }) {
  return (
    <ModalPortal>
    <div className="fixed inset-0 z-[120] flex items-center justify-center p-4">
      <div className="absolute inset-0 bg-black/40 backdrop-blur-sm" onClick={onClose} />
      <div className="relative w-full max-w-md rounded-[1.6rem] border border-border bg-white p-6 shadow-2xl">
        <div className="flex items-start justify-between gap-3">
          <h3 className="text-lg font-semibold text-foreground">{title}</h3>
          <button type="button" onClick={onClose} className="text-muted-foreground hover:text-foreground" aria-label="Zatvori">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
              <path d="M18 6 6 18M6 6l12 12" />
            </svg>
          </button>
        </div>
        <div className="mt-5">{children}</div>
      </div>
    </div>
    </ModalPortal>
  );
}

function MakeModal({
  title,
  make,
  withModels,
  busy,
  onClose,
  onSubmit,
}: {
  title: string;
  make?: VehicleMakeItem;
  withModels?: boolean;
  busy: boolean;
  onClose: () => void;
  onSubmit: (values: Record<string, string>) => void;
}) {
  const [name, setName] = useState(make?.name ?? "");
  const [slug, setSlug] = useState(make?.slug ?? "");
  const [slugTouched, setSlugTouched] = useState(Boolean(make?.slug));
  const [models, setModels] = useState("");

  return (
    <ModalShell title={title} onClose={onClose}>
      <div className="space-y-4">
        <label className="block">
          <span className="text-xs font-semibold text-muted-foreground">Naziv marke *</span>
          <input
            value={name}
            onChange={(e) => {
              setName(e.target.value);
              if (!slugTouched) setSlug(slugify(e.target.value));
            }}
            className="mt-1 h-11 w-full rounded-xl border border-border bg-white px-3.5"
            autoFocus
          />
        </label>
        <label className="block">
          <span className="text-xs font-semibold text-muted-foreground">Slug</span>
          <input
            value={slug}
            onChange={(e) => {
              setSlug(e.target.value);
              setSlugTouched(true);
            }}
            className="mt-1 h-11 w-full rounded-xl border border-border bg-white px-3.5 font-mono text-sm"
            placeholder="auto iz naziva"
          />
        </label>
        {withModels ? (
          <label className="block">
            <span className="text-xs font-semibold text-muted-foreground">Modeli (opciono, po jedan u redu)</span>
            <textarea
              value={models}
              onChange={(e) => setModels(e.target.value)}
              className="mt-1 min-h-28 w-full resize-y rounded-xl border border-border bg-white px-3.5 py-2.5"
              placeholder={"A4\nA6\nQ5"}
            />
          </label>
        ) : null}
      </div>
      <div className="mt-6 flex justify-end gap-2">
        <button type="button" onClick={onClose} className="ghost-button">Otkaži</button>
        <button
          type="button"
          disabled={!name.trim() || busy}
          onClick={() => {
            if (!name.trim() || busy) return;
            const v: Record<string, string> = { name: name.trim(), slug: slug.trim() || slugify(name) };
            if (withModels) v.models = models;
            onSubmit(v);
          }}
          className="primary-button inline-flex items-center gap-2 disabled:opacity-60"
        >
          {busy ? <Spinner className="h-4 w-4" /> : null}
          {busy ? "Čuvam…" : "Sačuvaj"}
        </button>
      </div>
    </ModalShell>
  );
}

function ModelModal({
  title,
  model,
  busy,
  onClose,
  onSubmit,
}: {
  title: string;
  model?: VehicleModelItem;
  busy: boolean;
  onClose: () => void;
  onSubmit: (values: Record<string, string>) => void;
}) {
  const [name, setName] = useState(model?.name ?? "");
  const [slug, setSlug] = useState(model?.slug ?? "");
  const [slugTouched, setSlugTouched] = useState(Boolean(model?.slug));

  return (
    <ModalShell title={title} onClose={onClose}>
      <div className="space-y-4">
        <label className="block">
          <span className="text-xs font-semibold text-muted-foreground">Naziv modela *</span>
          <input
            value={name}
            onChange={(e) => {
              setName(e.target.value);
              if (!slugTouched) setSlug(slugify(e.target.value));
            }}
            className="mt-1 h-11 w-full rounded-xl border border-border bg-white px-3.5"
            autoFocus
          />
        </label>
        <label className="block">
          <span className="text-xs font-semibold text-muted-foreground">Slug</span>
          <input
            value={slug}
            onChange={(e) => {
              setSlug(e.target.value);
              setSlugTouched(true);
            }}
            className="mt-1 h-11 w-full rounded-xl border border-border bg-white px-3.5 font-mono text-sm"
            placeholder="auto iz naziva"
          />
        </label>
      </div>
      <div className="mt-6 flex justify-end gap-2">
        <button type="button" onClick={onClose} className="ghost-button">Otkaži</button>
        <button
          type="button"
          disabled={!name.trim() || busy}
          onClick={() => {
            if (!name.trim() || busy) return;
            onSubmit({ name: name.trim(), slug: slug.trim() || slugify(name) });
          }}
          className="primary-button inline-flex items-center gap-2 disabled:opacity-60"
        >
          {busy ? <Spinner className="h-4 w-4" /> : null}
          {busy ? "Čuvam…" : "Sačuvaj"}
        </button>
      </div>
    </ModalShell>
  );
}
