"use client";

import Link from "next/link";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useParams } from "next/navigation";
import { ArrowLeft, ClipboardList, TestTube } from "lucide-react";
import { BrapiEntityPage, type BrapiFormField } from "@/components/brapi/BrapiEntityPage";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import {
  createSampleRow,
  fetchPlateDetail,
  fetchSampleDetail,
  fetchSamplePlateOptions,
  fetchSampleRows,
  normalizeSampleFormData,
  updateSampleRow,
} from "../../api";
import { buildSampleFields } from "../../components/sampleFormConfig";
import {
  optionLabel,
  PLATE_FORMAT_OPTIONS,
  SAMPLE_TYPE_OPTIONS,
} from "../../plateUtils";
import { TISSUE_TYPE_OPTIONS } from "../../sampleUtils";
import { NONE_SELECT_VALUE, type PlateRecord, type SelectOption } from "../../types";
import type { ObservationUnitContextOption } from "../../sampleUtils";
import type { StudyContextOption, TrialContextOption } from "../../plateUtils";

export default function PlateDetailPage() {
  const params = useParams<{ plateDbId: string }>();
  const plateDbId = decodeURIComponent(params.plateDbId);

  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [plate, setPlate] = useState<PlateRecord | null>(null);
  const [programOptions, setProgramOptions] = useState<SelectOption[]>([]);
  const [trialOptions, setTrialOptions] = useState<TrialContextOption[]>([]);
  const [studyOptions, setStudyOptions] = useState<StudyContextOption[]>([]);
  const [germplasmOptions, setGermplasmOptions] = useState<SelectOption[]>([]);
  const [observationUnitOptions, setObservationUnitOptions] = useState<ObservationUnitContextOption[]>([]);
  const [personOptions, setPersonOptions] = useState<SelectOption[]>([]);

  useEffect(() => {
    let mounted = true;
    setLoading(true);
    setError(null);
    Promise.all([fetchPlateDetail(plateDbId), fetchSamplePlateOptions()])
      .then(([detail, options]) => {
        if (!mounted) return;
        setPlate(detail);
        setProgramOptions(options.programs);
        setTrialOptions(options.trials);
        setStudyOptions(options.studies);
        setGermplasmOptions(options.germplasm);
        setObservationUnitOptions(options.observationUnits);
        setPersonOptions(options.people);
      })
      .catch((event) => {
        if (!mounted) return;
        setError(event instanceof Error ? event.message : "加载样本板详情失败");
      })
      .finally(() => {
        if (mounted) setLoading(false);
      });
    return () => { mounted = false; };
  }, [plateDbId]);

  const defaultFormValues = useMemo(() => {
    if (!plate) return undefined;
    return {
      plate_id: plate.id,
      study_id: plate.study_id && plate.study_id !== NONE_SELECT_VALUE ? plate.study_id : NONE_SELECT_VALUE,
      trial_id: plate.trial_id && plate.trial_id !== NONE_SELECT_VALUE ? plate.trial_id : NONE_SELECT_VALUE,
      program_id: plate.program_id && plate.program_id !== NONE_SELECT_VALUE ? plate.program_id : NONE_SELECT_VALUE,
      sample_type: plate.sample_type && plate.sample_type !== NONE_SELECT_VALUE ? plate.sample_type : NONE_SELECT_VALUE,
    };
  }, [plate]);

  const formOptions = useMemo(() => ({
    programOptions,
    trialOptions,
    studyOptions,
    germplasmOptions,
    observationUnitOptions,
    plateOptions: plate ? [{ value: plate.id, label: plate.plate_name || plate.id }] : [],
    personOptions,
    plates: plate ? [plate] : [],
    hidePlateField: true,
  }), [germplasmOptions, observationUnitOptions, personOptions, plate, programOptions, studyOptions, trialOptions]);

  const fields = useMemo<BrapiFormField[]>(() => buildSampleFields(formOptions), [formOptions]);

  const loadSamples = useCallback(async () => {
    const rows = await fetchSampleRows(undefined, plateDbId);
    return rows as unknown as Record<string, unknown>[];
  }, [plateDbId]);

  const fetchRecord = useCallback(async (id: string) => {
    const detail = await fetchSampleDetail(id);
    return normalizeSampleFormData({ ...detail, plate_id: plate?.id ?? detail.plate_id });
  }, [plate?.id]);

  if (loading) {
    return (
      <div className="space-y-4 p-1">
        <Skeleton className="h-10 w-48" />
        <Skeleton className="h-36 w-full" />
        <Skeleton className="h-96 w-full" />
      </div>
    );
  }

  if (error || !plate) {
    return (
      <div className="rounded-xl border border-destructive/20 bg-destructive/10 px-4 py-6 text-sm text-destructive">
        {error || "样本板不存在"}
        <div className="mt-4">
          <Button asChild variant="outline">
            <Link href="/genotyping/sample-plate"><ArrowLeft className="mr-2 h-4 w-4" />返回列表</Link>
          </Button>
        </div>
      </div>
    );
  }

  return (
    <div className="flex min-h-full flex-col gap-4">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <Button asChild variant="outline" size="sm">
          <Link href="/genotyping/sample-plate"><ArrowLeft className="mr-2 h-4 w-4" />返回样本板列表</Link>
        </Button>
        {(plate.sample_count ?? 0) > 0 ? (
          <Badge variant="outline" className="border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-200">
            该板已有 {plate.sample_count} 个样本，删除样本板前请先迁移样本
          </Badge>
        ) : null}
      </div>

      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="flex items-center gap-2 text-lg">
            <ClipboardList className="h-5 w-5 text-orange-500" />
            {plate.plate_name || plate.id}
          </CardTitle>
        </CardHeader>
        <CardContent className="grid gap-3 text-sm sm:grid-cols-2 lg:grid-cols-4">
          <div><span className="text-slate-500">Plate ID：</span>{plate.id}</div>
          <div><span className="text-slate-500">条码：</span>{plate.plate_barcode || "—"}</div>
          <div><span className="text-slate-500">规格：</span>{optionLabel(PLATE_FORMAT_OPTIONS, plate.plate_format)}</div>
          <div><span className="text-slate-500">样本类型：</span>{optionLabel(SAMPLE_TYPE_OPTIONS, plate.sample_type)}</div>
          <div><span className="text-slate-500">项目：</span>{plate.program_name || "—"}</div>
          <div><span className="text-slate-500">Trial：</span>{plate.trial_name || "—"}</div>
          <div><span className="text-slate-500">Study：</span>{plate.study_name || "—"}</div>
          <div><span className="text-slate-500">样本数：</span>{plate.sample_count ?? 0}</div>
        </CardContent>
      </Card>

      <BrapiEntityPage
        useEnhancedDialog
        icon={TestTube}
        iconBg="bg-gradient-to-br from-rose-500 to-red-600"
        title="板内样本"
        description="在此样本板下维护 sample；新增时默认带出 plate_id 及 Core 上下文。"
        addLabel="新增样本"
        defaultFormValues={defaultFormValues}
        columns={[
          { key: "sample_name", label: "样本名称" },
          { key: "sample_barcode", label: "条码" },
          { key: "sample_type", label: "类型", render: (value) => optionLabel(SAMPLE_TYPE_OPTIONS, value) },
          { key: "tissue_type", label: "组织", render: (value) => optionLabel(TISSUE_TYPE_OPTIONS, value) || String(value ?? "—") },
          { key: "well", label: "孔位" },
          { key: "row", label: "行" },
          { key: "column", label: "列" },
          { key: "observation_unit_id", label: "观测单元", render: (value) => optionLabel(observationUnitOptions, value) },
        ]}
        fields={fields}
        data={[]}
        loadData={loadSamples}
        fetchRecord={fetchRecord}
        createRecord={(payload) => createSampleRow(
          { ...payload, plate_id: plate.id },
          plate.plate_format,
        ) as unknown as Promise<Record<string, unknown>>}
        updateRecord={(id, payload) => updateSampleRow(
          id,
          { ...payload, plate_id: plate.id },
          plate.plate_format,
        ) as unknown as Promise<Record<string, unknown>>}
      />
    </div>
  );
}
