"use client";

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

import { Spinner } from "@/components/common/Spinner";
import { ThreeDIcon, type ThreeDIconName } from "@/components/public/common/ThreeDIcon";
import { ModalPortal } from "@/components/admin/common/ModalPortal";

type CategoryItem = {
  id: string;
  nameSr: string;
  nameEn?: string | null;
  slug: string;
  icon?: string | null;
  parentId?: string | null;
  sortOrder: number;
  isActive: boolean;
  parent?: { id: string; nameSr: string; slug: string } | null;
  children?: Array<{ id: string; nameSr: string; slug: string }>;
  _count?: { companies: number } | null;
};

type ServerAction = (formData: FormData) => Promise<void>;

/** Imena ikona koja portal stvarno ume da renderuje (ThreeDIcon LINE_GLYPHS). */
const ICON_OPTIONS: ThreeDIconName[] = [
  "companies", "places", "pin", "events", "calendar", "realestate", "home", "cars", "car",
  "jobs", "briefcase", "store", "shopping", "tag", "price", "card", "delivery", "tech", "tools",
  "construction", "industry", "beauty", "spa", "agriculture", "sport", "gym", "tourism", "hotel",
  "restaurant", "coffee", "education", "kids", "clinic", "building", "globe", "mail", "phone",
  "heart", "review", "medal", "trust", "verified", "security", "camera", "gallery", "document",
  "wifi", "parking", "pool", "music", "pet", "outdoor", "reservation", "accessibility",
];

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 | boolean | null | undefined>) {
  const form = new FormData();
  for (const [key, value] of Object.entries(values)) {
    if (value === null || value === undefined) continue;
    form.set(key, String(value));
  }
  return form;
}

