"use client";

import { useMemo, useState, type FormEvent } from "react";
import {
  PageHeader,
  Panel,
  AdminButton,
  StatCard,
  StatusBadge,
  FilterBar,
  SearchInput,
  SelectFilter,
  EmptyState,
} from "@/components/admin/ui";
import { Field, FormGrid, TextInput, TextSelect, TextTextarea, slugify } from "@/components/admin/formFields";
import { useAuth } from "@/context/AuthContext";
import { useStore } from "@/context/StoreContext";
import { api, ApiError, mediaOrPlaceholder } from "@/lib/api";
import type { CategoryRecord } from "@/data/ecommerceStore";

type CategoryFormState = {
  id?: string;
  name: string;
  slug: string;
  parent_id: string;
  status: "active" | "inactive";
  meta_title: string;
  meta_description: string;
  meta_keywords: string;
};

const emptyForm = (): CategoryFormState => ({
  name: "",
  slug: "",
  parent_id: "",
  status: "active",
  meta_title: "",
  meta_description: "",
  meta_keywords: "",
});

type TreeNode = CategoryRecord & { depth: number; productCount: number };

function buildTree(categories: CategoryRecord[], productCounts: Record<string, number>): TreeNode[] {
  const byParent = new Map<string | undefined, CategoryRecord[]>();
  categories.forEach((c) => {
    const key = c.parent_id || undefined;
    const list = byParent.get(key) || [];
    list.push(c);
    byParent.set(key, list);
  });

  const result: TreeNode[] = [];
  const walk = (parentId: string | undefined, depth: number) => {
    const children = (byParent.get(parentId) || []).slice().sort((a, b) => a.name.localeCompare(b.name));
    for (const child of children) {
      result.push({
        ...child,
        depth,
        productCount: productCounts[child.id] || 0,
      });
      walk(child.id, depth + 1);
    }
  };
  walk(undefined, 0);

  // Orphans whose parent is missing
  const visited = new Set(result.map((r) => r.id));
  categories.forEach((c) => {
    if (!visited.has(c.id)) {
      result.push({ ...c, depth: 0, productCount: productCounts[c.id] || 0 });
    }
  });
  return result;
}

