import { useEffect, useMemo, useState } from "react";
import { api, ApiError } from "../api";
import type { Category, CategoryInput } from "../types";
import { FolderTree, Pencil, Plus, Trash2 } from "lucide-react";

type FormState = {
  mode: "create" | "edit";
  id?: string;
  name_zh: string;
  name_en: string;
  slug: string;
  parent_id: string; // "" = top level
  gpc_brick_code: string;
};

function emptyForm(parentId = ""): FormState {
  return {
    mode: "create",
    name_zh: "",
    name_en: "",
    slug: "",
    parent_id: parentId,
    gpc_brick_code: "",
  };
}

export default function CategoriesPage() {
  const [rows, setRows] = useState<Category[]>([]);
  const [error, setError] = useState("");
  const [form, setForm] = useState<FormState | null>(null);

  async function load() {
    setError("");
    try {
      const res = await api.listCategories();
      setRows(res.items);
    } catch (e) {
      setError(e instanceof ApiError ? e.message : "加载失败");
    }
  }

  useEffect(() => {
    load();
  }, []);

  async function remove(c: Category) {
    if (!confirm(`确认删除分类「${c.name_zh}」(${c.path})？`)) return;
    setError("");
    try {
      await api.deleteCategory(c.id);
      await load();
    } catch (e) {
      setError(e instanceof ApiError ? e.message : "删除失败");
    }
  }

  return (
    <div className="mx-auto max-w-5xl">
      <div className="flex items-center justify-between mb-4">
        <div>
          <h2 className="text-lg font-semibold text-gray-800 flex items-center gap-2">
            <FolderTree className="h-5 w-5 text-emerald-600" /> 分类管理
          </h2>
          <p className="text-sm text-gray-500 mt-1">
            维护商品分类树。英文标识(slug)用于分类路径，新建后不可修改；可重命名、移动层级、删除空分类。
          </p>
        </div>
        <button
          onClick={() => setForm(emptyForm())}
          className="px-4 py-2 rounded-lg bg-emerald-600 text-white text-sm font-medium hover:bg-emerald-700 flex items-center gap-1.5"
        >
          <Plus className="h-4 w-4" /> 新建顶级分类
        </button>
      </div>

      {error && (
        <div className="mb-3 bg-red-50 text-red-700 text-sm rounded px-4 py-2">{error}</div>
      )}

      {form && (
        <CategoryForm
          form={form}
          categories={rows}
          onClose={() => setForm(null)}
          onSaved={() => {
            setForm(null);
            load();
          }}
          onError={setError}
        />
      )}

      <div className="bg-white border rounded-lg overflow-hidden">
        <table className="w-full text-sm">
          <thead className="bg-gray-50 text-gray-500 text-left">
            <tr>
              <th className="px-4 py-2 font-medium">名称</th>
              <th className="px-4 py-2 font-medium">路径</th>
              <th className="px-4 py-2 font-medium">GPC</th>
              <th className="px-4 py-2 font-medium">商品数</th>
              <th className="px-4 py-2 font-medium"></th>
            </tr>
          </thead>
          <tbody className="divide-y">
            {rows.length === 0 ? (
              <tr>
                <td colSpan={5} className="px-4 py-8 text-center text-gray-400">
                  暂无分类
                </td>
              </tr>
            ) : (
              rows.map((c) => (
                <tr key={c.id} className="hover:bg-gray-50">
                  <td className="px-4 py-2 text-gray-800">
                    <span style={{ paddingLeft: `${c.level * 18}px` }} className="inline-flex items-center gap-2">
                      {c.level > 0 && <span className="text-gray-300">└</span>}
                      <span className="font-medium">{c.name_zh}</span>
                      {c.name_en && <span className="text-xs text-gray-400">{c.name_en}</span>}
                    </span>
                  </td>
                  <td className="px-4 py-2 text-gray-500">
                    <code className="text-xs">{c.path}</code>
                  </td>
                  <td className="px-4 py-2 text-gray-500 text-xs">{c.gpc_brick_code || "—"}</td>
                  <td className="px-4 py-2 text-gray-600">{c.product_count}</td>
                  <td className="px-4 py-2 text-right whitespace-nowrap">
                    <button
                      onClick={() => setForm(emptyForm(c.id))}
                      className="text-gray-400 hover:text-emerald-600 mr-3"
                      title="新增子分类"
                    >
                      <Plus className="h-4 w-4" />
                    </button>
                    <button
                      onClick={() =>
                        setForm({
                          mode: "edit",
                          id: c.id,
                          name_zh: c.name_zh,
                          name_en: c.name_en ?? "",
                          slug: c.path,
                          parent_id: c.parent_id ?? "",
                          gpc_brick_code: c.gpc_brick_code ?? "",
                        })
                      }
                      className="text-gray-400 hover:text-emerald-600 mr-3"
                      title="编辑"
                    >
                      <Pencil className="h-4 w-4" />
                    </button>
                    <button
                      onClick={() => remove(c)}
                      className="text-gray-400 hover:text-red-600"
                      title="删除"
                    >
                      <Trash2 className="h-4 w-4" />
                    </button>
                  </td>
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function CategoryForm({
  form,
  categories,
  onClose,
  onSaved,
  onError,
}: {
  form: FormState;
  categories: Category[];
  onClose: () => void;
  onSaved: () => void;
  onError: (msg: string) => void;
}) {
  const [state, setState] = useState<FormState>(form);
  const [busy, setBusy] = useState(false);

  // When editing, the node itself and its descendants are not valid parents.
  const parentOptions = useMemo(() => {
    if (state.mode === "create") return categories;
    const self = categories.find((c) => c.id === state.id);
    if (!self) return categories;
    return categories.filter(
      (c) => c.id !== self.id && !c.path.startsWith(self.path + "."),
    );
  }, [categories, state.mode, state.id]);

  function set<K extends keyof FormState>(key: K, value: FormState[K]) {
    setState((s) => ({ ...s, [key]: value }));
  }

  async function submit() {
    if (!state.name_zh.trim()) {
      onError("分类名称不能为空");
      return;
    }
    setBusy(true);
    onError("");
    const body: CategoryInput = {
      name_zh: state.name_zh.trim(),
      name_en: state.name_en.trim() || null,
      parent_id: state.parent_id || null,
      gpc_brick_code: state.gpc_brick_code.trim() || null,
    };
    if (state.mode === "create") body.slug = state.slug.trim() || null;
    try {
      if (state.mode === "create") {
        await api.createCategory(body);
      } else if (state.id) {
        await api.updateCategory(state.id, body);
      }
      onSaved();
    } catch (e) {
      onError(e instanceof ApiError ? e.message : "保存失败");
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="mb-4 bg-white border rounded-lg p-5">
      <h3 className="font-medium text-gray-700 mb-3">
        {state.mode === "create" ? "新建分类" : "编辑分类"}
      </h3>
      <div className="grid grid-cols-2 gap-4">
        <label className="block">
          <span className="text-xs text-gray-500">中文名称 *</span>
          <input
            className="w-full border rounded-md px-3 py-2 text-sm mt-1"
            value={state.name_zh}
            onChange={(e) => set("name_zh", e.target.value)}
            placeholder="例如：饮料"
          />
        </label>
        <label className="block">
          <span className="text-xs text-gray-500">英文名称（可选）</span>
          <input
            className="w-full border rounded-md px-3 py-2 text-sm mt-1"
            value={state.name_en}
            onChange={(e) => set("name_en", e.target.value)}
            placeholder="Beverages"
          />
        </label>
        <label className="block">
          <span className="text-xs text-gray-500">上级分类</span>
          <select
            className="w-full border rounded-md px-3 py-2 text-sm mt-1 bg-white"
            value={state.parent_id}
            onChange={(e) => set("parent_id", e.target.value)}
          >
            <option value="">（顶级分类）</option>
            {parentOptions.map((c) => (
              <option key={c.id} value={c.id}>
                {"\u00A0".repeat(c.level * 2)}
                {c.name_zh} ({c.path})
              </option>
            ))}
          </select>
        </label>
        {state.mode === "create" ? (
          <label className="block">
            <span className="text-xs text-gray-500">英文标识 slug（可选，留空自动生成）</span>
            <input
              className="w-full border rounded-md px-3 py-2 text-sm mt-1"
              value={state.slug}
              onChange={(e) => set("slug", e.target.value)}
              placeholder="beverages"
            />
          </label>
        ) : (
          <label className="block">
            <span className="text-xs text-gray-500">路径（不可修改）</span>
            <input
              className="w-full border rounded-md px-3 py-2 text-sm mt-1 bg-gray-50 text-gray-400"
              value={state.slug}
              disabled
            />
          </label>
        )}
        <label className="block">
          <span className="text-xs text-gray-500">GPC Brick 编码（可选）</span>
          <input
            className="w-full border rounded-md px-3 py-2 text-sm mt-1"
            value={state.gpc_brick_code}
            onChange={(e) => set("gpc_brick_code", e.target.value)}
            placeholder="10000224"
          />
        </label>
      </div>
      <div className="mt-4 flex gap-2">
        <button
          onClick={submit}
          disabled={busy}
          className="px-4 py-2 rounded bg-emerald-600 text-white text-sm hover:bg-emerald-700 disabled:opacity-60"
        >
          保存
        </button>
        <button onClick={onClose} className="px-4 py-2 rounded border text-sm text-gray-600">
          取消
        </button>
      </div>
    </div>
  );
}
