"use client";

import { useCallback, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
import { RotateCcw, Search, TestTube } from "lucide-react";
import { BrapiEntityPage, type BrapiFormField } from "@/components/brapi/BrapiEntityPage";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import {
  createSampleRow,
  deleteSampleRow,
  fetchSampleDetail,
  loadSamplePlatePageData,
  normalizeSampleFormData,
  updateSampleRow,
} from "../api";
import { optionLabel, optionOrNone, SAMPLE_TYPE_OPTIONS } from "../plateUtils";
import { TISSUE_TYPE_OPTIONS, type ObservationUnitContextOption } from "../sampleUtils";
import { NONE_SELECT_VALUE, type PlateRecord, type SampleQuery, type SelectOption } from "../types";
import { buildSampleFields } from "./sampleFormConfig";
import type { StudyContextOption, TrialContextOption } from "../plateUtils";

const emptyQuery = (): SampleQuery => ({
  sample_name: "",
  sample_barcode: "",
  program_id: NONE_SELECT_VALUE,
  trial_id: NONE_SELECT_VALUE,
  study_id: NONE_SELECT_VALUE,
  plate_id: NONE_SELECT_VALUE,
  observation_unit_id: NONE_SELECT_VALUE,
});

function toSelectValue(value: string | null) {
  return value && value !== NONE_SELECT_VALUE ? value : NONE_SELECT_VALUE;
}

export function SampleTab() {
  const searchParams = useSearchParams();
  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 [plateOptions, setPlateOptions] = useState<SelectOption[]>([]);
  const [personOptions, setPersonOptions] = useState<SelectOption[]>([]);
  const [plates, setPlates] = useState<PlateRecord[]>([]);
  const [draftQuery, setDraftQuery] = useState<SampleQuery>(emptyQuery);
  const [appliedQuery, setAppliedQuery] = useState<SampleQuery>(emptyQuery);

  const urlDefaultFormValues = useMemo(() => {
    const values: Record<string, unknown> = {};
    const studyId = searchParams.get("study_id");
    const trialId = searchParams.get("trial_id");
    const programId = searchParams.get("program_id");
    const observationUnitId = searchParams.get("observation_unit_id");
    const plateId = searchParams.get("plate_id");

    if (studyId) values.study_id = studyId;
    if (trialId) values.trial_id = trialId;
    if (programId) values.program_id = programId;
    if (observationUnitId) values.observation_unit_id = observationUnitId;
    if (plateId) values.plate_id = plateId;
    return Object.keys(values).length > 0 ? values : undefined;
  }, [searchParams]);

  const applyOptions = useCallback((
    options: Awaited<ReturnType<typeof loadSamplePlatePageData>>["options"],
    plateRows: PlateRecord[],
  ) => {
    setProgramOptions(options.programs);
    setTrialOptions(options.trials);
    setStudyOptions(options.studies);
    setGermplasmOptions(options.germplasm);
    setObservationUnitOptions(options.observationUnits);
    setPlateOptions(options.plates);
    setPersonOptions(options.people);
    setPlates(plateRows);
    return options;
  }, []);

  const loadRows = useCallback(async () => {
    const { options, plates, samples } = await loadSamplePlatePageData({ sampleQuery: appliedQuery });
    applyOptions(options, plates);
    return samples as unknown as Record<string, unknown>[];
  }, [appliedQuery, applyOptions]);

  const resolvePlateFormat = useCallback((plateId: unknown) => {
    const id = String(plateId ?? "").trim();
    if (!id || id === NONE_SELECT_VALUE) return null;
    return plates.find((plate) => plate.id === id)?.plate_format ?? null;
  }, [plates]);

  const formOptions = useMemo(() => ({
    programOptions,
    trialOptions,
    studyOptions,
    germplasmOptions,
    observationUnitOptions,
    plateOptions,
    personOptions,
    plates,
  }), [germplasmOptions, observationUnitOptions, personOptions, plateOptions, plates, programOptions, studyOptions, trialOptions]);

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

  const renderFormExtra = useCallback(() => (
    <div className="col-span-2 rounded-lg border border-rose-100 bg-rose-50/60 p-3 text-xs text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100">
      <p className="font-medium">校验说明</p>
      <p className="mt-1 text-rose-800/80 dark:text-rose-200/80">
        若关联观测单元，其所属 Study 须与样本 Study 一致；Program / Trial / Study 层级会交叉校验。
        上板样本的行/列/孔位按板规格校验，同一板内孔位不可重复；仅填行+列时保存时自动生成孔位。
        删除前会检查是否已有 CallSet（BrAPI 暂不支持 DELETE）。
      </p>
    </div>
  ), []);

  const renderQueryForm = useCallback(() => (
    <div className="rounded-xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-950">
      <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
        <div className="space-y-1.5">
          <Label className="text-xs text-slate-500">样本名称</Label>
          <Input
            value={draftQuery.sample_name ?? ""}
            onChange={(event) => setDraftQuery((current) => ({ ...current, sample_name: event.target.value }))}
            placeholder="sampleName 模糊匹配"
          />
        </div>
        <div className="space-y-1.5">
          <Label className="text-xs text-slate-500">样本条码</Label>
          <Input
            value={draftQuery.sample_barcode ?? ""}
            onChange={(event) => setDraftQuery((current) => ({ ...current, sample_barcode: event.target.value }))}
            placeholder="barcode 模糊匹配"
          />
        </div>
        <div className="space-y-1.5">
          <Label className="text-xs text-slate-500">项目</Label>
          <Select value={toSelectValue(draftQuery.program_id ?? null)} onValueChange={(value) => setDraftQuery((current) => ({ ...current, program_id: value }))}>
            <SelectTrigger><SelectValue placeholder="全部" /></SelectTrigger>
            <SelectContent>
              {optionOrNone("全部项目", programOptions).map((option) => (
                <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
        <div className="space-y-1.5">
          <Label className="text-xs text-slate-500">Trial</Label>
          <Select value={toSelectValue(draftQuery.trial_id ?? null)} onValueChange={(value) => setDraftQuery((current) => ({ ...current, trial_id: value }))}>
            <SelectTrigger><SelectValue placeholder="全部" /></SelectTrigger>
            <SelectContent>
              {optionOrNone("全部 Trial", trialOptions).map((option) => (
                <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
        <div className="space-y-1.5">
          <Label className="text-xs text-slate-500">Study</Label>
          <Select value={toSelectValue(draftQuery.study_id ?? null)} onValueChange={(value) => setDraftQuery((current) => ({ ...current, study_id: value }))}>
            <SelectTrigger><SelectValue placeholder="全部" /></SelectTrigger>
            <SelectContent>
              {optionOrNone("全部 Study", studyOptions).map((option) => (
                <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
        <div className="space-y-1.5">
          <Label className="text-xs text-slate-500">样本板</Label>
          <Select value={toSelectValue(draftQuery.plate_id ?? null)} onValueChange={(value) => setDraftQuery((current) => ({ ...current, plate_id: value }))}>
            <SelectTrigger><SelectValue placeholder="全部" /></SelectTrigger>
            <SelectContent>
              {optionOrNone("全部样本板", plateOptions).map((option) => (
                <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
        <div className="space-y-1.5 xl:col-span-2">
          <Label className="text-xs text-slate-500">观测单元</Label>
          <Select value={toSelectValue(draftQuery.observation_unit_id ?? null)} onValueChange={(value) => setDraftQuery((current) => ({ ...current, observation_unit_id: value }))}>
            <SelectTrigger><SelectValue placeholder="全部" /></SelectTrigger>
            <SelectContent>
              {optionOrNone("全部观测单元", observationUnitOptions).map((option) => (
                <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </div>
      <div className="mt-3 flex justify-end gap-2">
        <Button type="button" variant="outline" className="gap-2" onClick={() => { const reset = emptyQuery(); setDraftQuery(reset); setAppliedQuery(reset); }}>
          <RotateCcw className="h-4 w-4" />
          重置
        </Button>
        <Button type="button" className="gap-2" onClick={() => setAppliedQuery({ ...draftQuery })}>
          <Search className="h-4 w-4" />
          查询
        </Button>
      </div>
    </div>
  ), [draftQuery, observationUnitOptions, plateOptions, programOptions, studyOptions, trialOptions]);

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

  return (
    <BrapiEntityPage
      useEnhancedDialog
      icon={TestTube}
      iconBg="bg-gradient-to-br from-rose-500 to-red-600"
      title="样本管理"
      description="管理送检样本：条码、组织类型、观测单元来源、样本板孔位及 Core 冗余字段。"
      addLabel="新建样本"
      defaultFormValues={urlDefaultFormValues}
      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: "program_name", label: "项目" },
        { key: "trial_name", label: "Trial" },
        { key: "study_name", label: "Study" },
        { key: "plate_name", label: "样本板" },
        { key: "observation_unit_id", label: "观测单元", render: (value) => optionLabel(observationUnitOptions, value) },
        { key: "well", label: "孔位" },
      ]}
      fields={fields}
      data={[]}
      stats={[{ label: "/brapi/v2/samples", value: "BrAPI", className: "bg-rose-50 text-rose-700 dark:bg-rose-400/10 dark:text-rose-200" }]}
      loadData={loadRows}
      fetchRecord={fetchRecord}
      createRecord={(payload) => createSampleRow(payload, resolvePlateFormat(payload.plate_id)) as unknown as Promise<Record<string, unknown>>}
      updateRecord={(id, payload) => updateSampleRow(id, payload, resolvePlateFormat(payload.plate_id)) as unknown as Promise<Record<string, unknown>>}
      deleteRecord={deleteSampleRow}
      renderQueryForm={() => renderQueryForm()}
      renderFormExtra={renderFormExtra}
    />
  );
}
