"use client"

import type React from "react"
import { createContext, useContext, useState, useCallback, useEffect, useRef, Suspense, useMemo } from "react"
import type { FamilyMember, FamilyTreeData } from "@/types/family"
import { useSession } from "next-auth/react"
import { useSearchParams } from "next/navigation"

interface FamilyTreeInfo {
  id: string
  name: string
  description: string | null
  ownerId: string
  rootMemberId: string | null
  currentUserRole?: "OWNER" | "EDITOR" | "VIEWER"
}

interface FamilyContextType {
  treeData: FamilyTreeData
  currentTree: FamilyTreeInfo | null
  getMember: (id: string) => FamilyMember | undefined
  addMember: (member: FamilyMember) => Promise<{ member: FamilyMember; message?: string }>
  updateMember: (id: string, updates: Partial<FamilyMember>) => Promise<void>
  deleteMember: (id: string) => Promise<{ success: boolean; message?: string; newRootMemberId?: string }>
  searchResults: FamilyMember[]
  searchMembers: (query: string) => void
  loadData: (data: FamilyTreeData) => Promise<void>
  resetData: () => Promise<void>
  refreshData: () => Promise<void>
  isLoading: boolean
  highlightedMemberId: string | null
  setHighlightedMemberId: (id: string | null) => void
}

const FamilyContext = createContext<FamilyContextType | undefined>(undefined)

