"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { GitBranch, Pencil, Plus, Trash2 } from "lucide-react";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  Dialog,
  DialogBody,
  DialogContent,
  DialogFooter,
} from "@/components/common/shadcn-enhanced";
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 { Skeleton } from "@/components/ui/skeleton";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { cn } from "@/lib/utils";
import { EDGE_TYPE_OPTIONS, PARENT_TYPE_OPTIONS, edgeTypeLabel, parentTypeLabel } from "../constants";
import {
  buildPedigreeEdgeFormState,
  fetchPedigreeEdgeRows,
  fetchPedigreeRows,
  removePedigreeEdge,
  upsertPedigreeEdge,
} from "../api";
import { NONE_SELECT_VALUE, type PedigreeEdgeFormState, type PedigreeEdgeRow, type SelectOption } from "../types";

interface PedigreeEdgePanelProps {
  scopeGermplasmDbId?: string;
  compact?: boolean;
  onChanged?: () => void;
}

export function PedigreeEdgePanel({ scopeGermplasmDbId, compact = false, onChanged }: PedigreeEdgePanelProps) {
  const [rows, setRows] = useState<PedigreeEdgeRow[]>([]);
  const [nodeOptions, setNodeOptions] = useState<SelectOption[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [search, setSearch] = useState("");
  const [dialogOpen, setDialogOpen] = useState(false);
  const [saving, setSaving] = useState(false);
  const [form, setForm] = useState<PedigreeEdgeFormState | null>(null);
  const [editingEdgeId, setEditingEdgeId] = useState<string | null>(null);
  const [deletingEdge, setDeletingEdge] = useState<PedigreeEdgeRow | null>(null);
  const [deleting, setDeleting] = useState(false);
  const saveLockRef = useRef(false);

  const loadRows = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const [edgeRows, nodes] = await Promise.all([
        fetchPedigreeEdgeRows(scopeGermplasmDbId),
        fetchPedigreeRows(),
      ]);
      setRows(edgeRows);
      setNodeOptions(
        nodes
          .filter((node) => node.germplasm_id)
          .map((node) => ({
            value: node.germplasm_id as string,
            label: node.germplasm_name || node.germplasm_id || "",
          })),
      );
    } catch (event) {
      setError(event instanceof Error ? event.message : "加载失败");
    } finally {
      setLoading(false);
    }
  }, [scopeGermplasmDbId]);

  useEffect(() => {
    loadRows();
  }, [loadRows]);

  const filteredRows = useMemo(() => {
    const keyword = search.trim().toLowerCase();
    if (!keyword) return rows;
    return rows.filter((row) =>
      [
        row.this_node_name,
        row.connected_node_name,
        row.edge_type,
        row.parent_type,
        row.this_node_id,
        row.connected_node_id,
      ].some((value) => String(value ?? "").toLowerCase().includes(keyword)),
    );
  }, [rows, search]);

  const openCreate = () => {
    if (nodeOptions.length < 2) {
      setError("请先在「Pedigree Node 系谱节点」创建至少两个节点");
      return;
    }
    setEditingEdgeId(null);
    const nextForm = buildPedigreeEdgeFormState();
    if (scopeGermplasmDbId) {
      nextForm.this_node_id = scopeGermplasmDbId;
    }
    setForm(nextForm);
    setDialogOpen(true);
  };

  const openEdit = (row: PedigreeEdgeRow) => {
    if (row.read_only || row.edge_type === "sibling") {
      setError("同胞关系为只读展示，请通过 parent 关系维护");
      return;
    }
    setEditingEdgeId(row.id);
    setForm(buildPedigreeEdgeFormState(row));
    setDialogOpen(true);
  };

  const handleSave = async () => {
    if (!form || saveLockRef.current) return;
    saveLockRef.current = true;
    setSaving(true);
    setError(null);
    try {
      await upsertPedigreeEdge(form, editingEdgeId ?? undefined);
      setDialogOpen(false);
      await loadRows();
      onChanged?.();
    } catch (event) {
      setError(event instanceof Error ? event.message : "保存失败");
    } finally {
      setSaving(false);
      saveLockRef.current = false;
    }
  };

  const handleDelete = async () => {
    if (!deletingEdge || saveLockRef.current) return;
    saveLockRef.current = true;
    setDeleting(true);
    setError(null);
    try {
      await removePedigreeEdge(deletingEdge.id);
      setDeletingEdge(null);
      await loadRows();
      onChanged?.();
    } catch (event) {
      setError(event instanceof Error ? event.message : "删除失败");
    } finally {
      setDeleting(false);
      saveLockRef.current = false;
    }
  };

  const showParentType = form?.edge_type === "parent" || form?.edge_type === "child";
  const lockThisNode = Boolean(scopeGermplasmDbId);

  return (
    <div className="flex min-h-full flex-col gap-4">
      <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
        <div className="flex items-center gap-3">
          <div className={cn("rounded-xl p-2.5", "bg-gradient-to-br from-cyan-500 to-teal-600")}>
            <GitBranch className="h-5 w-5 text-white" />
          </div>
          <div>
            <h2 className="text-lg font-semibold text-slate-900 dark:text-slate-50">
              {compact ? "系谱边" : "Pedigree Edge 系谱边"}
            </h2>
            <p className="mt-0.5 text-sm text-slate-500 dark:text-slate-400">
              {scopeGermplasmDbId
                ? "维护当前种质节点的 parent / child 关系；sibling 由 BrAPI 自动推断（只读）。"
                : "pedigree_edge：维护节点之间的 parent / child 关系；sibling 由 BrAPI 根据共享亲本自动推断（只读展示）"}
            </p>
          </div>
        </div>
        <Button onClick={openCreate} className="shrink-0 gap-1">
          <Plus className="h-4 w-4" />
          新增系谱边
        </Button>
      </div>

      {!compact ? (
        <div className="mb-1">
          <span className="rounded-full bg-cyan-50 px-3 py-1 text-xs text-cyan-700 dark:bg-cyan-400/10 dark:text-cyan-200">
            BrAPI PUT /brapi/v2/pedigree（parents 字段）
          </span>
        </div>
      ) : null}

      <div className="rounded-xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-950">
        <div className="mb-4 flex flex-wrap items-center gap-3">
          <Input
            value={search}
            onChange={(event) => setSearch(event.target.value)}
            placeholder="搜索当前材料 / 关联材料 / 关系类型"
            className="max-w-sm"
          />
        </div>

        {error ? <p className="mb-3 text-sm text-red-500">{error}</p> : null}

        {loading ? (
          <Skeleton className="h-40 w-full" />
        ) : (
          <Table>
            <TableHeader>
              <TableRow className="bg-slate-50 dark:bg-slate-900">
                <TableHead>关系类型</TableHead>
                <TableHead>当前材料</TableHead>
                <TableHead>关联材料</TableHead>
                <TableHead>parent_type</TableHead>
                <TableHead className="w-28 text-right">操作</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {filteredRows.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={5} className="py-8 text-center text-sm text-slate-400">
                    暂无系谱边。请先创建系谱节点，再维护 parent / child 关系。
                  </TableCell>
                </TableRow>
              ) : (
                filteredRows.map((row) => (
                  <TableRow key={row.id}>
                    <TableCell>
                      {edgeTypeLabel(row.edge_type)}
                      {row.read_only ? (
                        <span className="ml-2 text-xs text-slate-400">只读</span>
                      ) : null}
                    </TableCell>
                    <TableCell>{row.this_node_name || row.this_node_id}</TableCell>
                    <TableCell>{row.connected_node_name || row.connected_node_id}</TableCell>
                    <TableCell>{parentTypeLabel(row.parent_type)}</TableCell>
                    <TableCell className="text-right">
                      {!row.read_only ? (
                        <div className="flex justify-end gap-1">
                          <Button size="sm" variant="outline" className="gap-1" onClick={() => openEdit(row)}>
                            <Pencil className="h-3.5 w-3.5" />
                            编辑
                          </Button>
                          <Button
                            size="sm"
                            variant="outline"
                            className="gap-1 text-red-600 hover:text-red-600"
                            onClick={() => setDeletingEdge(row)}
                          >
                            <Trash2 className="h-3.5 w-3.5" />
                            删除
                          </Button>
                        </div>
                      ) : (
                        <span className="text-xs text-slate-400">—</span>
                      )}
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        )}
      </div>

      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="max-w-xl" title={editingEdgeId ? "编辑系谱边" : "新增系谱边"}>
          <DialogBody className="space-y-4">
            <div>
              <Label className="mb-1.5 block text-sm">edge_type 关系类型</Label>
              <Select
                value={form?.edge_type || "parent"}
                onValueChange={(value) => {
                  if (!form) return;
                  setForm({ ...form, edge_type: value });
                }}
              >
                <SelectTrigger><SelectValue placeholder="选择关系类型" /></SelectTrigger>
                <SelectContent position="popper" className="z-[110]">
                  {EDGE_TYPE_OPTIONS.map((option) => (
                    <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div>
              <Label className="mb-1.5 block text-sm">当前材料</Label>
              <Select
                value={form?.this_node_id || NONE_SELECT_VALUE}
                onValueChange={(value) => {
                  if (!form || lockThisNode) return;
                  setForm({ ...form, this_node_id: value });
                }}
                disabled={lockThisNode}
              >
                <SelectTrigger><SelectValue placeholder="选择当前材料" /></SelectTrigger>
                <SelectContent position="popper" className="z-[110] max-h-60">
                  <SelectItem value={NONE_SELECT_VALUE}>请选择当前材料</SelectItem>
                  {nodeOptions.map((option) => (
                    <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div>
              <Label className="mb-1.5 block text-sm">关联材料</Label>
              <Select
                value={form?.connected_node_id || NONE_SELECT_VALUE}
                onValueChange={(value) => {
                  if (!form) return;
                  setForm({ ...form, connected_node_id: value });
                }}
              >
                <SelectTrigger><SelectValue placeholder="选择关联材料" /></SelectTrigger>
                <SelectContent position="popper" className="z-[110] max-h-60">
                  <SelectItem value={NONE_SELECT_VALUE}>请选择关联材料</SelectItem>
                  {nodeOptions
                    .filter((option) => option.value !== scopeGermplasmDbId)
                    .map((option) => (
                      <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
                    ))}
                </SelectContent>
              </Select>
            </div>

            {showParentType ? (
              <div>
                <Label className="mb-1.5 block text-sm">parent_type 亲本类型</Label>
                <Select
                  value={form?.parent_type || NONE_SELECT_VALUE}
                  onValueChange={(value) => {
                    if (!form) return;
                    setForm({ ...form, parent_type: value });
                  }}
                >
                  <SelectTrigger><SelectValue placeholder="选择亲本类型" /></SelectTrigger>
                  <SelectContent position="popper" className="z-[110]">
                    <SelectItem value={NONE_SELECT_VALUE}>请选择 parent_type</SelectItem>
                    {PARENT_TYPE_OPTIONS.map((option) => (
                      <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            ) : null}

            <p className="text-xs text-slate-500 dark:text-slate-400">
              parent：当前材料为子代，关联材料为亲本；child：当前材料为亲本，关联材料为子代。
            </p>
          </DialogBody>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDialogOpen(false)} disabled={saving}>取消</Button>
            <Button
              onClick={handleSave}
              disabled={
                saving
                || !form
                || form.this_node_id === NONE_SELECT_VALUE
                || form.connected_node_id === NONE_SELECT_VALUE
                || (showParentType && form.parent_type === NONE_SELECT_VALUE)
              }
            >
              {saving ? "保存中..." : "保存"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <AlertDialog open={Boolean(deletingEdge)} onOpenChange={(open) => !open && setDeletingEdge(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>确认删除系谱边？</AlertDialogTitle>
            <AlertDialogDescription>
              将移除
              {" "}
              {deletingEdge ? edgeTypeLabel(deletingEdge.edge_type) : ""}
              {" "}
              关系：
              {deletingEdge?.this_node_name || deletingEdge?.this_node_id}
              {" → "}
              {deletingEdge?.connected_node_name || deletingEdge?.connected_node_id}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={deleting}>取消</AlertDialogCancel>
            <AlertDialogAction onClick={handleDelete} disabled={deleting}>
              {deleting ? "删除中..." : "确认删除"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
