"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { StatusPill } from "@/components/admin/NegocioShell";
import { useAdmin } from "@/context/AdminContext";
import { getProduct } from "@/data/products";

type InvVariant = {
  product_id: string;
  product_title: string;
  product_handle: string;
  product_thumbnail: string | null;
  product_category?: string | null;
  variant_id: string;
  variant_title: string;
  sku: string | null;
  size: string;
  color: string;
  manage_inventory: boolean;
  inventory_item_id: string | null;
  inventory_level_id: string | null;
  location_id: string | null;
  stocked_quantity: number;
  reserved_quantity: number;
  available_quantity: number;
};

type Counts = {
  variants: number;
  low_stock: number;
  out_of_stock: number;
  unmanaged: number;
};

type StockFilter = "all" | "low" | "out";
type CatFilter = string;

const FALLBACK_IMG = "/brand/ot-club-seal.png";

const PRESET_CAT_TABS: { id: string; label: string }[] = [
  { id: "all", label: "Todas" },
  { id: "mujer", label: "Mujer" },
  { id: "hombre", label: "Hombre" },
  { id: "accesorios", label: "Accesorios" },
  { id: "sets", label: "Sets" },
];

function categoryLabel(id: string) {
  const preset = PRESET_CAT_TABS.find((t) => t.id === id);
  if (preset) return preset.label;
  if (id === "otros") return "Otros";
  return id
    .split("-")
    .filter(Boolean)
    .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
    .join(" ");
}

function categoryForRow(row: InvVariant): string {
  if (row.product_category?.trim()) return row.product_category.trim();
  return categoryForHandle(row.product_handle);
}

function categoryForHandle(handle: string): string {
  const product = getProduct(handle);
  if (product?.category) return product.category;
  const h = handle.toLowerCase();
  if (
    h.includes("visor") ||
    h.includes("gorra") ||
    h.includes("bolso") ||
    h.includes("neceser") ||
    h.includes("packaging")
  ) {
    return "accesorios";
  }
  if (h.includes("set-") || h.includes("pareja") || h.includes("completo")) {
    return "sets";
  }
  if (
    h.includes("bermuda") ||
    h.includes("polos-hombre") ||
    h.includes("gentleman") ||
    h.includes("chaqueta")
  ) {
    return "hombre";
  }
  if (
    h.includes("falda") ||
    h.includes("enterizo") ||
    h.includes("vestido") ||
    h.includes("polo") ||
    h.includes("truza")
  ) {
    return "mujer";
  }
  return "otros";
}

function imageForRow(row: InvVariant): string {
  const product = getProduct(row.product_handle);
  if (product) {
    const colorKey = row.color.trim().toLowerCase();
    const idx = product.colors.findIndex(
      (c) => c.trim().toLowerCase() === colorKey
    );
    if (idx >= 0 && product.images[idx]) return product.images[idx];
    if (product.images[0]) return product.images[0];
  }
  return row.product_thumbnail || FALLBACK_IMG;
}

function recomputeCounts(rows: InvVariant[], threshold: number): Counts {
  return {
    variants: rows.length,
    low_stock: rows.filter((r) => r.available_quantity <= threshold).length,
    out_of_stock: rows.filter((r) => r.available_quantity <= 0).length,
    unmanaged: rows.filter((r) => !r.manage_inventory || !r.inventory_item_id)
      .length,
  };
}

