"use client"

import { useEffect, useRef, useState, forwardRef, useImperativeHandle, memo } from "react"
import * as d3 from "d3"
// @ts-ignore - d3-org-chart没有TypeScript类型定义
import { OrgChart } from "d3-org-chart"
import { Download, FileText } from "lucide-react"
import type { FamilyMember } from "@/types/family"
import jsPDF from "jspdf"
import { db } from "@/lib/db"

interface D3OrgChartFlowProps {
  members: Record<string, FamilyMember>
  rootId: string
  onMemberClick?: (memberId: string) => void
  onExport?: () => void
  relationMode?: boolean
  selectedMembers?: string[]
}

export interface D3OrgChartRef {
  exportPNG: () => void
  exportPDF: () => void
  expandAll: () => void
  collapseAll: () => void
  fitView: () => void
}

interface ChartNode {
  id: string
  parentId: string | null
  name: string
  generation: string
  birthYear: string
  deathYear: string
  birthPlace: string
  gender: string
  avatarImageId: string | null | undefined
  spouseName: string
  spouseId: string | null
  hasChildren: boolean
  ageText: string
}

// 计算年龄
function calculateAge(birthDate?: string, deathDate?: string): number | null {
  if (!birthDate) return null
  
  const birth = new Date(birthDate)
  const end = deathDate ? new Date(deathDate) : new Date()
  
  let age = end.getFullYear() - birth.getFullYear()
  const monthDiff = end.getMonth() - birth.getMonth()
  
  if (monthDiff < 0 || (monthDiff === 0 && end.getDate() < birth.getDate())) {
    age--
  }
  
  return age
}