export default function AdminCategoriesPage() {
  const { token } = useAuth();
  const { store, refreshStore } = useStore();
  const [search, setSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState("all");
  const [form, setForm] = useState<CategoryFormState>(emptyForm());
  const [slugTouched, setSlugTouched] = useState(false);
  const [imageFile, setImageFile] = useState<File | null>(null);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");
  const [message, setMessage] = useState("");
  const [showForm, setShowForm] = useState(false);

  const productCounts = useMemo(() => {
    const counts: Record<string, number> = {};
    store.products.forEach((p) => {
      counts[p.category_id] = (counts[p.category_id] || 0) + 1;
    });
    return counts;
  }, [store.products]);

  const tree = useMemo(
    () => buildTree(store.categories, productCounts),
    [store.categories, productCounts],
  );

  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    return tree.filter((c) => {
      if (statusFilter === "active" && (c as CategoryRecord & { status?: string }).status === "inactive") {
        return false;
      }
      if (statusFilter === "inactive" && (c as CategoryRecord & { status?: string }).status === "active") {
        return false;
      }
      if (!q) return true;
      return c.name.toLowerCase().includes(q) || c.slug.toLowerCase().includes(q);
    });
  }, [tree, search, statusFilter]);

  const parentName = (id?: string) => store.categories.find((c) => c.id === id)?.name || "—";

  const openCreate = () => {
    setForm(emptyForm());
    setSlugTouched(false);
    setImageFile(null);
    setShowForm(true);
    setError("");
  };

  const openEdit = (category: CategoryRecord) => {
    setForm({
      id: category.id,
      name: category.name,
      slug: category.slug,
      parent_id: category.parent_id || "",
      status: "active",
      meta_title: category.name,
      meta_description: "",
      meta_keywords: "",
    });
    setSlugTouched(true);
    setImageFile(null);
    setShowForm(true);
    setError("");
  };

  const onSubmit = async (e: FormEvent) => {
    e.preventDefault();
    if (!form.name.trim()) {
      setError("Category name is required.");
      return;
    }
    setBusy(true);
    setError("");
    setMessage("");
    try {
      const fd = new FormData();
      fd.set("name", form.name.trim());
      fd.set("slug", form.slug.trim() || slugify(form.name));
      if (form.parent_id) fd.set("parent_id", form.parent_id);
      else fd.set("parent_id", "");
      fd.set("status", form.status);
      fd.set("meta_title", form.meta_title || form.name);
      fd.set("meta_description", form.meta_description);
      fd.set("meta_keywords", form.meta_keywords);
      if (imageFile) fd.set("image", imageFile);

      if (form.id) {
        await api.admin.updateCategory(form.id, fd, token);
        if (imageFile) {
          const imgFd = new FormData();
          imgFd.set("image", imageFile);
          await api.admin.uploadCategoryImage(form.id, imgFd, token);
        }
        setMessage("Category updated.");
      } else {
        await api.admin.createCategory(fd, token);
        setMessage("Category created.");
      }
      await refreshStore();
      setShowForm(false);
      setForm(emptyForm());
      setImageFile(null);
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "Failed to save category.");
    } finally {
      setBusy(false);
    }
  };

  const deleteCategory = async (category: CategoryRecord) => {
    if (!window.confirm(`Delete category “${category.name}”?`)) return;
    setBusy(true);
    setError("");
    try {
      await api.admin.deleteCategory(category.id, token);
      await refreshStore();
      setMessage("Category deleted.");
      if (form.id === category.id) {
        setShowForm(false);
        setForm(emptyForm());
      }
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "Failed to delete category.");
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="space-y-6">
      <PageHeader
        title="Categories"
        description="Organize products into a nested category tree."
        actions={<AdminButton onClick={openCreate}>Add Category</AdminButton>}
      />

      <div className="grid gap-3 sm:grid-cols-3">
        <StatCard label="Categories" value={store.categories.length} />
        <StatCard
          label="Top-level"
          value={store.categories.filter((c) => !c.parent_id).length}
          tone="info"
        />
        <StatCard
          label="With products"
          value={store.categories.filter((c) => (productCounts[c.id] || 0) > 0).length}
          tone="success"
        />
      </div>

      {(message || error) && (
        <div
          className={`rounded-xl border px-4 py-3 text-sm ${
            error
              ? "border-destructive/30 bg-destructive/10 text-destructive"
              : "border-emerald-200 bg-emerald-50 text-emerald-800"
          }`}
        >
          {error || message}
        </div>
      )}

      {showForm ? (
        <Panel
          title={form.id ? "Edit category" : "Add category"}
          description="Name, parent, image, and optional SEO fields"
          actions={
            <AdminButton
              variant="ghost"
              onClick={() => {
                setShowForm(false);
                setForm(emptyForm());
              }}
            >
              Close
            </AdminButton>
          }
        >
          <form onSubmit={onSubmit} className="space-y-4">
            <FormGrid cols={2}>
              <Field label="Name *">
                <TextInput
                  value={form.name}
                  onChange={(e) => {
                    const name = e.target.value;
                    setForm((prev) => ({
                      ...prev,
                      name,
                      slug: slugTouched ? prev.slug : slugify(name),
                    }));
                  }}
                  required
                />
              </Field>
              <Field label="Slug">
                <TextInput
                  value={form.slug}
                  onChange={(e) => {
                    setSlugTouched(true);
                    setForm((prev) => ({ ...prev, slug: e.target.value }));
                  }}
                />
              </Field>
              <Field label="Parent category">
                <TextSelect
                  value={form.parent_id}
                  onChange={(e) => setForm((prev) => ({ ...prev, parent_id: e.target.value }))}
                >
                  <option value="">None (top-level)</option>
                  {store.categories
                    .filter((c) => c.id !== form.id)
                    .map((c) => (
                      <option key={c.id} value={c.id}>
                        {c.name}
                      </option>
                    ))}
                </TextSelect>
              </Field>
              <Field label="Status">
                <TextSelect
                  value={form.status}
                  onChange={(e) =>
                    setForm((prev) => ({
                      ...prev,
                      status: e.target.value as "active" | "inactive",
                    }))
                  }
                >
                  <option value="active">Active</option>
                  <option value="inactive">Inactive</option>
                </TextSelect>
              </Field>
              <Field label="Image" className="sm:col-span-2">
                <TextInput
                  type="file"
                  accept="image/*"
                  onChange={(e) => setImageFile(e.target.files?.[0] || null)}
                />
              </Field>
              <Field label="Meta title (optional)">
                <TextInput
                  value={form.meta_title}
                  onChange={(e) => setForm((prev) => ({ ...prev, meta_title: e.target.value }))}
                />
              </Field>
              <Field label="Meta keywords (optional)">
                <TextInput
                  value={form.meta_keywords}
                  onChange={(e) => setForm((prev) => ({ ...prev, meta_keywords: e.target.value }))}
                />
              </Field>
              <Field label="Meta description (optional)" className="sm:col-span-2">
                <TextTextarea
                  value={form.meta_description}
                  onChange={(e) => setForm((prev) => ({ ...prev, meta_description: e.target.value }))}
                  rows={3}
                />
              </Field>
            </FormGrid>
            <div className="flex gap-2">
              <AdminButton type="submit">{busy ? "Saving…" : form.id ? "Update category" : "Create category"}</AdminButton>
              <AdminButton
                variant="secondary"
                onClick={() => {
                  setShowForm(false);
                  setForm(emptyForm());
                }}
              >
                Cancel
              </AdminButton>
            </div>
          </form>
        </Panel>
      ) : null}

      <Panel title="Category tree" description="Indented parent / child hierarchy">
        <FilterBar>
          <SearchInput value={search} onChange={setSearch} placeholder="Search categories…" />
          <SelectFilter
            value={statusFilter}
            onChange={setStatusFilter}
            options={[
              { value: "all", label: "All statuses" },
              { value: "active", label: "Active" },
              { value: "inactive", label: "Inactive" },
            ]}
          />
        </FilterBar>

        {filtered.length === 0 ? (
          <EmptyState title="No categories found" description="Add a category to start organizing products." />
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full min-w-[720px] text-left text-sm">
              <thead>
                <tr className="border-b border-border text-xs uppercase tracking-wide text-muted-foreground">
                  <th className="py-2 pr-3">Image</th>
                  <th className="py-2 pr-3">Name</th>
                  <th className="py-2 pr-3">Parent</th>
                  <th className="py-2 pr-3">Products</th>
                  <th className="py-2 pr-3">Status</th>
                  <th className="py-2">Actions</th>
                </tr>
              </thead>
              <tbody>
                {filtered.map((category) => (
                  <tr key={category.id} className="border-b border-border/70">
                    <td className="py-2.5 pr-3">
                      {/* eslint-disable-next-line @next/next/no-img-element */}
                      <img
                        src={mediaOrPlaceholder(category.image)}
                        alt=""
                        className="h-10 w-10 rounded-lg object-cover border border-border"
                      />
                    </td>
                    <td className="py-2.5 pr-3">
                      <div style={{ paddingLeft: category.depth * 16 }} className="font-medium">
                        {category.depth > 0 ? (
                          <span className="mr-1 text-muted-foreground">↳</span>
                        ) : null}
                        {category.name}
                      </div>
                      <p className="text-[11px] text-muted-foreground" style={{ paddingLeft: category.depth * 16 }}>
                        /{category.slug}
                      </p>
                    </td>
                    <td className="py-2.5 pr-3 text-muted-foreground">{parentName(category.parent_id)}</td>
                    <td className="py-2.5 pr-3">{category.productCount}</td>
                    <td className="py-2.5 pr-3">
                      <StatusBadge status="active" />
                    </td>
                    <td className="py-2.5">
                      <div className="flex flex-wrap gap-2">
                        <button
                          type="button"
                          className="text-xs font-semibold text-accent hover:underline"
                          onClick={() => openEdit(category)}
                        >
                          Edit
                        </button>
                        <button
                          type="button"
                          className="text-xs font-semibold text-destructive hover:underline"
                          onClick={() => void deleteCategory(category)}
                        >
                          Delete
                        </button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}

        <p className="mt-4 text-xs text-muted-foreground">
          Showing {filtered.length} of {store.categories.length} categories
        </p>
      </Panel>
    </div>
  );
}