function FamilyProviderInner({ children }: { children: React.ReactNode }) {
  const { data: session, status } = useSession()
  const searchParams = useSearchParams()
  const [searchResults, setSearchResults] = useState<FamilyMember[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [highlightedMemberId, setHighlightedMemberId] = useState<string | null>(null)
  const [treeData, setTreeData] = useState<FamilyTreeData>({
    rootId: "",
    members: {},
  })
  const [currentTree, setCurrentTree] = useState<FamilyTreeInfo | null>(null)
  const loadingTreeIdRef = useRef<string | null>(null)

  // 监听 URL 和 Session 变化，加载家族树
  useEffect(() => {
    const controller = new AbortController()
    const signal = controller.signal

    const loadTree = async () => {
      const treeId = searchParams.get('treeId')
      
      // 如果 session 正在加载，等待
      if (status === 'loading') {
        return
      }
      
      // 如果 session 不存在（未登录），清除所有数据
      if (!session?.user?.id) {
        if (!signal.aborted) {
          setCurrentTree(null)
          setTreeData({ rootId: "", members: {} })
          setIsLoading(false)
          loadingTreeIdRef.current = null
        }
        return
      }

      // 如果 URL 中有 treeId，使用它
      if (treeId) {
        // 如果正在加载相同的树，跳过
        if (loadingTreeIdRef.current === treeId) {
          return
        }
        
        // 如果 treeId 与当前树相同，跳过
        if (treeId === currentTree?.id) {
          return
        }
      } else {
        // URL 中没有 treeId
        // 如果已经有当前树，保持不变（避免在页面跳转时丢失上下文）
        if (currentTree?.id) {
          return
        }
        // 如果没有当前树，加载第一个
      }
      
      const targetTreeId = treeId || 'first'
      
      // 如果正在加载相同的树，跳过
      if (loadingTreeIdRef.current === targetTreeId) {
        return
      }

      // 标记正在加载
      loadingTreeIdRef.current = targetTreeId
      
      if (!signal.aborted) setIsLoading(true)
      
      const fetchUrl = targetTreeId === 'first' 
        ? '/api/trees' 
        : `/api/trees/${targetTreeId}`
        
      try {
        const res = await fetch(fetchUrl, { signal })
        if (!res.ok) {
          throw new Error(`HTTP error! status: ${res.status}`)
        }
        const data = await res.json()
        
        if (signal.aborted) return

        let tree = null
        if (targetTreeId === 'first') {
          tree = data.trees?.[0]
        } else {
          tree = data.tree
        }
        
        if (tree) {
          setCurrentTree(tree)
          // 加载该树的成员数据
          try {
            const memberRes = await fetch(`/api/trees/${tree.id}/members`, { signal })
            if (!memberRes.ok) {
              throw new Error(`Failed to load members: ${memberRes.status}`)
            }
            const memberData = await memberRes.json()
            
            if (signal.aborted) return

            if (memberData.members) {
              const membersMap = memberData.members.reduce(
                (acc: Record<string, FamilyMember>, member: FamilyMember) => {
                  acc[member.id] = member
                  return acc
                },
                {}
              )
              setTreeData({
                rootId: memberData.rootId || "",
                members: membersMap,
              })
            }
          } catch (err: any) {
            if (err.name === 'AbortError') {
              return
            }
            console.error('加载成员数据失败:', err)
            // 即使成员加载失败，也保留树的信息
            setTreeData({ rootId: "", members: {} })
          }
        } else {
          setCurrentTree(null)
          setTreeData({ rootId: "", members: {} })
        }
      } catch (err: any) {
        if (err.name === 'AbortError') {
          return
        }
        
        // 忽略 Failed to fetch 错误
        if (err.message === 'Failed to fetch' || err.toString().includes('Failed to fetch')) {
          return
        }
        
        console.error('加载家族树失败:', err.message || err)
        setCurrentTree(null)
        setTreeData({ rootId: "", members: {} })
      } finally {
        if (!signal.aborted) {
          setIsLoading(false)
          // 加载完成后清除标记
          loadingTreeIdRef.current = null
        }
      }
    }

    loadTree()

    return () => {
      controller.abort()
    }
  }, [searchParams, session?.user?.id, status])

  const getMember = useCallback(
    (id: string) => {
      return treeData.members[id]
    },
    [treeData],
  )

  const addMember = useCallback(async (member: FamilyMember) => {
    if (!currentTree?.id) throw new Error('没有选择家族树')
    
    const response = await fetch(`/api/trees/${currentTree.id}/members`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(member),
    })
    
    if (!response.ok) {
      const error = await response.json()
      throw new Error(error.error || '添加成员失败')
    }
    
    const data = await response.json()
    
    // 如果发生了代数重新计算，需要重新加载所有成员数据
    if (data.generationRecalculated) {
      const membersResponse = await fetch(`/api/trees/${currentTree.id}/members`)
      if (membersResponse.ok) {
        const membersData = await membersResponse.json()
        const membersMap: Record<string, FamilyMember> = {}
        membersData.members.forEach((m: FamilyMember) => {
          membersMap[m.id] = m
        })
        setTreeData(prev => ({
          rootId: membersData.rootId || prev.rootId,
          members: membersMap,
        }))
        
        // 返回提示信息
        return {
          member: data.member,
          message: `已成功添加成员。由于给始祖添加了父母，全族代数已自动调整（+${data.generationOffset}代）。`
        }
      }
    }
    
    // 更新本地状态
    setTreeData(prev => ({
      ...prev,
      members: {
        ...prev.members,
        [data.member.id]: data.member,
      },
    }))
    
    return { member: data.member }
  }, [currentTree?.id])

  const updateMember = useCallback(async (id: string, updates: Partial<FamilyMember>) => {
    if (!currentTree?.id) throw new Error('没有选择家族树')
    
    // 将 undefined 转为 null，确保 JSON 序列化时能正确传递给后端
    // 否则 JSON.stringify 会忽略 undefined 值，导致后端收不到更新
    const payload = Object.fromEntries(
      Object.entries(updates).map(([key, value]) => [key, value === undefined ? null : value])
    )
    
    const response = await fetch(`/api/trees/${currentTree.id}/members/${id}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
    })
    
    if (!response.ok) {
      const error = await response.json()
      throw new Error(error.error || '更新成员失败')
    }
    
    const data = await response.json()
    
    // 由于后端会维护双向关系,需要重新加载所有成员以保持数据一致性
    // 特别是当修改了关系字段(spouseIds, childrenIds, fatherId, motherId)时
    const hasRelationshipChanges = 
      updates.spouseIds !== undefined || 
      updates.childrenIds !== undefined || 
      updates.fatherId !== undefined || 
      updates.motherId !== undefined
    
    if (hasRelationshipChanges) {
      // 重新加载所有成员数据以同步双向关系
      const membersResponse = await fetch(`/api/trees/${currentTree.id}/members`)
      if (membersResponse.ok) {
        const membersData = await membersResponse.json()
        const membersMap: Record<string, FamilyMember> = {}
        membersData.members.forEach((m: FamilyMember) => {
          membersMap[m.id] = m
        })
        setTreeData(prev => ({
          ...prev,
          members: membersMap,
        }))
        return
      }
    }
    
    // 如果没有关系变更,只更新当前成员
    setTreeData(prev => ({
      ...prev,
      members: {
        ...prev.members,
        [id]: data.member,
      },
    }))
  }, [currentTree?.id])

  const deleteMember = useCallback(async (id: string) => {
    if (!currentTree?.id) throw new Error('没有选择家族树')
    
    const response = await fetch(`/api/trees/${currentTree.id}/members/${id}`, {
      method: 'DELETE',
    })
    
    if (!response.ok) {
      const error = await response.json()
      throw new Error(error.error || '删除成员失败')
    }
    
    const data = await response.json()
    
    // 如果发生了代数重新计算，需要重新加载所有成员数据
    if (data.generationRecalculated) {
      const membersResponse = await fetch(`/api/trees/${currentTree.id}/members`)
      if (membersResponse.ok) {
        const membersData = await membersResponse.json()
        const membersMap: Record<string, FamilyMember> = {}
        membersData.members.forEach((m: FamilyMember) => {
          membersMap[m.id] = m
        })
        setTreeData(prev => ({
          rootId: membersData.rootId || prev.rootId,
          members: membersMap,
        }))
        
        return {
          success: true,
          message: `已成功删除成员。由于删除了始祖，全族代数已自动调整（-1代）。`,
          newRootMemberId: data.newRootMemberId
        }
      }
    }
    
    // 更新本地状态
    setTreeData(prev => {
      const newMembers = { ...prev.members }
      delete newMembers[id]
      return {
        ...prev,
        members: newMembers,
      }
    })
    
    return { success: true }
  }, [currentTree?.id])

  const loadData = useCallback(async (data: FamilyTreeData) => {
    if (!currentTree?.id) throw new Error('没有选择家族树')
    
    // 导入数据到服务器
    const response = await fetch(`/api/trees/${currentTree.id}/import`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    })
    
    if (!response.ok) {
      const error = await response.json()
      throw new Error(error.error || '导入数据失败')
    }
    
    // 重新加载数据
    const membersResponse = await fetch(`/api/trees/${currentTree.id}/members`)
    const membersData = await membersResponse.json()
    
    if (membersData.members) {
      const membersMap = membersData.members.reduce(
        (acc: Record<string, FamilyMember>, member: FamilyMember) => {
          acc[member.id] = member
          return acc
        },
        {}
      )
      setTreeData({
        rootId: membersData.rootId || "",
        members: membersMap,
      })
    }
  }, [currentTree?.id])

  const resetData = useCallback(async () => {
    // 重置为空数据
    setTreeData({ rootId: "", members: {} })
  }, [])

  // 刷新数据（从服务器重新加载当前树的成员数据）
  const refreshData = useCallback(async () => {
    if (!currentTree?.id) return
    
    try {
      setIsLoading(true)
      const membersResponse = await fetch(`/api/trees/${currentTree.id}/members`)
      if (membersResponse.ok) {
        const membersData = await membersResponse.json()
        if (membersData.members) {
          const membersMap = membersData.members.reduce(
            (acc: Record<string, FamilyMember>, member: FamilyMember) => {
              acc[member.id] = member
              return acc
            },
            {}
          )
          setTreeData({
            rootId: membersData.rootId || "",
            members: membersMap,
          })
        }
      }
    } catch (err) {
      console.error('刷新数据失败:', err)
    } finally {
      setIsLoading(false)
    }
  }, [currentTree?.id])

  const searchMembers = useCallback(
    (query: string) => {
      if (!query.trim()) {
        setSearchResults([])
        return
      }

      const lowerQuery = query.toLowerCase()
      // 在内存中的 treeData 上执行搜索，简单快速
      const results = Object.values(treeData.members).filter(
        (member) =>
          member.fullName.includes(lowerQuery) ||
          member.givenName.includes(lowerQuery) ||
          member.courtesyName?.includes(lowerQuery) ||
          member.artName?.includes(lowerQuery),
      )
      setSearchResults(results)
    },
    [treeData],
  )

  // Listen for import events
  useEffect(() => {
    const handleImport = (e: CustomEvent<FamilyTreeData>) => {
      loadData(e.detail)
    }
    window.addEventListener("family-data-import" as any, handleImport as any)
    return () => window.removeEventListener("family-data-import" as any, handleImport as any)
  }, [loadData])

  // 监听 treeData 变化
  // useEffect(() => {
  //   console.log('🔄 FamilyContext treeData 更新:', {
  //     rootId: treeData.rootId,
  //     membersCount: Object.keys(treeData.members).length,
  //     memberIds: Object.keys(treeData.members),
  //     currentTreeId: currentTree?.id,
  //     currentTreeName: currentTree?.name
  //   })
  // }, [treeData, currentTree])

  // 使用 useMemo 缓存 context value，避免不必要的重渲染
  const contextValue = useMemo(() => ({
    treeData,
    currentTree,
    getMember,
    addMember,
    updateMember,
    deleteMember,
    searchResults,
    searchMembers,
    loadData,
    resetData,
    refreshData,
    isLoading,
    highlightedMemberId,
    setHighlightedMemberId,
  }), [
    treeData,
    currentTree,
    getMember,
    addMember,
    updateMember,
    deleteMember,
    searchResults,
    searchMembers,
    loadData,
    resetData,
    refreshData,
    isLoading,
    highlightedMemberId,
  ])

  return (
    <FamilyContext.Provider value={contextValue}>
      {children}
    </FamilyContext.Provider>
  )
}

export function FamilyProvider({ children }: { children: React.ReactNode }) {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <FamilyProviderInner>{children}</FamilyProviderInner>
    </Suspense>
  )
}

export function useFamily() {
  const context = useContext(FamilyContext)
  if (context === undefined) {
    throw new Error("useFamily must be used within a FamilyProvider")
  }
  return context
}
