"use client" import { useMemo, useState, useEffect } from "react" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog" import { Input } from "@/components/ui/input" import { Button } from "@/components/ui/button" import { Label } from "@/components/ui/label" import { ScrollArea } from "@/components/ui/scroll-area" import { MemberNameWithStatus } from "@/components/member-name-with-status" import { useFamily } from "@/context/family-context" import { useToast } from "@/components/ui/use-toast" import type { FamilyMember } from "@/types/family" import { GenerationWarningDialog } from "@/components/tree/generation-warning-dialog" import { shouldShowGenerationWarning } from "@/lib/generation-utils" export type RelationType = "child" | "spouse" | "father" | "mother" interface AddRelationDialogProps { open: boolean onOpenChange: (open: boolean) => void member: FamilyMember relationType: RelationType onCreateNew: (prefillName: string, relationType: RelationType) => void } interface CandidateMeta { member: FamilyMember fatherName?: string motherName?: string } export function AddRelationDialog({ open, onOpenChange, member, relationType, onCreateNew, }: AddRelationDialogProps) { const { treeData, updateMember } = useFamily() const { toast } = useToast() const [query, setQuery] = useState("") const [linkingId, setLinkingId] = useState(null) // 代数重新计算警告对话框状态 const [showWarningDialog, setShowWarningDialog] = useState(false) const [pendingAction, setPendingAction] = useState<{ type: 'link' | 'create', target?: FamilyMember } | null>(null) useEffect(() => { if (!open) { setQuery("") setLinkingId(null) setShowWarningDialog(false) setPendingAction(null) } }, [open]) const normalizedQuery = query.trim().toLowerCase() const candidates: CandidateMeta[] = useMemo(() => { if (!normalizedQuery) return [] const members = Object.values(treeData.members) return members .filter((candidate) => { if (candidate.id === member.id) return false if (!candidate.fullName.toLowerCase().includes(normalizedQuery) && !(candidate.givenName || "").toLowerCase().includes(normalizedQuery) && !(candidate.courtesyName || "").toLowerCase().includes(normalizedQuery)) { return false } if (relationType === "child") { if (candidate.generation !== (member.generation + 1)) return false if (member.childrenIds?.includes(candidate.id)) return false if (member.spouseIds?.includes(candidate.id)) return false const fatherMatches = candidate.fatherId ? candidate.fatherId === member.id : true const motherMatches = candidate.motherId ? candidate.motherId === member.id : true if (member.gender === "MALE" && !fatherMatches) return false if (member.gender === "FEMALE" && !motherMatches) return false if (member.gender !== "MALE" && member.gender !== "FEMALE") { if (candidate.fatherId && candidate.motherId) return false } } else if (relationType === "spouse") { if (candidate.generation !== member.generation) return false if (member.spouseIds?.includes(candidate.id)) return false if (candidate.spouseIds?.includes(member.id)) return false if (candidate.gender === member.gender) return false } else if (relationType === "father") { if (candidate.gender !== "MALE") return false if (candidate.generation !== (member.generation - 1)) return false if (member.fatherId === candidate.id) return false } else if (relationType === "mother") { if (candidate.gender !== "FEMALE") return false if (candidate.generation !== (member.generation - 1)) return false if (member.motherId === candidate.id) return false } return true }) .slice(0, 8) .map((candidate) => ({ member: candidate, fatherName: candidate.fatherId ? treeData.members[candidate.fatherId]?.fullName : undefined, motherName: candidate.motherId ? treeData.members[candidate.motherId]?.fullName : undefined, })) }, [member, relationType, treeData.members, normalizedQuery]) const handleLink = async (target: FamilyMember) => { // 检查是否需要显示代数重新计算警告 if ((relationType === 'father' || relationType === 'mother') && shouldShowGenerationWarning(member, relationType)) { setPendingAction({ type: 'link', target }) setShowWarningDialog(true) return } await performLink(target) } const performLink = async (target: FamilyMember) => { try { setLinkingId(target.id) if (relationType === "child") { const payload: Partial = {} if (member.gender === "FEMALE") { payload.motherId = member.id } else if (member.gender === "MALE") { payload.fatherId = member.id } else { if (!target.fatherId) { payload.fatherId = member.id } else if (!target.motherId) { payload.motherId = member.id } else { throw new Error("该成员已绑定父母") } } await updateMember(target.id, payload) toast({ title: "关联成功", description: `已将 ${target.fullName} 标记为 ${member.fullName} 的子女。` }) } else if (relationType === "spouse") { const existing = new Set(member.spouseIds || []) existing.add(target.id) await updateMember(member.id, { spouseIds: Array.from(existing) }) toast({ title: "关联成功", description: `${member.fullName} 与 ${target.fullName} 已建立配偶关系。` }) } else if (relationType === "father") { await updateMember(member.id, { fatherId: target.id }) toast({ title: "关联成功", description: `已将 ${target.fullName} 设为 ${member.fullName} 的父亲。` }) } else if (relationType === "mother") { await updateMember(member.id, { motherId: target.id }) toast({ title: "关联成功", description: `已将 ${target.fullName} 设为 ${member.fullName} 的母亲。` }) } onOpenChange(false) } catch (error) { const message = error instanceof Error ? error.message : "关联失败" toast({ title: "操作失败", description: message, variant: "destructive", }) } finally { setLinkingId(null) } } const handleCreateNew = () => { if (!normalizedQuery) return // 检查是否需要显示代数重新计算警告 if ((relationType === 'father' || relationType === 'mother') && shouldShowGenerationWarning(member, relationType)) { setPendingAction({ type: 'create' }) setShowWarningDialog(true) return } onCreateNew(query.trim(), relationType) } // 确认添加父母后的处理 const handleConfirmAddParent = () => { if (pendingAction?.type === 'link' && pendingAction.target) { performLink(pendingAction.target) } else if (pendingAction?.type === 'create') { onCreateNew(query.trim(), relationType) } setPendingAction(null) } return ( <> 添加{relationType === "child" ? "子女" : relationType === "spouse" ? "配偶" : relationType === "father" ? "父亲" : "母亲"} 先输入姓名,系统会检索已有成员。若没有匹配,可直接新建。
setQuery(e.target.value)} />
{normalizedQuery ? ( candidates.length > 0 ? (

找到以下可能的匹配:

{candidates.map(({ member: candidate, fatherName, motherName }) => (

第 {candidate.generation} 世 · {candidate.gender === "FEMALE" ? "女" : "男"}

父亲:{fatherName || "未登记"}
母亲:{motherName || "未登记"}
))}
) : (

未找到匹配成员,可直接创建新成员。

) ) : (

请输入姓名以搜索已有成员。

)}
{/* 代数重新计算警告对话框 */} {pendingAction && (relationType === 'father' || relationType === 'mother') && ( )} ) }