"use client";

import Link from "next/link";
import { useCallback, useMemo } from "react";
import { Share2 } from "lucide-react";
import { BrapiEntityPage, type BrapiFormField } from "@/components/brapi/BrapiEntityPage";
import {
  createPedigreeRow,
  fetchPedigreeDetail,
  fetchPedigreeNodeByGermplasm,
  fetchPedigreeRows,
  normalizePedigreeForm,
  updatePedigreeRow,
} from "../api";
import { useCrossPedigree } from "../CrossPedigreeContext";
import { NONE_SELECT_VALUE } from "../types";

interface PedigreeNodeFormPanelProps {
  scopeGermplasmDbId?: string;
  scopeGermplasmName?: string | null;
  compact?: boolean;
  onChanged?: () => void;
}

export function PedigreeNodeFormPanel({
  scopeGermplasmDbId,
  scopeGermplasmName,
  compact = false,
  onChanged,
}: PedigreeNodeFormPanelProps) {
  const { snapshot } = useCrossPedigree();
  const germplasmOptions = snapshot?.germplasm ?? [];
  const crossingProjectOptions = snapshot?.crossingProjectOptions ?? [];

  const loadRows = useCallback(async () => {
    if (scopeGermplasmDbId) {
      const node = await fetchPedigreeNodeByGermplasm(scopeGermplasmDbId);
      if (!node) return [];
      const projectNameById = new Map(
        (snapshot?.crossingProjects ?? []).map((project) => [project.id, project.name || project.id]),
      );
      return [{
        ...node,
        germplasm_name: node.germplasm_name || scopeGermplasmName,
        crossing_project_name:
          node.crossing_project_name
          || (node.crossing_project_id ? projectNameById.get(node.crossing_project_id) : null),
      }] as unknown as Record<string, unknown>[];
    }

    const rows = await fetchPedigreeRows();
    const projectNameById = new Map(
      (snapshot?.crossingProjects ?? []).map((project) => [project.id, project.name || project.id]),
    );
    return rows.map((row) => ({
      ...row,
      crossing_project_name:
        row.crossing_project_name || (row.crossing_project_id ? projectNameById.get(row.crossing_project_id) : null),
    })) as unknown as Record<string, unknown>[];
  }, [scopeGermplasmDbId, scopeGermplasmName, snapshot?.crossingProjects]);

  const fetchRecord = useCallback(async (id: string) => {
    const detail = await fetchPedigreeDetail(id);
    return normalizePedigreeForm(detail);
  }, []);

  const wrapMutation = useCallback(<T,>(action: () => Promise<T>) => async () => {
    const result = await action();
    onChanged?.();
    return result;
  }, [onChanged]);

  const scopedGermplasmOptions = useMemo(() => {
    if (!scopeGermplasmDbId) return germplasmOptions;
    const existing = germplasmOptions.find((item) => item.value === scopeGermplasmDbId);
    if (existing) return [existing];
    return [{
      value: scopeGermplasmDbId,
      label: scopeGermplasmName || scopeGermplasmDbId,
    }];
  }, [germplasmOptions, scopeGermplasmDbId, scopeGermplasmName]);

  const fields = useMemo<BrapiFormField[]>(() => [
    {
      key: "germplasm_id",
      label: "Germplasm 材料",
      type: "select",
      required: true,
      readOnly: Boolean(scopeGermplasmDbId),
      options: [{ value: NONE_SELECT_VALUE, label: "请选择 Germplasm" }, ...scopedGermplasmOptions],
    },
    {
      key: "crossing_project_id",
      label: "CrossingProject 杂交项目",
      type: "select",
      options: [{ value: NONE_SELECT_VALUE, label: "不指定杂交项目" }, ...crossingProjectOptions],
    },
    {
      key: "crossing_year",
      label: "crossing_year 杂交年份",
      type: "year",
      placeholder: "四位年份",
    },
    {
      key: "family_code",
      label: "family_code 家系编号",
      type: "text",
      placeholder: "同一 crossing_project 下建议唯一",
    },
    {
      key: "pedigree_string",
      label: "pedigree_string 系谱字符串",
      type: "text",
      placeholder: "如 A/B//C，支持 Purdy notation",
      colSpan: 2,
    },
  ], [crossingProjectOptions, scopedGermplasmOptions, scopeGermplasmDbId]);

  const columns = useMemo(() => [
    {
      key: "germplasm_name",
      label: "材料",
      render: (value: unknown, row: Record<string, unknown>) => {
        const id = String(row.germplasm_id ?? row.id ?? "");
        const name = String(value ?? row.germplasm_id ?? "—");
        if (!id || scopeGermplasmDbId) return name;
        return (
          <Link
            href={`/germplasm/cross-pedigree/pedigree-nodes/${encodeURIComponent(id)}`}
            className="font-medium text-sky-600 hover:underline dark:text-sky-400"
          >
            {name}
          </Link>
        );
      },
    },
    ...(scopeGermplasmDbId ? [] : [{ key: "germplasm_id", label: "Germplasm ID" }]),
    { key: "crossing_project_name", label: "杂交项目" },
    { key: "crossing_year", label: "杂交年份" },
    { key: "family_code", label: "家系编号" },
    {
      key: "pedigree_string",
      label: "系谱字符串",
      render: (value: unknown) => {
        const text = String(value ?? "").trim();
        if (!text) return "—";
        return text.length > 40 ? `${text.slice(0, 40)}…` : text;
      },
    },
  ], [scopeGermplasmDbId]);

  const defaultFormValues = useMemo(() => (
    scopeGermplasmDbId
      ? { germplasm_id: scopeGermplasmDbId }
      : undefined
  ), [scopeGermplasmDbId]);

  return (
    <BrapiEntityPage
      icon={Share2}
      iconBg="bg-gradient-to-br from-sky-500 to-blue-600"
      title={compact ? "系谱节点" : "Pedigree Node 系谱节点"}
      description={
        scopeGermplasmDbId
          ? "维护当前种质对应的 pedigree_node；同一 germplasm 通常仅一条节点记录。"
          : "pedigree_node：系谱树中的节点，通常对应一个 germplasm。BrAPI 以 germplasmDbId 作为更新主键。"
      }
      addLabel={scopeGermplasmDbId ? "创建系谱节点" : "新增系谱节点"}
      useEnhancedDialog
      fetchRecord={fetchRecord}
      columns={columns}
      fields={fields}
      data={[]}
      defaultFormValues={defaultFormValues}
      loadData={loadRows}
      createRecord={(payload) => wrapMutation(() => {
        const body = scopeGermplasmDbId
          ? { ...payload, germplasm_id: scopeGermplasmDbId }
          : payload;
        return createPedigreeRow(body);
      })() as Promise<Record<string, unknown>>}
      updateRecord={(id, payload) => wrapMutation(() => updatePedigreeRow(id, payload))() as Promise<Record<string, unknown>>}
    />
  );
}