export function CategoryManager({
  items,
  createAction,
  updateAction,
  deleteAction,
}: {
  items: CategoryItem[];
  createAction: ServerAction;
  updateAction: ServerAction;
  deleteAction: 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 [filter, setFilter] = useState<"all" | "main" | "sub">("all");
  const [collapsed, setCollapsed] = useState<Set<string>>(new Set());
  const [editing, setEditing] = useState<CategoryItem | null>(null);
  const [adding, setAdding] = useState<{ parentId: string | null } | null>(null);

  const mains = useMemo(
    () =>
      items
        .filter((c) => !c.parentId)
        .sort((a, b) => a.sortOrder - b.sortOrder || a.nameSr.localeCompare(b.nameSr, "sr")),
    [items],
  );
  const subsByParent = useMemo(() => {
    const map = new Map<string, CategoryItem[]>();
    for (const c of items) {
      if (!c.parentId) continue;
      const arr = map.get(c.parentId) ?? [];
      arr.push(c);
      map.set(c.parentId, arr);
    }
    for (const arr of map.values())
      arr.sort((a, b) => a.sortOrder - b.sortOrder || a.nameSr.localeCompare(b.nameSr, "sr"));
    return map;
  }, [items]);

  const q = search.trim().toLowerCase();
  function matches(c: CategoryItem) {
    if (!q) return true;
    return (
      c.nameSr.toLowerCase().includes(q) ||
      (c.nameEn ?? "").toLowerCase().includes(q) ||
      c.slug.toLowerCase().includes(q)
    );
  }

  // Redovi za tabelu: u režimu pretrage/filtera „pod" idemo flat; inače stablo.
  type Row = { cat: CategoryItem; isMain: boolean; subCount: number };
  const rows: Row[] = [];
  const flatMode = Boolean(q) || filter === "sub";
  if (flatMode) {
    for (const c of items) {
      if (filter === "main" && c.parentId) continue;
      if (filter === "sub" && !c.parentId) continue;
      if (!matches(c)) continue;
      rows.push({ cat: c, isMain: !c.parentId, subCount: subsByParent.get(c.id)?.length ?? 0 });
    }
    rows.sort((a, b) => a.cat.nameSr.localeCompare(b.cat.nameSr, "sr"));
  } else {
    for (const main of mains) {
      rows.push({ cat: main, isMain: true, subCount: subsByParent.get(main.id)?.length ?? 0 });
      if (filter === "main") continue;
      if (collapsed.has(main.id)) continue;
      for (const sub of subsByParent.get(main.id) ?? [])
        rows.push({ cat: sub, isMain: false, subCount: 0 });
    }
  }

  function toggleCollapse(id: string) {
    setCollapsed((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  }

  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 kategorija sa tim slug-om. Promeni naziv ili upiši drugačiji slug."
            : "Čuvanje nije uspelo. Pokušaj ponovo.",
        );
      } finally {
        setBusy(null);
      }
    });
  }

  function handleDelete(cat: CategoryItem) {
    const subCount = subsByParent.get(cat.id)?.length ?? 0;
    const msg = subCount
      ? `„${cat.nameSr}" ima ${subCount} podkategorija. Brisanje može uticati i na njih. Obrisati?`
      : `Obrisati kategoriju „${cat.nameSr}"?`;
    if (!window.confirm(msg)) return;
    runAction(deleteAction, fd({ id: cat.id }), `delete:${cat.id}`);
  }

  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}

      {/* ── Toolbar ─────────────────────────────────────────────────── */}
      <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} ukupno
            </span>
            <span className="rounded-full border border-border bg-white px-3 py-1.5 font-semibold text-muted-foreground">
              {mains.length} glavnih
            </span>
            <span className="rounded-full border border-border bg-white px-3 py-1.5 font-semibold text-muted-foreground">
              {items.length - mains.length} podkategorija
            </span>
          </div>

          <div className="relative ml-auto min-w-[220px] 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 kategorije…"
              className="h-11 w-full rounded-full border border-border bg-white pl-10 pr-4 text-sm"
            />
          </div>

          <div className="flex rounded-full border border-border bg-white p-1 text-sm">
            {([
              ["all", "Sve"],
              ["main", "Glavne"],
              ["sub", "Podkategorije"],
            ] as const).map(([key, label]) => (
              <button
                key={key}
                type="button"
                onClick={() => setFilter(key)}
                className={`rounded-full px-3.5 py-1.5 font-semibold transition ${
                  filter === key ? "bg-primary text-white" : "text-muted-foreground hover:text-foreground"
                }`}
              >
                {label}
              </button>
            ))}
          </div>

          <button
            type="button"
            onClick={() => setAdding({ parentId: null })}
            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 kategorija
          </button>
        </div>
      </div>

      {/* ── Tabela ──────────────────────────────────────────────────── */}
      <div className="surface overflow-hidden rounded-[1.6rem]">
        <div className="overflow-x-auto">
          <table className="w-full min-w-[820px] 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">Kategorija</th>
                <th className="px-4 py-3">Naziv (EN)</th>
                <th className="px-4 py-3">Slug</th>
                <th className="px-4 py-3">Roditelj</th>
                <th className="px-4 py-3 text-center">Firme</th>
                <th className="px-4 py-3 text-center">Redosled</th>
                <th className="px-4 py-3 text-center">Status</th>
                <th className="px-4 py-3 text-right">Akcije</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-border/70">
              {rows.map(({ cat, isMain, subCount }) => (
                <tr key={cat.id} className={isMain ? "bg-white" : "bg-muted/25"}>
                  <td className="px-4 py-3">
                    <div className="flex items-center gap-2">
                      {isMain && !flatMode ? (
                        <button
                          type="button"
                          onClick={() => toggleCollapse(cat.id)}
                          className="text-muted-foreground transition hover:text-foreground"
                          aria-label={collapsed.has(cat.id) ? "Razvij" : "Skupi"}
                        >
                          <svg
                            width="16"
                            height="16"
                            viewBox="0 0 24 24"
                            fill="none"
                            stroke="currentColor"
                            strokeWidth="2.2"
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            className={`transition-transform ${collapsed.has(cat.id) ? "" : "rotate-90"}`}
                          >
                            <path d="m9 6 6 6-6 6" />
                          </svg>
                        </button>
                      ) : (
                        <span className={isMain ? "w-4" : "ml-5 w-2 text-muted-foreground"}>{isMain ? "" : "•"}</span>
                      )}
                      {cat.icon ? (
                        <ThreeDIcon name={cat.icon as ThreeDIconName} size="xs" />
                      ) : (
                        <span className="inline-flex h-6 w-6 items-center justify-center rounded-lg border border-dashed border-border text-[0.6rem] text-muted-foreground">
                          —
                        </span>
                      )}
                      <span className={`${isMain ? "font-semibold text-foreground" : "text-foreground/90"}`}>
                        {cat.nameSr}
                      </span>
                      {isMain && subCount > 0 ? (
                        <span className="rounded-full bg-accent/55 px-2 py-0.5 text-[0.65rem] font-bold text-primary">
                          {subCount}
                        </span>
                      ) : null}
                    </div>
                  </td>
                  <td className="px-4 py-3 text-muted-foreground">{cat.nameEn || "—"}</td>
                  <td className="px-4 py-3">
                    <code className="rounded bg-muted/60 px-1.5 py-0.5 text-xs text-muted-foreground">
                      {cat.slug}
                    </code>
                  </td>
                  <td className="px-4 py-3 text-muted-foreground">{cat.parent?.nameSr || "—"}</td>
                  <td className="px-4 py-3 text-center">
                    {cat._count?.companies ? (
                      <span className="inline-flex min-w-[2rem] items-center justify-center rounded-full bg-accent/45 px-2 py-0.5 text-xs font-semibold text-primary">
                        {cat._count.companies}
                      </span>
                    ) : (
                      <span className="text-xs text-muted-foreground">0</span>
                    )}
                  </td>
                  <td className="px-4 py-3 text-center text-muted-foreground">{cat.sortOrder}</td>
                  <td className="px-4 py-3 text-center">
                    {cat.isActive ? (
                      <span className="inline-flex items-center gap-1 rounded-full bg-emerald-50 px-2.5 py-0.5 text-xs font-semibold text-emerald-700">
                        <span className="h-1.5 w-1.5 rounded-full bg-emerald-500" /> Aktivna
                      </span>
                    ) : (
                      <span className="inline-flex items-center gap-1 rounded-full bg-zinc-100 px-2.5 py-0.5 text-xs font-semibold text-zinc-500">
                        <span className="h-1.5 w-1.5 rounded-full bg-zinc-400" /> Neaktivna
                      </span>
                    )}
                  </td>
                  <td className="px-4 py-3">
                    <div className="flex items-center justify-end gap-1.5">
                      {isMain ? (
                        <button
                          type="button"
                          onClick={() => setAdding({ parentId: cat.id })}
                          title="Dodaj podkategoriju"
                          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"
                        >
                          + pod
                        </button>
                      ) : null}
                      <button
                        type="button"
                        onClick={() => setEditing(cat)}
                        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={() => handleDelete(cat)}
                        disabled={busy === `delete:${cat.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 === `delete:${cat.id}` ? <Spinner className="h-3.5 w-3.5" /> : null}
                        Obriši
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
              {rows.length === 0 ? (
                <tr>
                  <td colSpan={8} className="px-4 py-10 text-center text-sm text-muted-foreground">
                    {q ? `Nema rezultata za „${search}".` : "Nema kategorija. Dodaj prvu glavnu kategoriju."}
                  </td>
                </tr>
              ) : null}
            </tbody>
          </table>
        </div>
      </div>

      {/* ── Modal: dodavanje ────────────────────────────────────────── */}
      {adding ? (
        <CategoryFormModal
          title={adding.parentId ? "Nova podkategorija" : "Nova glavna kategorija"}
          mains={mains}
          initialParentId={adding.parentId}
          busy={busy === "create"}
          onClose={() => setAdding(null)}
          onSubmit={(values) =>
            runAction(createAction, fd(values), "create", () => setAdding(null))
          }
        />
      ) : null}

      {/* ── Modal: izmena ───────────────────────────────────────────── */}
      {editing ? (
        <CategoryFormModal
          title={`Izmena: ${editing.nameSr}`}
          mains={mains.filter((m) => m.id !== editing.id)}
          category={editing}
          initialParentId={editing.parentId ?? null}
          busy={busy === `edit:${editing.id}`}
          onClose={() => setEditing(null)}
          onSubmit={(values) =>
            runAction(
              updateAction,
              fd({ id: editing.id, ...values }),
              `edit:${editing.id}`,
              () => setEditing(null),
            )
          }
        />
      ) : null}
    </div>
  );
}