export default function NegocioInventarioPage() {
  const { authenticated, loading: authLoading } = useAdmin();
  const [variants, setVariants] = useState<InvVariant[]>([]);
  const [counts, setCounts] = useState<Counts | null>(null);
  const [threshold, setThreshold] = useState(3);
  const [loading, setLoading] = useState(false);
  const [stockFilter, setStockFilter] = useState<StockFilter>("all");
  const [catFilter, setCatFilter] = useState<CatFilter>("all");
  const [query, setQuery] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [openIds, setOpenIds] = useState<Set<string>>(new Set());
  const variantsRef = useRef<InvVariant[]>([]);
  const pendingQty = useRef<Record<string, number>>({});
  const saveTimers = useRef<Record<string, ReturnType<typeof setTimeout>>>({});
  const ensured = useRef(false);

  useEffect(() => {
    variantsRef.current = variants;
  }, [variants]);

  const applyRows = useCallback(
    (rows: InvVariant[], thr = threshold) => {
      variantsRef.current = rows;
      setVariants(rows);
      setCounts(recomputeCounts(rows, thr));
    },
    [threshold]
  );

  const load = useCallback(
    async (opts?: { ensure?: boolean; silent?: boolean }) => {
      if (!opts?.silent) setLoading(true);
      setError(null);
      const ensure = opts?.ensure ? "?ensure=1" : "";
      const res = await fetch(`/api/ops/inventory${ensure}`, {
        cache: "no-store",
      });
      const data = (await res.json().catch(() => ({}))) as {
        variants?: InvVariant[];
        counts?: Counts;
        low_stock_threshold?: number;
        message?: string;
      };
      if (!opts?.silent) setLoading(false);
      if (!res.ok) {
        setError(data.message || "No se pudo cargar el inventario.");
        return;
      }
      const thr = data.low_stock_threshold || threshold;
      setThreshold(thr);
      const pending = pendingQty.current;
      const rows = (data.variants || []).map((row) => {
        const local = pending[row.variant_id];
        if (typeof local === "number") {
          const reserved = row.reserved_quantity || 0;
          return {
            ...row,
            stocked_quantity: local,
            available_quantity: Math.max(0, local - reserved),
          };
        }
        return row;
      });
      applyRows(rows, thr);
    },
    [applyRows, threshold]
  );

  useEffect(() => {
    if (!authenticated) return;
    void (async () => {
      await load({ silent: false });
      if (!ensured.current) {
        ensured.current = true;
        const unmanaged = variantsRef.current.some(
          (v) => !v.manage_inventory || !v.inventory_item_id
        );
        if (unmanaged) {
          await load({ ensure: true, silent: true });
        }
      }
    })();
  }, [authenticated, load]);

  useEffect(() => {
    if (!authenticated) return;
    const tick = window.setInterval(() => {
      if (Object.keys(pendingQty.current).length) return;
      void load({ silent: true });
    }, 20000);
    const onFocus = () => {
      if (Object.keys(pendingQty.current).length) return;
      void load({ silent: true });
    };
    window.addEventListener("focus", onFocus);
    return () => {
      clearInterval(tick);
      window.removeEventListener("focus", onFocus);
      Object.values(saveTimers.current).forEach(clearTimeout);
    };
  }, [authenticated, load]);

  const patchLocalStock = useCallback(
    (variantId: string, quantity: number) => {
      const qty = Math.max(0, Math.floor(quantity));
      pendingQty.current[variantId] = qty;
      const next = variantsRef.current.map((row) => {
        if (row.variant_id !== variantId) return row;
        const reserved = row.reserved_quantity || 0;
        return {
          ...row,
          stocked_quantity: qty,
          available_quantity: Math.max(0, qty - reserved),
        };
      });
      applyRows(next);
    },
    [applyRows]
  );

  const flushSave = useCallback(async (variantId: string) => {
    const row = variantsRef.current.find((v) => v.variant_id === variantId);
    const qty = pendingQty.current[variantId];
    if (!row?.inventory_item_id || typeof qty !== "number") return;
    try {
      const res = await fetch("/api/ops/inventory", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          inventory_item_id: row.inventory_item_id,
          location_id: row.location_id,
          stocked_quantity: qty,
        }),
      });
      if (!res.ok) {
        const data = (await res.json().catch(() => ({}))) as {
          message?: string;
        };
        setError(data.message || "No se pudo guardar el stock.");
        return;
      }
      if (pendingQty.current[variantId] === qty) {
        delete pendingQty.current[variantId];
      }
    } catch {
      setError("No se pudo guardar el stock.");
    }
  }, []);

  const scheduleSave = useCallback(
    (variantId: string) => {
      if (saveTimers.current[variantId]) {
        clearTimeout(saveTimers.current[variantId]);
      }
      saveTimers.current[variantId] = setTimeout(() => {
        void flushSave(variantId);
      }, 280);
    },
    [flushSave]
  );

  const bump = (row: InvVariant, delta: number) => {
    if (!row.inventory_item_id) return;
    const current =
      pendingQty.current[row.variant_id] ?? row.stocked_quantity;
    const next = Math.max(0, current + delta);
    patchLocalStock(row.variant_id, next);
    scheduleSave(row.variant_id);
  };

  const setExact = (row: InvVariant, raw: string) => {
    if (!row.inventory_item_id) return;
    const next = Math.max(0, parseInt(raw || "0", 10) || 0);
    patchLocalStock(row.variant_id, next);
    scheduleSave(row.variant_id);
  };

  const enriched = useMemo(
    () =>
      variants.map((v) => ({
        ...v,
        category: categoryForRow(v),
      })),
    [variants]
  );

  const catCounts = useMemo(() => {
    const map: Record<string, number> = { all: 0 };
    const seen = new Set<string>();
    for (const v of enriched) {
      if (seen.has(v.product_id)) continue;
      seen.add(v.product_id);
      map[v.category] = (map[v.category] || 0) + 1;
      map.all += 1;
    }
    return map;
  }, [enriched]);

  const visibleCatTabs = useMemo(() => {
    const extras = Object.keys(catCounts)
      .filter(
        (id) =>
          id !== "all" &&
          !PRESET_CAT_TABS.some((t) => t.id === id) &&
          (catCounts[id] || 0) > 0
      )
      .sort((a, b) => categoryLabel(a).localeCompare(categoryLabel(b), "es"))
      .map((id) => ({ id, label: categoryLabel(id) }));

    return [
      ...PRESET_CAT_TABS.filter(
        (t) => t.id === "all" || (catCounts[t.id] || 0) > 0
      ),
      ...extras,
    ];
  }, [catCounts]);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    return enriched.filter((v) => {
      if (catFilter !== "all" && v.category !== catFilter) return false;
      if (stockFilter === "low" && v.available_quantity > threshold)
        return false;
      if (stockFilter === "out" && v.available_quantity > 0) return false;
      if (!q) return true;
      return (
        v.product_title.toLowerCase().includes(q) ||
        v.size.toLowerCase().includes(q) ||
        v.color.toLowerCase().includes(q) ||
        (v.sku || "").toLowerCase().includes(q) ||
        v.product_handle.toLowerCase().includes(q)
      );
    });
  }, [enriched, catFilter, stockFilter, query, threshold]);

  const grouped = useMemo(() => {
    const map = new Map<string, (typeof filtered)[number][]>();
    for (const v of filtered) {
      const list = map.get(v.product_id) || [];
      list.push(v);
      map.set(v.product_id, list);
    }
    return Array.from(map.entries())
      .map(([id, rows]) => {
        const low = rows.filter((r) => r.available_quantity <= threshold).length;
        const out = rows.filter((r) => r.available_quantity <= 0).length;
        const colors = Array.from(new Set(rows.map((r) => r.color)));
        return {
          id,
          title: rows[0]?.product_title || id,
          handle: rows[0]?.product_handle || "",
          category: rows[0]?.category || "otros",
          thumbnail: rows[0]?.product_thumbnail || imageForRow(rows[0]!),
          rows,
          colors,
          low,
          out,
          totalUnits: rows.reduce((s, r) => s + r.available_quantity, 0),
        };
      })
      .sort((a, b) => a.title.localeCompare(b.title, "es"));
  }, [filtered, threshold]);

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

  const expandAll = () => setOpenIds(new Set(grouped.map((g) => g.id)));
  const collapseAll = () => setOpenIds(new Set());

  if (authLoading || !authenticated) return null;

  return (
    <div className="space-y-7">
      <div className="flex flex-wrap items-center gap-3">
        <p className="ot-eyebrow">Fase C</p>
        <StatusPill status="activo" />
      </div>

      <div className="flex flex-wrap items-end justify-between gap-4">
        <div>
          <h1 className="font-serif text-4xl">Inventario</h1>
          <p className="text-sm text-ot-muted mt-2 max-w-xl">
            Organizado por categoría. Abre una prenda para ajustar tallas y
            colores.
          </p>
        </div>
        {counts ? (
          <div className="flex flex-wrap gap-4 text-sm">
            <div>
              <p className="text-[10px] tracking-[0.14em] uppercase text-ot-muted">
                Variantes
              </p>
              <p className="font-serif text-2xl">{counts.variants}</p>
            </div>
            <div>
              <p className="text-[10px] tracking-[0.14em] uppercase text-ot-muted">
                Bajo stock
              </p>
              <p className="font-serif text-2xl text-ot-gold">{counts.low_stock}</p>
            </div>
            <div>
              <p className="text-[10px] tracking-[0.14em] uppercase text-ot-muted">
                Agotadas
              </p>
              <p className="font-serif text-2xl text-red-700">
                {counts.out_of_stock}
              </p>
            </div>
          </div>
        ) : null}
      </div>

      <div className="space-y-3">
        <div className="flex flex-wrap gap-2">
          {visibleCatTabs.map((tab) => (
            <button
              key={tab.id}
              type="button"
              onClick={() => {
                setCatFilter(tab.id);
                setOpenIds(new Set());
              }}
              className={`px-4 py-2 text-xs tracking-[0.14em] uppercase border transition ${
                catFilter === tab.id
                  ? "border-ot-green bg-ot-green text-ot-cream"
                  : "border-black/15 bg-transparent hover:border-ot-green/40"
              }`}
            >
              {tab.label}
              <span className="ml-1.5 opacity-70">({catCounts[tab.id]})</span>
            </button>
          ))}
        </div>

        <div className="flex flex-wrap gap-2 items-center">
          {(
            [
              ["all", "Todo el stock"],
              ["low", "Bajo stock"],
              ["out", "Agotadas"],
            ] as const
          ).map(([id, label]) => (
            <button
              key={id}
              type="button"
              onClick={() => setStockFilter(id)}
              className={`px-3 py-1.5 text-[11px] tracking-[0.12em] uppercase border ${
                stockFilter === id
                  ? "border-ot-ink bg-ot-ink text-ot-cream"
                  : "border-black/10 text-ot-muted hover:border-black/25"
              }`}
            >
              {label}
            </button>
          ))}
          <input
            className="ml-auto border border-black/15 bg-transparent px-3 py-2 text-sm min-w-[200px] outline-none focus:border-ot-green"
            placeholder="Buscar prenda, talla, color…"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
          />
          {grouped.length > 0 ? (
            <div className="flex gap-2 text-[11px]">
              <button
                type="button"
                className="underline text-ot-muted hover:text-ot-ink"
                onClick={expandAll}
              >
                Expandir
              </button>
              <button
                type="button"
                className="underline text-ot-muted hover:text-ot-ink"
                onClick={collapseAll}
              >
                Cerrar
              </button>
            </div>
          ) : null}
        </div>
      </div>

      {error ? <p className="text-sm text-red-700">{error}</p> : null}
      {loading ? (
        <p className="text-sm text-ot-muted">Cargando inventario…</p>
      ) : null}

      <div className="space-y-3">
        {grouped.map((group) => {
          const open = openIds.has(group.id);
          const catLabel = categoryLabel(group.category);
          return (
            <section
              key={group.id}
              className="border border-black/10 bg-ot-cream-dark/30 overflow-hidden"
            >
              <button
                type="button"
                onClick={() => toggleOpen(group.id)}
                className="w-full px-4 sm:px-5 py-4 flex flex-wrap items-center gap-3 sm:gap-4 text-left hover:bg-ot-cream-dark/50 transition"
              >
                {/* eslint-disable-next-line @next/next/no-img-element */}
                <img
                  src={group.thumbnail}
                  alt=""
                  className="h-16 w-12 sm:h-[4.5rem] sm:w-14 shrink-0 object-cover object-top bg-ot-cream border border-black/5"
                />
                <div className="min-w-0 flex-1">
                  <div className="flex flex-wrap items-center gap-2">
                    <h2 className="font-serif text-xl sm:text-2xl leading-tight">
                      {group.title}
                    </h2>
                    <span className="text-[10px] tracking-[0.12em] uppercase text-ot-muted border border-black/10 px-2 py-0.5">
                      {catLabel}
                    </span>
                  </div>
                  <p className="mt-1 text-xs text-ot-muted">
                    {group.rows.length} variantes · {group.colors.length} colores
                    · {group.totalUnits} uds.
                    {group.low > 0 ? (
                      <span className="text-ot-gold"> · {group.low} bajas</span>
                    ) : null}
                    {group.out > 0 ? (
                      <span className="text-red-700"> · {group.out} agotadas</span>
                    ) : null}
                  </p>
                </div>
                <span
                  className={`text-ot-muted text-lg transition ${
                    open ? "rotate-180" : ""
                  }`}
                  aria-hidden
                >
                  ▾
                </span>
              </button>

              {open ? (
                <div className="border-t border-black/10 bg-ot-cream/40">
                  <div className="px-4 sm:px-5 py-2 flex justify-end">
                    <a
                      href={`/product/${group.handle}`}
                      target="_blank"
                      rel="noreferrer"
                      className="text-[11px] tracking-[0.12em] uppercase text-ot-muted underline hover:text-ot-green"
                      onClick={(e) => e.stopPropagation()}
                    >
                      Ver en tienda
                    </a>
                  </div>
                  <div className="divide-y divide-black/5">
                    {group.rows.map((row) => {
                      const low = row.available_quantity <= threshold;
                      const out = row.available_quantity <= 0;
                      const img = imageForRow(row);
                      return (
                        <div
                          key={row.variant_id}
                          className="px-4 sm:px-5 py-3 grid sm:grid-cols-[1.3fr_0.7fr_auto] gap-3 items-center text-sm"
                        >
                          <div className="flex items-center gap-3 min-w-0">
                            {/* eslint-disable-next-line @next/next/no-img-element */}
                            <img
                              src={img}
                              alt=""
                              className="h-12 w-10 shrink-0 object-cover object-top bg-ot-cream border border-black/5"
                            />
                            <div className="min-w-0">
                              <p className="font-medium truncate">
                                {row.size} · {row.color}
                              </p>
                              <p className="text-[11px] text-ot-muted truncate">
                                {row.sku || row.variant_id.slice(-8)}
                              </p>
                            </div>
                          </div>
                          <div>
                            <p>
                              Disp.{" "}
                              <span
                                className={
                                  out
                                    ? "text-red-700 font-medium"
                                    : low
                                      ? "text-ot-gold font-medium"
                                      : ""
                                }
                              >
                                {row.available_quantity}
                              </span>
                            </p>
                            <p className="text-[11px] text-ot-muted">
                              Bodega {row.stocked_quantity}
                              {row.reserved_quantity
                                ? ` · carritos ${row.reserved_quantity}`
                                : ""}
                            </p>
                          </div>
                          <div className="flex items-center gap-1.5 justify-end">
                            <button
                              type="button"
                              className="w-8 h-8 border border-black/15 bg-transparent"
                              disabled={!row.inventory_item_id}
                              onClick={() => bump(row, -1)}
                            >
                              −
                            </button>
                            <input
                              className="w-14 border border-black/15 bg-transparent px-1.5 py-1.5 text-center outline-none focus:border-ot-green"
                              value={String(row.stocked_quantity)}
                              onChange={(e) =>
                                setExact(
                                  row,
                                  e.target.value.replace(/[^\d]/g, "")
                                )
                              }
                              disabled={!row.inventory_item_id}
                            />
                            <button
                              type="button"
                              className="w-8 h-8 border border-black/15 bg-transparent"
                              disabled={!row.inventory_item_id}
                              onClick={() => bump(row, 1)}
                            >
                              +
                            </button>
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </div>
              ) : null}
            </section>
          );
        })}
        {!loading && !grouped.length ? (
          <p className="text-sm text-ot-muted py-8 text-center">
            No hay prendas en esta vista.
          </p>
        ) : null}
      </div>
    </div>
  );
}