const D3OrgChartFlowComponent = forwardRef<D3OrgChartRef, D3OrgChartFlowProps>(
  ({ members, rootId, onMemberClick, onExport, relationMode = false, selectedMembers = [] }, ref) => {
  console.log('D3OrgChartFlow render, selectedMembers:', selectedMembers, 'relationMode:', relationMode)
  
  const chartRef = useRef<HTMLDivElement>(null)
  const chartInstanceRef = useRef<any>(null)
  const [isReady, setIsReady] = useState(false)
  const [avatarCache, setAvatarCache] = useState<Map<string, string>>(new Map())

  // 转换数据格式
  const convertToChartData = (): ChartNode[] => {
    const chartNodes: ChartNode[] = []
    
    // 首先找到根节点（没有父节点的节点）
    const rootMember = members[rootId]
    if (!rootMember) return []
    
    // 使用BFS遍历，确保只包含从rootId开始的树
    const visited = new Set<string>()
    const queue: string[] = [rootId]
    
    while (queue.length > 0) {
      const currentId = queue.shift()!
      if (visited.has(currentId)) continue
      
      visited.add(currentId)
      const member = members[currentId]
      if (!member) continue
      
      // 获取配偶信息，确保配偶存在于members中
      let spouse = null
      if (member.spouseIds?.[0] && members[member.spouseIds[0]]) {
        spouse = members[member.spouseIds[0]]
      }
      
      // 确定父节点ID - 只有根节点的parentId为null
      let parentId: string | null = null
      if (currentId !== rootId) {
        // 根据姓氏判断主线，优先选择同姓的父母
        const father = member.fatherId ? members[member.fatherId] : null
        const mother = member.motherId ? members[member.motherId] : null
        
        // 判断父母中谁是家族主线（同姓）
        const isFatherMainLine = father && member.surname === father.surname
        const isMotherMainLine = mother && member.surname === mother.surname
        
        if (isFatherMainLine) {
          parentId = member.fatherId || null
        } else if (isMotherMainLine) {
          parentId = member.motherId || null
        } else if (father) {
          // 如果都不同姓，优先选择父亲
          parentId = member.fatherId || null
        } else if (mother) {
          parentId = member.motherId || null
        }
      }
      
      // 计算年龄文本
      const age = calculateAge(member.birthDate, member.deathDate)
      const ageText = age !== null
        ? member.deathDate
          ? `享年${age}岁`
          : `${age}岁`
        : ''
      
      chartNodes.push({
        id: member.id,
        parentId: parentId,
        name: member.fullName,
        generation: `第${member.generation}世`,
        birthYear: member.birthDate ? new Date(member.birthDate).getFullYear().toString() : '',
        deathYear: member.deathDate ? new Date(member.deathDate).getFullYear().toString() : '',
        birthPlace: member.birthPlace || '',
        gender: member.gender === 'MALE' ? '男' : '女',
        avatarImageId: member.avatarImageId,
        spouseName: spouse?.fullName || '',
        spouseId: spouse?.id || null,
        hasChildren: Object.values(members).some(m => m.fatherId === member.id || m.motherId === member.id),
        ageText: ageText
      })
      
      // 添加子节点到队列
      Object.values(members).forEach(m => {
        if ((m.fatherId === currentId || m.motherId === currentId) && !visited.has(m.id)) {
          queue.push(m.id)
        }
      })
    }
    
    return chartNodes
  }

  // 加载所有成员的头像
  useEffect(() => {
    const loadAvatars = async () => {
      const cache = new Map<string, string>()
      
      for (const member of Object.values(members)) {
        if (member.avatarImageId) {
          try {
            const image = await db.images.get(member.avatarImageId)
            if (image) {
              const url = URL.createObjectURL(image.blob)
              cache.set(member.avatarImageId, url)
            }
          } catch (error) {
            console.error(`Failed to load avatar for ${member.fullName}:`, error)
          }
        }
      }
      
      setAvatarCache(cache)
    }
    
    loadAvatars()
    
    // 清理函数
    return () => {
      avatarCache.forEach(url => URL.revokeObjectURL(url))
    }
  }, [members])

  useEffect(() => {
    if (!chartRef.current || !rootId) return

    // 清理旧的图表
    if (chartRef.current) {
      chartRef.current.innerHTML = ''
    }

    const data = convertToChartData()
    
    // 初始化图表
    const chart = new OrgChart()
      .container(chartRef.current)
      .data(data)
      .nodeWidth(() => 160)
      .nodeHeight(() => 120)
      .childrenMargin(() => 50)
      .compactMarginBetween(() => 35)
      .compactMarginPair(() => 35)
      .neighbourMargin(() => 35)
      .siblingsMargin(() => 35)
      .linkUpdate(function (d: any, i: any, arr: any) {
        // 加深连线颜色
        d3.select(arr[i])
          .attr('stroke', '#475569')
          .attr('stroke-width', 2.5)
      })
      .buttonContent(({ node }: any) => {
        return `<div style="color:#716E7B;border-radius:5px;padding:4px;font-size:10px;margin:auto auto;background-color:white;border: 1px solid #E4E2E9"> <span style="font-size:9px">${node.children ? `<i class="fas fa-angle-up"></i>` : `<i class="fas fa-angle-down"></i>`}</span> ${node.data._directSubordinates || 0} </div>`
      })
      .nodeContent((d: any) => {
        const node = d.data
        const color = node.gender === '男' ? '#3b82f6' : '#ec4899'
        const bgColor = node.gender === '男' ? '#dbeafe' : '#fce7f3'
        
        // 获取头像URL
        const avatarUrl = node.avatarImageId ? avatarCache.get(node.avatarImageId) : null
        
        // 检查是否被选中
        const isSelected = selectedMembers.includes(node.id)
        
        return `
          <div style="
            position: relative;
            width: 160px;
            height: 120px;
            box-sizing: border-box;
            background: ${node.deathYear ? '#fafafa' : 'white'};
            border: 2px solid ${color};
            border-radius: 10px;
            padding: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            cursor: pointer;
            transition: all 0.3s;
          " onmouseover="this.style.boxShadow='0 4px 12px rgba(0,0,0,0.2)'" onmouseout="this.style.boxShadow='0 2px 8px rgba(0,0,0,0.1)'">
            <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 5px;">
              <div style="
                width: 40px;
                height: 40px;
                border-radius: 50%;
                background: ${bgColor};
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 16px;
                color: ${color};
                font-weight: bold;
                flex-shrink: 0;
                overflow: hidden;
                border: 1px solid ${color}40;
              ">
                ${avatarUrl 
                  ? `<img src="${avatarUrl}" alt="${node.name}" style="width: 100%; height: 100%; object-fit: cover;" />`
                  : node.gender === '女'
                    ? `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 24px; height: 24px;"><circle cx="12" cy="8" r="5"/><path d="M20 21a8 8 0 1 0-16 0"/></svg>`
                    : `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 24px; height: 24px;"><circle cx="12" cy="8" r="5"/><path d="M20 21a8 8 0 1 0-16 0"/></svg>`
                }
              </div>
              <div style="flex: 1; min-width: 0;">
                <div style="font-size: 13px; font-weight: 600; color: #1f2937; margin-bottom: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: flex; align-items: center; gap: 4px;">
                  <span>${node.name}</span>
                  ${isSelected ? `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#3b82f6" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>` : ''}
                </div>
                <div style="font-size: 9px; color: #6b7280; padding: 1px 4px; background: #f3f4f6; border-radius: 3px; display: inline-block;">
                  ${node.generation}
                </div>
              </div>
            </div>
            
            <div style="font-size: 10px; color: #6b7280; line-height: 1.3;">
              ${node.birthYear ? `<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1px;">
                <span>${node.birthYear}${node.deathYear ? ` - ${node.deathYear}` : ''}</span>
                ${node.ageText ? `<span style="font-size: 9px; color: #9ca3af;">${node.ageText}</span>` : ''}
              </div>` : ''}
              ${node.birthPlace ? `<div style="margin-bottom: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
                ${node.birthPlace}
              </div>` : ''}
            </div>
            
            ${node.spouseName && node.spouseId ? `
              <div 
                class="spouse-area"
                data-spouse-id="${node.spouseId}"
                style="
                  margin-top: 4px;
                  padding: 3px 5px;
                  background: #f9fafb;
                  border: 1px solid #e5e7eb;
                  border-radius: 4px;
                  font-size: 9px;
                  color: #4b5563;
                  overflow: hidden;
                  text-overflow: ellipsis;
                  white-space: nowrap;
                  cursor: pointer;
                  transition: all 0.2s;
                "
                onmouseover="this.style.borderColor='#3b82f6'; this.style.background='#eff6ff'; this.style.color='#1e40af'"
                onmouseout="this.style.borderColor='#e5e7eb'; this.style.background='#f9fafb'; this.style.color='#4b5563'"
              >
                配偶: ${node.spouseName}
              </div>
            ` : ''}
            
            ${node.deathYear ? `
              <div style="
                position: absolute;
                bottom: 4px;
                left: 4px;
                width: 12px;
                height: 12px;
                border-radius: 50%;
                background: #737373;
                border: 2px solid white;
              "></div>
            ` : ''}
          </div>
        `
      })
      .onNodeClick((d: any) => {
        if (onMemberClick && d) {
          // d3-org-chart传递的是节点数据对象，需要提取id
          const nodeId = typeof d === 'string' ? d : (d.data?.id || d.id)
          if (nodeId) {
            onMemberClick(nodeId)
          }
        }
      })
      .render()
      .expandAll() // 初始化时展开所有节点

    // 添加配偶区域点击事件监听
    setTimeout(() => {
      const spouseAreas = chartRef.current?.querySelectorAll('.spouse-area')
      spouseAreas?.forEach((area) => {
        area.addEventListener('click', (e) => {
          e.stopPropagation() // 阻止事件冒泡到节点
          const spouseId = (area as HTMLElement).getAttribute('data-spouse-id')
          if (spouseId && onMemberClick) {
            onMemberClick(spouseId)
          }
        })
      })
    }, 100)

    chartInstanceRef.current = chart
    setIsReady(true)

    return () => {
      // 清理
      if (chartRef.current) {
        chartRef.current.innerHTML = ''
      }
    }
  }, [members, rootId, onMemberClick, avatarCache])

  // 监听selectedMembers变化，动态显示/隐藏勾选图标
  // 逻辑已移至tree/page.tsx以避免组件重新渲染
  
  // 导出PNG
  const handleExportPNG = () => {
    if (!chartInstanceRef.current) return

    chartInstanceRef.current.exportImg({
      save: true,
      full: true,
      onLoad: () => {
        onExport?.()
      }
    })
  }

  // 导出PDF
  const handleExportPDF = () => {
    if (!chartInstanceRef.current) return

    chartInstanceRef.current.exportImg({
      save: false,
      full: true,
      onLoad: (base64: string) => {
        const pdf = new jsPDF({
          orientation: 'landscape',
          unit: 'px',
          format: 'a4'
        })
        
        const img = new Image()
        img.src = base64
        img.onload = function () {
          const imgWidth = img.width
          const imgHeight = img.height
          const pdfWidth = pdf.internal.pageSize.getWidth()
          const pdfHeight = pdf.internal.pageSize.getHeight()
          
          // 计算缩放比例以适应页面
          const ratio = Math.min(pdfWidth / imgWidth, pdfHeight / imgHeight)
          const scaledWidth = imgWidth * ratio
          const scaledHeight = imgHeight * ratio
          
          // 居中放置
          const x = (pdfWidth - scaledWidth) / 2
          const y = (pdfHeight - scaledHeight) / 2
          
          pdf.addImage(img, 'PNG', x, y, scaledWidth, scaledHeight)
          pdf.save(`家谱图-${new Date().toISOString().split('T')[0]}.pdf`)
          onExport?.()
        }
      }
    })
  }

  // 展开所有节点
  const handleExpandAll = () => {
    if (!chartInstanceRef.current) return
    chartInstanceRef.current.expandAll()
  }

  // 折叠所有节点
  const handleCollapseAll = () => {
    if (!chartInstanceRef.current) return
    chartInstanceRef.current.collapseAll()
  }

  // 适应视图
  const handleFitView = () => {
    if (!chartInstanceRef.current) return
    chartInstanceRef.current.fit()
  }

  // 暴露方法给父组件
  useImperativeHandle(ref, () => ({
    exportPNG: handleExportPNG,
    exportPDF: handleExportPDF,
    expandAll: handleExpandAll,
    collapseAll: handleCollapseAll,
    fitView: handleFitView,
  }))

  return (
    <div className="w-full h-full bg-background rounded-lg border relative" key={`d3-chart-${rootId}`}>
      {/* 图表容器 */}
      <div 
        ref={chartRef} 
        className="w-full h-full"
        style={{ overflow: 'hidden' }}
      />
    </div>
  )
})

D3OrgChartFlowComponent.displayName = 'D3OrgChartFlow'

// 使用memo优化，避免不必要的重新渲染
export const D3OrgChartFlow = memo(D3OrgChartFlowComponent, (prevProps, nextProps) => {
  return prevProps.rootId === nextProps.rootId && 
         prevProps.members === nextProps.members
})
