"use client";

import { useCallback, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
import { Binary, RotateCcw, Search } from "lucide-react";
import { BrapiEntityPage, type BrapiFormField } from "@/components/brapi/BrapiEntityPage";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import {
  createCallSetRow,
  deleteCallSetRow,
  fetchCallSetDetail,
  loadCallSetPageData,
  normalizeCallSetFormData,
  updateCallSetRow,
} from "../api";
import { NONE_SELECT_VALUE, type CallSetQuery, type SelectOption } from "../types";

const emptyQuery = (): CallSetQuery => ({
  call_set_name: "",
  sample_id: NONE_SELECT_VALUE,
  variant_set_id: NONE_SELECT_VALUE,
});

const optionOrNone = (label: string, options: SelectOption[]) => [
  { value: NONE_SELECT_VALUE, label },
  ...options,
];

function normalizeSelectedVariantSetIds(value: unknown): string[] {
  if (!Array.isArray(value)) return [];
  return value.map((item) => String(item ?? "").trim()).filter(Boolean);
}

export function CallSetTab() {
  const searchParams = useSearchParams();
  const [sampleOptions, setSampleOptions] = useState<SelectOption[]>([]);
  const [variantSetOptions, setVariantSetOptions] = useState<SelectOption[]>([]);
  const [draftQuery, setDraftQuery] = useState<CallSetQuery>(emptyQuery);
  const [appliedQuery, setAppliedQuery] = useState<CallSetQuery>(emptyQuery);

  const urlDefaultFormValues = useMemo(() => {
    const sampleId = searchParams.get("sample_id");
    if (!sampleId) return undefined;
    return { sample_id: sampleId };
  }, [searchParams]);

  const loadRows = useCallback(async () => {
    const { options, rows } = await loadCallSetPageData({ query: appliedQuery });
    setSampleOptions(options.samples);
    setVariantSetOptions(options.variantSets);
    return rows as unknown as Record<string, unknown>[];
  }, [appliedQuery]);

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

  const fields = useMemo<BrapiFormField[]>(() => [
    { key: "id", label: "CallSet ID", type: "text", placeholder: "留空则系统自动生成（导入时可指定）" },
    {
      key: "call_set_name",
      label: "CallSet 名称",
      type: "text",
      required: true,
      placeholder: "如 sample01_variantset1",
    },
    {
      key: "sample_id",
      label: "Sample",
      type: "select",
      required: true,
      options: optionOrNone("请选择 Sample", sampleOptions),
    },
  ], [sampleOptions]);

  const renderFormExtra = useCallback(({ formData, updateFormBatch }: {
    formData: Record<string, unknown>;
    updateForm: (key: string, value: string) => void;
    updateFormBatch: (patch: Record<string, unknown>) => void;
    editingRow: Record<string, unknown> | null;
  }) => {
    const selectedIds = normalizeSelectedVariantSetIds(formData.variant_set_ids);

    const toggleVariantSet = (variantSetId: string, checked: boolean) => {
      const next = checked
        ? Array.from(new Set([...selectedIds, variantSetId]))
        : selectedIds.filter((id) => id !== variantSetId);
      updateFormBatch({ variant_set_ids: next });
    };

    return (
      <>
        <div className="md:col-span-2 space-y-2">
          <Label className="text-sm text-slate-700 dark:text-slate-200">VariantSet（可多选）</Label>
          <div className="max-h-48 space-y-2 overflow-y-auto rounded-lg border border-slate-200 p-3 dark:border-slate-800">
            {variantSetOptions.length === 0 ? (
              <p className="text-sm text-slate-500">暂无可选 VariantSet，请先在 VariantSet 页面创建。</p>
            ) : (
              variantSetOptions.map((option) => {
                const checked = selectedIds.includes(option.value);
                return (
                  <label
                    key={option.value}
                    className="flex cursor-pointer items-center gap-2 rounded-md px-1 py-1 text-sm hover:bg-slate-50 dark:hover:bg-slate-900"
                  >
                    <Checkbox
                      checked={checked}
                      onCheckedChange={(value) => toggleVariantSet(option.value, value === true)}
                    />
                    <span>{option.label}</span>
                  </label>
                );
              })
            )}
          </div>
          <p className="text-xs text-slate-500">
            创建或编辑 CallSet 时绑定 VariantSet；导入 allele_call 时也会自动写入 callset_variant_sets 关系。
          </p>
        </div>
        <div className="col-span-2 rounded-lg border border-sky-100 bg-sky-50/60 p-3 text-xs text-sky-900 dark:border-sky-900/40 dark:bg-sky-950/30 dark:text-sky-100">
          <p className="font-medium">callset_variant_sets</p>
          <p className="mt-1 text-sky-800/80 dark:text-sky-200/80">
            此处勾选会写入 callset 与 variantset 的多对多关系，无需单独维护关系表。
          </p>
        </div>
      </>
    );
  }, [variantSetOptions]);

  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">CallSet 名称</Label>
          <Input
            value={draftQuery.call_set_name ?? ""}
            onChange={(event) => setDraftQuery((current) => ({ ...current, call_set_name: event.target.value }))}
            placeholder="callSetName 模糊匹配"
          />
        </div>
        <div className="space-y-1.5">
          <Label className="text-xs text-slate-500">Sample</Label>
          <Select
            value={draftQuery.sample_id ?? NONE_SELECT_VALUE}
            onValueChange={(value) => setDraftQuery((current) => ({ ...current, sample_id: value }))}
          >
            <SelectTrigger><SelectValue placeholder="全部" /></SelectTrigger>
            <SelectContent>
              <SelectItem value={NONE_SELECT_VALUE}>全部</SelectItem>
              {sampleOptions.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">VariantSet</Label>
          <Select
            value={draftQuery.variant_set_id ?? NONE_SELECT_VALUE}
            onValueChange={(value) => setDraftQuery((current) => ({ ...current, variant_set_id: value }))}
          >
            <SelectTrigger><SelectValue placeholder="全部" /></SelectTrigger>
            <SelectContent>
              <SelectItem value={NONE_SELECT_VALUE}>全部</SelectItem>
              {variantSetOptions.map((option) => (
                <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </div>
      <div className="mt-3 flex flex-wrap 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, sampleOptions, variantSetOptions]);

  return (
    <BrapiEntityPage
      useEnhancedDialog
      icon={Binary}
      iconBg="bg-gradient-to-br from-sky-500 to-blue-600"
      title="CallSet 调用集合"
      description="维护 sample 的 genotype call 集合，并绑定其覆盖的 VariantSet。"
      addLabel="新增 CallSet"
      defaultFormValues={urlDefaultFormValues}
      columns={[
        { key: "call_set_name", label: "名称" },
        { key: "sample_name", label: "Sample" },
        {
          key: "variant_set_names",
          label: "VariantSet",
          render: (value) => (
            <Badge variant="outline" className="max-w-xs truncate">
              {String(value ?? "—")}
            </Badge>
          ),
        },
      ]}
      fields={fields}
      data={[]}
      stats={[{
        label: "/brapi/v2/callsets",
        value: "BrAPI",
        className: "bg-sky-50 text-sky-700 dark:bg-sky-400/10 dark:text-sky-200",
      }]}
      loadData={loadRows}
      fetchRecord={fetchRecord}
      createRecord={(payload) => createCallSetRow(payload) as unknown as Promise<Record<string, unknown>>}
      updateRecord={(id, payload) => updateCallSetRow(id, payload) as unknown as Promise<Record<string, unknown>>}
      deleteRecord={deleteCallSetRow}
      renderQueryForm={renderQueryForm}
      renderFormExtra={renderFormExtra}
    />
  );
}
