"use client";

import { useEffect, useMemo, useState } from "react";
import type {
  AdminFilters,
  AdminProductRow,
  PageResponse,
  PlatformDto,
  CaliberDto,
} from "../_lib/types";


import { initialFilters } from "../_lib/types";
import {
  bulkUpdate,
  fetchAdminCalibers,
  fetchAdminProducts,
  fetchAdminRoles,
  fetchPlatforms,
} from "../_lib/api";

import FilterChips from "./filterChips";
import ProductsTable from "./productsTable";
import PaginationBar from "./paginationBar";
import { BulkBar } from "./BulkBar";
import ProductsToolbar from "./ProductsToolbar";

export default function AdminProductsClient() {
  const [page, setPage] = useState(0);
  const [size, setSize] = useState(50);

  const [platformOptions, setPlatformOptions] = useState<PlatformDto[]>([]);
  const [data, setData] = useState<PageResponse<AdminProductRow> | null>(null);
  const [loading, setLoading] = useState(false);
  const [err, setErr] = useState<string | null>(null);

  const [selected, setSelected] = useState<Set<number>>(new Set());

  const [draft, setDraft] = useState<AdminFilters>(initialFilters);
  const [applied, setApplied] = useState<AdminFilters>(initialFilters);

  const [roleOptions, setRoleOptions] = useState<string[]>([""]);
  const [caliberOptions, setCaliberOptions] = useState<CaliberDto[]>([]);
  // ------------------------------
  // Column Collasping
  // ------------------------------
  const [visibleCols, setVisibleCols] = useState({
    brand: true,
    platform: true,
    role: true,
    caliber: true,
    import: true,
    flags: true,
    updated: true,
  });
  // ------------------------------
  // Bulk action state
  // ------------------------------
  const [bulkPlatformKey, setBulkPlatformKey] = useState("");
  const [bulkPlatformLock, setBulkPlatformLock] = useState(false);

  const [bulkRole, setBulkRole] = useState("");
  const [bulkRoleLock, setBulkRoleLock] = useState(false);

  const [bulkCaliber, setBulkCaliber] = useState("");
  const [bulkCaliberGroup, setBulkCaliberGroup] = useState("");
  const [bulkCaliberLock, setBulkCaliberLock] = useState(false);
  const [bulkForceCaliber, setBulkForceCaliber] = useState(false);

  const queryParams = useMemo(() => {
    return {
      ...applied,
      builderEligible:
        applied.builderEligible === "" ? null : applied.builderEligible,
      adminLocked: applied.adminLocked === "" ? null : applied.adminLocked,
      page,
      size,
      sort: "updatedAt,desc",
    };
  }, [applied, page, size]);

  const refresh = async () => {
    setLoading(true);
    setErr(null);
    try {
      const res: any = await fetchAdminProducts(queryParams);

      // API returns `{ content, page: { size, number, totalElements, totalPages } }`
      // but the UI expects `totalPages/totalElements/number/size` at the top-level.
      const normalized: any = res?.page
        ? {
            content: res.content ?? [],
            ...res.page,
          }
        : res;

      setData(normalized);
      setSelected(new Set());
    } catch (e: any) {
      setErr(e?.message ?? "Failed to load.");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    refresh();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [queryParams]);

  useEffect(() => {
    (async () => {
      try {
        const roles = await fetchAdminRoles({});
        setRoleOptions(["", ...roles]);
      } catch {
        setRoleOptions([""]);
      }
    })();
  }, []);

  useEffect(() => {
    (async () => {
      try {
        const cals = await fetchAdminCalibers({ activeOnly: true });
        setCaliberOptions(Array.isArray(cals) ? cals : []);
      } catch {
        setCaliberOptions([]);
      }
    })();
  }, []);

  useEffect(() => {
    (async () => {
      try {
        const plats = await fetchPlatforms();
        plats.sort((a, b) => a.label.localeCompare(b.label));
        setPlatformOptions(plats);
      } catch (e: any) {
        console.warn(e?.message ?? "Failed to load platforms");
      }
    })();
  }, []);

  const content = data?.content ?? [];
  const selectedIds = Array.from(selected);

  const allOnPageSelected =
    content.length > 0 && content.every((r) => selected.has(r.id));

  const toggleAllOnPage = () => {
    const next = new Set(selected);
    if (allOnPageSelected) content.forEach((r) => next.delete(r.id));
    else content.forEach((r) => next.add(r.id));
    setSelected(next);
  };

  const toggleOne = (id: number) => {
    const next = new Set(selected);
    if (next.has(id)) next.delete(id);
    else next.add(id);
    setSelected(next);
  };

  const applyFilters = () => {
    setPage(0);
    setApplied({ ...draft });
  };

  const clearFilters = () => {
    setDraft(initialFilters);
    setApplied(initialFilters);
    setPage(0);
  };

  const chips = useMemo(() => {
    const out: { key: keyof AdminFilters; label: string }[] = [];
    if (applied.q) out.push({ key: "q", label: `Search: ${applied.q}` });
    if (applied.platform)
      out.push({ key: "platform", label: `Platform: ${applied.platform}` });
    if (applied.partRole)
      out.push({ key: "partRole", label: `Role: ${applied.partRole}` });
    if (applied.caliber)
      out.push({ key: "caliber", label: `Caliber: ${applied.caliber}` });
    if (applied.visibility)
      out.push({
        key: "visibility",
        label: `Visibility: ${applied.visibility}`,
      });
    if (applied.status)
      out.push({ key: "status", label: `Status: ${applied.status}` });
    if (applied.builderEligible)
      out.push({
        key: "builderEligible",
        label: `Builder: ${applied.builderEligible}`,
      });
    if (applied.adminLocked)
      out.push({ key: "adminLocked", label: `Locked: ${applied.adminLocked}` });
    return out;
  }, [applied]);

  const clearOne = async (key: keyof AdminFilters) => {
    setDraft((d) => ({ ...d, [key]: "" } as AdminFilters));
    setApplied((a) => ({ ...a, [key]: "" } as AdminFilters));
    setPage(0);
  };

  const runBulk = async (set: Parameters<typeof bulkUpdate>[1]) => {
    if (selectedIds.length === 0) return;

    setLoading(true);
    setErr(null);
    try {
      await bulkUpdate(selectedIds, set);
      await refresh();
    } catch (e: any) {
      setErr(e?.message ?? "Bulk update failed.");
      setLoading(false);
    }
  };

  return (
    // Prevent page-level horizontal scroll; allow table-only horizontal scroll.
    <div className="w-full max-w-full overflow-x-hidden">
      {/* Header */}
      <div className="mb-4 flex items-start justify-between gap-4">
        <div className="min-w-0">
          <h1 className="text-2xl font-semibold">Admin · Products</h1>
          <p className="text-sm opacity-70">
            Filter, select, and apply bulk actions. This is where bad imports
            come to die.
          </p>
        </div>

        <button
          className="shrink-0 rounded-md border border-zinc-700 px-3 py-2 text-sm hover:bg-zinc-900 disabled:opacity-50"
          onClick={() => refresh()}
          disabled={loading}
        >
          Refresh
        </button>
      </div>

      {/* OPTIONAL IMPROVEMENT:
          Sticky controls area so table scroll doesn't push search/actions away.
          If you hate sticky, remove the wrapper div and keep the inner content. */}
      <div className="sticky top-0 z-20 -mx-2 px-2 pb-3 pt-2 bg-black/70 backdrop-blur border-b border-zinc-900">
        <ProductsToolbar
          draft={draft}
          setDraft={setDraft}
          platformOptions={platformOptions}
          roleOptions={roleOptions}
          caliberOptions={caliberOptions}
          loading={loading}
          onApply={applyFilters}
          onClear={clearFilters}
          selectedCount={selected.size}
          visibleCols={visibleCols}
          setVisibleCols={setVisibleCols}
        />

        {/* Chips stay visible too */}
        <FilterChips chips={chips} onClearOne={(k) => void clearOne(k)} />

        {/* Bulk actions */}
        {selectedIds.length > 0 && (
          <BulkBar
            selectedCount={selectedIds.length}
            loading={loading}
            platformOptions={platformOptions}
            roleOptions={roleOptions}
            caliberOptions={caliberOptions}
            bulkPlatformKey={bulkPlatformKey}
            setBulkPlatformKey={setBulkPlatformKey}
            bulkPlatformLock={bulkPlatformLock}
            setBulkPlatformLock={setBulkPlatformLock}
            bulkRole={bulkRole}
            setBulkRole={setBulkRole}
            bulkRoleLock={bulkRoleLock}
            setBulkRoleLock={setBulkRoleLock}
            bulkCaliber={bulkCaliber}
            setBulkCaliber={setBulkCaliber}
            bulkCaliberGroup={bulkCaliberGroup}
            setBulkCaliberGroup={setBulkCaliberGroup}
            bulkCaliberLock={bulkCaliberLock}
            setBulkCaliberLock={setBulkCaliberLock}
            bulkForceCaliber={bulkForceCaliber}
            setBulkForceCaliber={setBulkForceCaliber}
            runBulk={runBulk}
          />
        )}

        {err && (
          <div className="mt-3 rounded-md border border-red-800 bg-red-950/40 px-3 py-2 text-sm">
            {err}
          </div>
        )}
      </div>

      {/* Table + pagination area
          min-w-0 is crucial to stop flex children from forcing horizontal overflow */}
      <div className="flex min-h-0 min-w-0 flex-1 flex-col gap-3 pt-3">
        {/* This min-w-0 wrapper ensures the table container can shrink to viewport width.
            The ProductsTable itself should have overflow-x-auto on its wrapper and a min-w on the table. */}
        <div className="min-w-0">
          <ProductsTable
            rows={content}
            loading={loading}
            selected={selected}
            onToggleAll={toggleAllOnPage}
            onToggleOne={toggleOne}
            allOnPageSelected={allOnPageSelected}
            visibleCols={visibleCols}
          />
        </div>

        <PaginationBar
          page={page}
          setPage={setPage}
          size={size}
          setSize={setSize}
          loading={loading}
          totalPages={(data as any)?.totalPages ?? (data as any)?.page?.totalPages ?? 1}
          totalElements={(data as any)?.totalElements ?? (data as any)?.page?.totalElements ?? 0}
          number={(data as any)?.number ?? (data as any)?.page?.number ?? page}
        />
      </div>
    </div>
  );
}