/* ── Modal forma (add/edit) ──────────────────────────────────────────── */
function CategoryFormModal({
  title,
  mains,
  category,
  initialParentId,
  busy,
  onClose,
  onSubmit,
}: {
  title: string;
  mains: CategoryItem[];
  category?: CategoryItem;
  initialParentId: string | null;
  busy: boolean;
  onClose: () => void;
  onSubmit: (values: Record<string, string | number | boolean>) => void;
}) {
  const [nameSr, setNameSr] = useState(category?.nameSr ?? "");
  const [nameEn, setNameEn] = useState(category?.nameEn ?? "");
  const [slug, setSlug] = useState(category?.slug ?? "");
  const [slugTouched, setSlugTouched] = useState(Boolean(category?.slug));
  const [icon, setIcon] = useState<string>(category?.icon ?? "");
  const [parentId, setParentId] = useState<string>(initialParentId ?? "");
  const [sortOrder, setSortOrder] = useState<number>(category?.sortOrder ?? 0);
  const [isActive, setIsActive] = useState<boolean>(category?.isActive ?? true);
  const [iconOpen, setIconOpen] = useState(false);

  function changeName(value: string) {
    setNameSr(value);
    if (!slugTouched) setSlug(slugify(value));
  }

  function submit() {
    if (!nameSr.trim() || busy) return;
    onSubmit({
      nameSr: nameSr.trim(),
      nameEn: nameEn.trim(),
      slug: slug.trim() || slugify(nameSr),
      icon,
      parentId,
      sortOrder,
      isActive,
    });
  }

  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-lg 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 space-y-4">
          <div className="grid gap-4 sm:grid-cols-2">
            <label className="block">
              <span className="text-xs font-semibold text-muted-foreground">Naziv (SR) *</span>
              <input
                value={nameSr}
                onChange={(e) => changeName(e.target.value)}
                className="mt-1 h-11 w-full rounded-xl border border-border bg-white px-3.5"
                placeholder="npr. Zdravstvo"
                autoFocus
              />
            </label>
            <label className="block">
              <span className="text-xs font-semibold text-muted-foreground">Naziv (EN)</span>
              <input
                value={nameEn}
                onChange={(e) => setNameEn(e.target.value)}
                className="mt-1 h-11 w-full rounded-xl border border-border bg-white px-3.5"
                placeholder="Healthcare"
              />
            </label>
          </div>

          <div className="grid gap-4 sm:grid-cols-2">
            <label className="block">
              <span className="text-xs font-semibold text-muted-foreground">Slug (URL)</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>
            <label className="block">
              <span className="text-xs font-semibold text-muted-foreground">Roditelj</span>
              <select
                value={parentId}
                onChange={(e) => setParentId(e.target.value)}
                className="mt-1 h-11 w-full rounded-xl border border-border bg-white px-3.5"
              >
                <option value="">Glavna kategorija</option>
                {mains.map((m) => (
                  <option key={m.id} value={m.id}>
                    {m.nameSr}
                  </option>
                ))}
              </select>
            </label>
          </div>

          {/* Icon picker */}
          <div>
            <span className="text-xs font-semibold text-muted-foreground">Ikona</span>
            <div className="mt-1 flex items-center gap-3">
              <button
                type="button"
                onClick={() => setIconOpen((v) => !v)}
                className="inline-flex items-center gap-2 rounded-xl border border-border bg-white px-3 py-2 text-sm"
              >
                {icon ? (
                  <ThreeDIcon name={icon as ThreeDIconName} size="xs" />
                ) : (
                  <span className="inline-flex h-6 w-6 items-center justify-center rounded-lg border border-dashed border-border text-[0.6rem] text-muted-foreground">
                    —
                  </span>
                )}
                <span className="text-muted-foreground">{icon || "Izaberi ikonu"}</span>
              </button>
              {icon ? (
                <button type="button" onClick={() => setIcon("")} className="text-xs text-muted-foreground underline">
                  ukloni
                </button>
              ) : null}
            </div>
            {iconOpen ? (
              <div className="mt-2 grid max-h-44 grid-cols-8 gap-1.5 overflow-y-auto rounded-xl border border-border bg-muted/30 p-2 sm:grid-cols-10">
                {ICON_OPTIONS.map((name) => (
                  <button
                    key={name}
                    type="button"
                    title={name}
                    onClick={() => {
                      setIcon(name);
                      setIconOpen(false);
                    }}
                    className={`flex items-center justify-center rounded-lg p-1.5 transition hover:bg-white ${
                      icon === name ? "bg-white ring-2 ring-primary" : ""
                    }`}
                  >
                    <ThreeDIcon name={name} size="xs" />
                  </button>
                ))}
              </div>
            ) : null}
          </div>

          <div className="grid gap-4 sm:grid-cols-2">
            <label className="block">
              <span className="text-xs font-semibold text-muted-foreground">Redosled</span>
              <input
                type="number"
                min={0}
                value={sortOrder}
                onChange={(e) => setSortOrder(Number(e.target.value) || 0)}
                className="mt-1 h-11 w-full rounded-xl border border-border bg-white px-3.5"
              />
            </label>
            <label className="mt-6 flex items-center gap-2.5 rounded-xl border border-border bg-white px-3.5 py-2.5 text-sm">
              <input
                type="checkbox"
                checked={isActive}
                onChange={(e) => setIsActive(e.target.checked)}
                className="h-4 w-4 rounded border-border"
              />
              Aktivna kategorija
            </label>
          </div>
        </div>

        <div className="mt-6 flex justify-end gap-2">
          <button type="button" onClick={onClose} className="ghost-button">
            Otkaži
          </button>
          <button
            type="button"
            onClick={submit}
            disabled={!nameSr.trim() || busy}
            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>
      </div>
    </div>
    </ModalPortal>
  );
}
