import { useEffect, useMemo, useState } from "react";
import { CheckCircle2, PlusCircle, Trash2 } from "lucide-react";
import { api } from "../api";
import type { Category, KindField, SubmissionImage, SubmissionInput } from "../types";

const NUTRI_FIELDS: { key: string; label: string }[] = [
  { key: "energy_kcal", label: "能量 (kcal)" },
  { key: "energy_kj", label: "能量 (kJ)" },
  { key: "fat", label: "脂肪 (g)" },
  { key: "saturated_fat", label: "饱和脂肪 (g)" },
  { key: "carbohydrates", label: "碳水 (g)" },
  { key: "sugars", label: "糖 (g)" },
  { key: "proteins", label: "蛋白质 (g)" },
  { key: "salt", label: "盐 (g)" },
];

function field(v: string): string | null {
  const t = v.trim();
  return t === "" ? null : t;
}

export default function Contribute({ onDone }: { onDone: () => void }) {
  const [categories, setCategories] = useState<Category[]>([]);
  const [done, setDone] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState("");

  const [name, setName] = useState("");
  const [gtin, setGtin] = useState("");
  const [brand, setBrand] = useState("");
  const [categoryID, setCategoryID] = useState("");
  const [netValue, setNetValue] = useState("");
  const [netUnit, setNetUnit] = useState("");
  const [country, setCountry] = useState("");
  const [ingredients, setIngredients] = useState("");
  const [basis, setBasis] = useState("");
  const [nutri, setNutri] = useState<Record<string, string>>({});
  const [kindFields, setKindFields] = useState<KindField[]>([]);
  const [attrs, setAttrs] = useState<Record<string, string>>({});
  const [images, setImages] = useState<SubmissionImage[]>([]);
  const [imageURL, setImageURL] = useState("");
  const [submitter, setSubmitter] = useState("");
  const [contact, setContact] = useState("");
  const [note, setNote] = useState("");

  useEffect(() => {
    api.categories().then((r) => setCategories(r.items)).catch(() => undefined);
  }, []);

  // Derive the archive kind from the selected category. No category => generic.
  const kind = useMemo(() => {
    const c = categories.find((x) => x.id === categoryID);
    return c?.archive_kind || "generic";
  }, [categories, categoryID]);

  // Fetch the kind-specific field template for non-food kinds.
  useEffect(() => {
    setAttrs({});
    if (kind === "food" || kind === "generic") {
      setKindFields([]);
      return;
    }
    let alive = true;
    api
      .kindFields(kind)
      .then((r) => {
        if (alive) setKindFields(r.items);
      })
      .catch(() => {
        if (alive) setKindFields([]);
      });
    return () => {
      alive = false;
    };
  }, [kind]);

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    if (name.trim() === "") {
      setError("请填写商品名称");
      return;
    }
    setSubmitting(true);
    setError("");

    const nutriments: Record<string, number> = {};
    if (kind === "food") {
      for (const [k, v] of Object.entries(nutri)) {
        const n = parseFloat(v);
        if (!Number.isNaN(n)) nutriments[k] = n;
      }
    }

    const attributes: Record<string, unknown> = {};
    if (kind !== "food" && kind !== "generic") {
      for (const f of kindFields) {
        const raw = (attrs[f.field_key] || "").trim();
        if (raw === "") continue;
        if (f.field_type === "number") {
          const n = parseFloat(raw);
          if (!Number.isNaN(n)) attributes[f.field_key] = n;
        } else if (f.field_type === "list") {
          const parts = raw
            .split(/[\n,，、]/)
            .map((s) => s.trim())
            .filter((s) => s !== "");
          if (parts.length) attributes[f.field_key] = parts;
        } else {
          attributes[f.field_key] = raw;
        }
      }
    }

    const input: SubmissionInput = {
      name: name.trim(),
      gtin: field(gtin),
      brand_name: field(brand),
      category_id: categoryID || null,
      net_content_value: field(netValue) ? parseFloat(netValue) : null,
      net_content_unit: field(netUnit),
      country_of_origin: field(country),
      ingredients_text: kind === "food" ? field(ingredients) : null,
      nutriments: Object.keys(nutriments).length ? nutriments : null,
      attributes: Object.keys(attributes).length ? attributes : null,
      nutrition_basis: kind === "food" && basis ? basis : null,
      images: images.length ? images : undefined,
      submitter_name: field(submitter),
      submitter_contact: field(contact),
      note: field(note),
    };

    try {
      await api.submit(input);
      setDone(true);
    } catch (err) {
      setError(err instanceof Error ? err.message : "提交失败");
    } finally {
      setSubmitting(false);
    }
  }

  if (done) {
    return (
      <div className="max-w-xl mx-auto text-center py-16 animate-fade-up">
        <span className="mx-auto grid h-16 w-16 place-items-center rounded-2xl bg-brand-50">
          <CheckCircle2 className="w-9 h-9 text-brand-600" />
        </span>
        <h1 className="mt-4 text-xl font-semibold text-gray-800">已提交，等待审核</h1>
        <p className="mt-2 text-gray-500">
          感谢你的贡献！资料将由管理员人工审核，通过后会收录进公共商品库。
        </p>
        <button onClick={onDone} className="btn-primary mt-6">
          返回首页
        </button>
      </div>
    );
  }

  const input = "input";
  const label = "block text-xs font-medium text-gray-500 mb-1";

  // Group the kind fields by their group label, preserving template order.
  const groups: { label: string; fields: KindField[] }[] = [];
  for (const f of kindFields) {
    let g = groups.find((x) => x.label === f.group_label);
    if (!g) {
      g = { label: f.group_label, fields: [] };
      groups.push(g);
    }
    g.fields.push(f);
  }

  const KIND_LABEL: Record<string, string> = {
    drug: "药品",
    electronics: "数码 3C",
    food: "食品",
    generic: "通用",
  };

  function renderField(f: KindField) {
    const val = attrs[f.field_key] || "";
    const set = (v: string) => setAttrs((p) => ({ ...p, [f.field_key]: v }));
    const lbl = f.unit ? `${f.label_zh} (${f.unit})` : f.label_zh;
    return (
      <div key={f.field_key} className={f.field_type === "textarea" || f.field_type === "list" ? "sm:col-span-2" : ""}>
        <label className={label}>
          {lbl}
          {f.qualified && <span className="text-brand-500"> *</span>}
        </label>
        {f.field_type === "select" ? (
          <select className={input} value={val} onChange={(e) => set(e.target.value)}>
            <option value="">（未选择）</option>
            {(f.options || []).map((o) => (
              <option key={o} value={o}>
                {o}
              </option>
            ))}
          </select>
        ) : f.field_type === "textarea" ? (
          <textarea className={input} rows={3} value={val} placeholder={f.placeholder || ""} onChange={(e) => set(e.target.value)} />
        ) : f.field_type === "list" ? (
          <textarea className={input} rows={2} value={val} placeholder={f.placeholder || "每行一项，或用、逗号分隔"} onChange={(e) => set(e.target.value)} />
        ) : (
          <input
            type={f.field_type === "number" ? "number" : "text"}
            step={f.field_type === "number" ? "any" : undefined}
            className={input}
            value={val}
            placeholder={f.placeholder || ""}
            onChange={(e) => set(e.target.value)}
          />
        )}
      </div>
    );
  }

  return (
    <form onSubmit={submit} className="max-w-3xl mx-auto animate-fade-up">
      <h1 className="text-2xl font-semibold tracking-tight text-gray-900">贡献商品档案</h1>
      <p className="mt-1 text-sm text-gray-500">
        任何人都可以提交新商品资料。提交后会进入审核队列，<b>通过人工审核后才会收纳</b>。除商品名称外均为选填，按品类填写对应资料即可。
      </p>

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

      <div className="card p-5 mt-4">
        <h2 className="font-medium text-gray-700 mb-3">基础信息</h2>
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
          <div className="sm:col-span-2">
            <label className={label}>商品名称 *</label>
            <input className={input} value={name} onChange={(e) => setName(e.target.value)} />
          </div>
          <div>
            <label className={label}>条码 (GTIN)</label>
            <input className={input} value={gtin} onChange={(e) => setGtin(e.target.value)} />
          </div>
          <div>
            <label className={label}>品牌</label>
            <input className={input} value={brand} onChange={(e) => setBrand(e.target.value)} />
          </div>
          <div>
            <label className={label}>品类</label>
            <select className={input} value={categoryID} onChange={(e) => setCategoryID(e.target.value)}>
              <option value="">（未选择）</option>
              {categories.map((c) => (
                <option key={c.id} value={c.id}>
                  {c.name_zh} ({c.path})
                </option>
              ))}
            </select>
            {categoryID && (
              <p className="mt-1 text-xs text-gray-400">
                档案类型：{KIND_LABEL[kind] || kind}
              </p>
            )}
          </div>
          <div>
            <label className={label}>产地</label>
            <input className={input} value={country} onChange={(e) => setCountry(e.target.value)} />
          </div>
          <div>
            <label className={label}>净含量</label>
            <input
              type="number"
              step="any"
              className={input}
              value={netValue}
              onChange={(e) => setNetValue(e.target.value)}
            />
          </div>
          <div>
            <label className={label}>净含量单位 (g/ml/cl…)</label>
            <input className={input} value={netUnit} onChange={(e) => setNetUnit(e.target.value)} />
          </div>
        </div>
      </div>

      {kind === "food" && (
        <div className="card p-5 mt-4">
          <h2 className="font-medium text-gray-700 mb-3">配料与营养</h2>
          <label className={label}>配料表</label>
          <textarea
            className={input}
            rows={3}
            value={ingredients}
            onChange={(e) => setIngredients(e.target.value)}
          />
          <div className="mt-3">
            <label className={label}>营养基准</label>
            <select className={input} value={basis} onChange={(e) => setBasis(e.target.value)}>
              <option value="">（未设置）</option>
              <option value="per_100g">每 100g</option>
              <option value="per_100ml">每 100ml</option>
              <option value="per_serving">每份</option>
            </select>
          </div>
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-3 mt-3">
            {NUTRI_FIELDS.map((f) => (
              <div key={f.key}>
                <label className={label}>{f.label}</label>
                <input
                  type="number"
                  step="any"
                  className={input}
                  value={nutri[f.key] || ""}
                  onChange={(e) => setNutri({ ...nutri, [f.key]: e.target.value })}
                />
              </div>
            ))}
          </div>
        </div>
      )}

      {kind !== "food" && kind !== "generic" && kindFields.length > 0 && (
        <div className="card p-5 mt-4">
          <h2 className="font-medium text-gray-700 mb-1">{KIND_LABEL[kind] || kind}资料</h2>
          <p className="text-xs text-gray-400 mb-3">带 * 为该品类的关键字段，建议尽量填写。</p>
          {groups.map((g) => (
            <div key={g.label} className="mt-3 first:mt-0">
              {g.label && <h3 className="text-xs font-semibold text-gray-400 mb-2">{g.label}</h3>}
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                {g.fields.map(renderField)}
              </div>
            </div>
          ))}
        </div>
      )}

      <div className="card p-5 mt-4">
        <h2 className="font-medium text-gray-700 mb-3">图片（仅填 URL）</h2>
        {images.length > 0 && (
          <ul className="mb-3 space-y-1">
            {images.map((im, i) => (
              <li key={i} className="flex items-center gap-2 text-sm">
                <span className="truncate text-gray-600 flex-1">{im.url}</span>
                <button
                  type="button"
                  onClick={() => setImages(images.filter((_, j) => j !== i))}
                  className="text-gray-400 hover:text-red-500"
                >
                  <Trash2 className="w-4 h-4" />
                </button>
              </li>
            ))}
          </ul>
        )}
        <div className="flex gap-2">
          <input
            className={input}
            placeholder="图片 URL"
            value={imageURL}
            onChange={(e) => setImageURL(e.target.value)}
          />
          <button
            type="button"
            onClick={() => {
              if (imageURL.trim()) {
                setImages([...images, { url: imageURL.trim(), kind: "front" }]);
                setImageURL("");
              }
            }}
            className="shrink-0 px-3 rounded-xl border border-gray-200 text-sm flex items-center gap-1 hover:bg-gray-50"
          >
            <PlusCircle className="w-4 h-4" /> 添加
          </button>
        </div>
      </div>

      <div className="card p-5 mt-4">
        <h2 className="font-medium text-gray-700 mb-3">联系方式（选填）</h2>
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
          <div>
            <label className={label}>你的称呼</label>
            <input className={input} value={submitter} onChange={(e) => setSubmitter(e.target.value)} />
          </div>
          <div>
            <label className={label}>联系方式（邮箱/微信）</label>
            <input className={input} value={contact} onChange={(e) => setContact(e.target.value)} />
          </div>
          <div className="sm:col-span-2">
            <label className={label}>备注 / 资料来源</label>
            <input className={input} value={note} onChange={(e) => setNote(e.target.value)} />
          </div>
        </div>
      </div>

      <div className="mt-5 flex items-center gap-3">
        <button type="submit" disabled={submitting} className="btn-primary px-6">
          {submitting ? "提交中…" : "提交审核"}
        </button>
        <button type="button" onClick={onDone} className="text-sm text-gray-500 hover:underline">
          取消
        </button>
      </div>
    </form>
  );
}
