"use client";

import Link from "next/link";
import { useCallback, useEffect, useMemo, useState, type ReactNode } from "react";
import { MapPin } from "lucide-react";
import { BrapiEntityPage, type BrapiFormField } from "@/components/brapi/BrapiEntityPage";
import {
  createMarkerPositionRow,
  deleteMarkerPositionRow,
  fetchAllLinkageGroupFormOptions,
  fetchLinkageGroupOptions,
  fetchMarkerPositionRowsByQuery,
  fetchVariantOptions,
  normalizeMarkerPositionFormData,
  updateMarkerPositionRow,
} from "../api";
import { NONE_SELECT_VALUE, type MarkerPositionQuery, type SelectOption } from "../types";

interface MarkerPositionEntityPageProps {
  /** 详情页固定所属图谱 */
  mapDbId?: string;
  /** 连锁群详情页固定所属连锁群 */
  linkageGroupDbId?: string;
  linkageGroupName?: string | null;
  markerPositionQuery?: MarkerPositionQuery;
  onChanged?: () => void;
  defaultFormValues?: Record<string, unknown>;
  renderQueryForm?: () => ReactNode;
}

export function MarkerPositionEntityPage({
  mapDbId,
  linkageGroupDbId,
  linkageGroupName,
  markerPositionQuery,
  onChanged,
  defaultFormValues,
  renderQueryForm,
}: MarkerPositionEntityPageProps) {
  const scopedToMap = Boolean(mapDbId);
  const scopedToLinkageGroup = Boolean(linkageGroupDbId);
  const [linkageGroupOptions, setLinkageGroupOptions] = useState<SelectOption[]>([]);
  const [variantOptions, setVariantOptions] = useState<SelectOption[]>([]);

  useEffect(() => {
    let mounted = true;
    const linkagePromise = mapDbId
      ? fetchLinkageGroupOptions(mapDbId)
      : fetchAllLinkageGroupFormOptions();
    Promise.all([linkagePromise, fetchVariantOptions()])
      .then(([linkageGroups, variants]) => {
        if (!mounted) return;
        setLinkageGroupOptions(linkageGroups);
        setVariantOptions(variants);
      })
      .catch(() => {
        if (!mounted) return;
        setLinkageGroupOptions([]);
        setVariantOptions([]);
      });
    return () => { mounted = false; };
  }, [mapDbId]);

  const loadRows = useCallback(async () => {
    const query = scopedToMap && mapDbId
      ? { map_db_id: mapDbId }
      : markerPositionQuery;
    const rows = await fetchMarkerPositionRowsByQuery(query, linkageGroupDbId);
    return rows as unknown as Record<string, unknown>[];
  }, [scopedToMap, mapDbId, linkageGroupDbId, markerPositionQuery]);

  const fields = useMemo<BrapiFormField[]>(() => [
    { key: "id", label: "MarkerPosition ID", type: "text", placeholder: "留空则系统自动生成" },
    {
      key: "linkage_group_id",
      label: "连锁群",
      type: "select",
      required: true,
      options: [
        { value: NONE_SELECT_VALUE, label: "请选择连锁群" },
        ...linkageGroupOptions,
      ],
    },
    {
      key: "variant_id",
      label: "Variant",
      type: "select",
      required: true,
      options: [
        { value: NONE_SELECT_VALUE, label: "请选择 Variant" },
        ...variantOptions,
      ],
    },
    { key: "position", label: "图谱位置", type: "number", required: true, placeholder: "非负整数" },
  ], [linkageGroupOptions, variantOptions]);

  const columns = useMemo(() => {
    const cols = [];
    if (!scopedToMap) {
      cols.push({
        key: "map_name",
        label: "所属图谱",
        render: (value: unknown, row: Record<string, unknown>) => {
          const id = String(row.map_db_id ?? row.mapDbId ?? "");
          const label = String(value ?? row.map_name ?? "—");
          if (!id) return label;
          return (
            <Link
              href={`/genotyping/genome-map/maps/${encodeURIComponent(id)}`}
              className="text-teal-600 hover:underline dark:text-teal-400"
            >
              {label}
            </Link>
          );
        },
      });
    }
    cols.push(
      {
        key: "linkage_group_name",
        label: "连锁群",
        render: (value: unknown, row: Record<string, unknown>) => {
          const name = String(value ?? "—");
          const lgId = String(row.linkage_group_db_id ?? row.linkageGroupDbId ?? "");
          const targetMapId = mapDbId || String(row.map_db_id ?? row.mapDbId ?? "");
          if (!lgId || !targetMapId) return name;
          return (
            <Link
              href={`/genotyping/genome-map/maps/${encodeURIComponent(targetMapId)}/linkage-groups/${encodeURIComponent(lgId)}`}
              className="font-medium text-teal-600 hover:underline dark:text-teal-400"
            >
              {name}
            </Link>
          );
        },
      },
      {
        key: "variant_name",
        label: "Variant",
        render: (value: unknown, row: Record<string, unknown>) => {
          const id = String(row.variant_db_id ?? row.variantDbId ?? "");
          const name = String(value ?? "—");
          if (!id) return name;
          return (
            <Link
              href={`/genotyping/variant/variants/${encodeURIComponent(id)}`}
              className="font-medium text-rose-600 hover:underline dark:text-rose-400"
            >
              {name}
            </Link>
          );
        },
      },
      { key: "position", label: "位置" },
    );
    return cols;
  }, [scopedToMap, mapDbId]);

  const resolvedDefaultFormValues = useMemo(() => ({
    ...defaultFormValues,
    ...(linkageGroupDbId ? { linkage_group_id: linkageGroupDbId } : {}),
  }), [defaultFormValues, linkageGroupDbId]);

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

  const findRowById = useCallback(async (id: string) => {
    const query = scopedToMap && mapDbId
      ? { map_db_id: mapDbId }
      : markerPositionQuery;
    const rows = await fetchMarkerPositionRowsByQuery(query, linkageGroupDbId);
    return rows.find((item) => item.id === id);
  }, [scopedToMap, mapDbId, linkageGroupDbId, markerPositionQuery]);

  const title = scopedToLinkageGroup && linkageGroupName
    ? `Marker Position · ${linkageGroupName}`
    : scopedToMap
      ? "Marker Position"
      : "Marker Position 列表";

  const description = scopedToLinkageGroup
    ? "在该连锁群下维护 Variant 图谱位置；同一 Variant 不可重复。"
    : scopedToMap
      ? "将 Variant 定位到连锁群坐标；同一连锁群下同一 Variant 不可重复。"
      : "按图谱、连锁群、Variant 查询并维护 marker_position。";

  return (
    <BrapiEntityPage
      useEnhancedDialog
      icon={MapPin}
      iconBg="bg-gradient-to-br from-cyan-500 to-blue-600"
      title={title}
      description={description}
      addLabel="新增 Marker Position"
      defaultFormValues={resolvedDefaultFormValues}
      columns={columns}
      fields={fields}
      data={[]}
      loadData={loadRows}
      fetchRecord={async (id) => {
        const row = await findRowById(id);
        if (!row) throw new Error("Marker Position 不存在");
        return normalizeMarkerPositionFormData(row);
      }}
      createRecord={(payload) => wrapMutation(() => createMarkerPositionRow(payload))() as Promise<Record<string, unknown>>}
      updateRecord={(id, payload) => wrapMutation(() => updateMarkerPositionRow(id, payload))() as Promise<Record<string, unknown>>}
      deleteRecord={(id) => wrapMutation(() => deleteMarkerPositionRow(id))().then(() => undefined)}
      renderQueryForm={renderQueryForm}
      renderFormExtra={() => (
        <div className="col-span-2 rounded-lg border border-cyan-100 bg-cyan-50/60 p-3 text-xs text-cyan-900 dark:border-cyan-900/40 dark:bg-cyan-950/30 dark:text-cyan-100">
          <p className="font-medium">校验说明</p>
          <p className="mt-1 text-cyan-800/80 dark:text-cyan-200/80">
            position 不应超过所属连锁群的 max_position（若已设置）；单位应与图谱 unit 一致。
          </p>
        </div>
      )}
    />
  );
}
