'use client'

/**
 * ServiceTopology — React Flow 嵌套群組拓撲圖主元件
 * ==================================================
 * Sprint 5 Phase 2: 串接真實 dashboard API
 *
 * 功能:
 *   - 從 useDashboardStore 讀取真實主機/服務資料
 *   - elkjs 自動排版 (compound graph)
 *   - 展開/收合群組互動
 *   - 控制列: 全部展開/收合/只看異常
 *   - MiniMap + Controls
 *
 * 零假數據: 所有資料來自 HostAggregator 真實探測
 *
 * 建立時間: 2026-04-08 (台北時區)
 * 修改時間: 2026-04-10 — B2 elkjs + 展開收合 (Claude Code Sprint 5R)
 */

import { useCallback, useMemo, useState } from 'react'
import {
  ReactFlow,
  Controls,
  MiniMap,
  Background,
  BackgroundVariant,
  type NodeTypes,
  type EdgeTypes,
} from '@xyflow/react'
import '@xyflow/react/dist/style.css'

import { useTranslations } from 'next-intl'
import { useTopologyData } from './hooks/useTopologyData'
import { useElkLayout } from './hooks/useElkLayout'
import { ServiceNode } from './nodes/ServiceNode'
import { GroupNode } from './nodes/GroupNode'
import { TopologyEdge } from './edges/TopologyEdge'

// =============================================================================
// Node/Edge Types (React Flow 需要在元件外定義，避免每次 render 重建)
// =============================================================================

const nodeTypes: NodeTypes = {
  serviceNode: ServiceNode,
  groupNode: GroupNode,
}

const edgeTypes: EdgeTypes = {
  topologyEdge: TopologyEdge,
}

// =============================================================================
// Props
// =============================================================================

export interface ServiceTopologyProps {
  /** 顯示模式: compact=收合群組, full=可展開 */
  mode?: 'compact' | 'full'
  /** 顯示控制列 */
  showControls?: boolean
  /** 顯示迷你地圖 */
  showMiniMap?: boolean
  /** 高度 (預設 100%) */
  height?: number | string
}

// =============================================================================
// 元件
// =============================================================================

export function ServiceTopology({
  mode = 'compact',
  showControls = true,
  showMiniMap = false,
  height = '100%',
}: ServiceTopologyProps) {
  const t = useTranslations('dashboard')
  const { nodes: rawNodes, edges, hostCount, serviceCount, healthyCount, warningCount } = useTopologyData()

  // 展開/收合狀態
  const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set())
  // 只看異常
  const [warningOnly, setWarningOnly] = useState(false)

  // 切換單一群組展開
  const handleToggle = useCallback((groupId: string) => {
    setExpandedGroups(prev => {
      const next = new Set(prev)
      if (next.has(groupId)) next.delete(groupId)
      else next.add(groupId)
      return next
    })
  }, [])

  // 全部展開/收合
  const expandAll = useCallback(() => {
    setExpandedGroups(new Set(rawNodes.filter(n => n.type === 'groupNode').map(n => n.id)))
  }, [rawNodes])

  const collapseAll = useCallback(() => {
    setExpandedGroups(new Set())
  }, [])

  // 注入 onToggle + isExpanded + id 到 groupNode data
  const augmentedNodes = useMemo(() => {
    return rawNodes
      .filter(node => {
        if (!warningOnly) return true
        // 只看異常: 保留有警告的群組 + 其底下的服務
        if (node.type === 'groupNode') {
          const d = node.data as Record<string, any>
          return d.healthyServices < d.serviceCount
        }
        if (node.type === 'serviceNode') {
          const d = node.data as Record<string, any>
          return d.status !== 'up'
        }
        return true
      })
      .map(node => {
        if (node.type !== 'groupNode') return node
        return {
          ...node,
          data: {
            ...node.data,
            id: node.id,
            isExpanded: expandedGroups.has(node.id),
            onToggle: handleToggle,
          },
        }
      })
  }, [rawNodes, expandedGroups, handleToggle, warningOnly])

  // elkjs 排版
  const { nodes: layoutNodes, loading } = useElkLayout(augmentedNodes, edges, expandedGroups)

  // 空狀態
  if (rawNodes.length === 0) {
    return (
      <div style={{
        display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
        height: typeof height === 'number' ? height : '100%',
        color: '#87867f', fontSize: 13,
      }}>
        <div style={{ fontSize: 28, opacity: 0.3, marginBottom: 8 }}>--</div>
        <div>{t('waitingHostData')}</div>
        <div style={{ fontSize: 10, marginTop: 4 }}>{t('dashboardConnecting')}</div>
      </div>
    )
  }

  const allExpanded = expandedGroups.size === rawNodes.filter(n => n.type === 'groupNode').length
  const allCollapsed = expandedGroups.size === 0

  return (
    <div style={{ height, position: 'relative' }}>
      {/* 狀態列 */}
      <div style={{
        position: 'absolute', top: 8, left: 12, zIndex: 10,
        display: 'flex', alignItems: 'center', gap: 12,
        fontSize: 10, color: '#87867f',
        background: 'rgba(250,249,243,0.9)', padding: '4px 10px', borderRadius: 6,
        border: '0.5px solid #e0ddd4',
      }}>
        <span>{hostCount} {t('hostsLabel')}</span>
        <span>{serviceCount}</span>
        <span style={{ color: '#22C55E' }}>{healthyCount}</span>
        {warningCount > 0 && <span style={{ color: '#F59E0B' }}>{warningCount}</span>}
        {loading && <span style={{ color: '#87867f', fontSize: 9 }}>排版中…</span>}
      </div>

      {/* 過濾控制列 */}
      <div style={{
        position: 'absolute', top: 8, right: 12, zIndex: 10,
        display: 'flex', alignItems: 'center', gap: 6,
        fontSize: 10,
      }}>
        <button
          onClick={expandAll}
          disabled={allExpanded}
          style={{
            padding: '3px 8px', borderRadius: 4, border: '0.5px solid #e0ddd4',
            background: 'rgba(250,249,243,0.9)', color: allExpanded ? '#c0beb8' : '#555550',
            cursor: allExpanded ? 'default' : 'pointer', fontSize: 10,
          }}
        >
          全展開
        </button>
        <button
          onClick={collapseAll}
          disabled={allCollapsed}
          style={{
            padding: '3px 8px', borderRadius: 4, border: '0.5px solid #e0ddd4',
            background: 'rgba(250,249,243,0.9)', color: allCollapsed ? '#c0beb8' : '#555550',
            cursor: allCollapsed ? 'default' : 'pointer', fontSize: 10,
          }}
        >
          全收合
        </button>
        {warningCount > 0 && (
          <button
            onClick={() => setWarningOnly(w => !w)}
            style={{
              padding: '3px 8px', borderRadius: 4, border: `0.5px solid ${warningOnly ? '#F59E0B' : '#e0ddd4'}`,
              background: warningOnly ? 'rgba(245,158,11,0.1)' : 'rgba(250,249,243,0.9)',
              color: warningOnly ? '#F59E0B' : '#555550',
              cursor: 'pointer', fontSize: 10,
            }}
          >
            只看異常
          </button>
        )}
      </div>

      <ReactFlow
        nodes={layoutNodes}
        edges={edges}
        nodeTypes={nodeTypes}
        edgeTypes={edgeTypes}
        fitView
        fitViewOptions={{ padding: 0.2 }}
        minZoom={0.3}
        maxZoom={2}
        proOptions={{ hideAttribution: true }}
        style={{ background: '#f5f4ed' }}
      >
        <Background variant={BackgroundVariant.Dots} gap={20} size={0.5} color="#d8d5cc" />
        {showControls && <Controls position="bottom-right" />}
        {showMiniMap && (
          <MiniMap
            nodeColor={(node) => {
              if (node.type === 'groupNode') return (node.data.color as string) || '#e0ddd4'
              const status = node.data.status as string
              if (status === 'up') return '#22C55E'
              if (status === 'down') return '#cc2200'
              return '#F59E0B'
            }}
            maskColor="rgba(245,244,237,0.8)"
            style={{ border: '0.5px solid #e0ddd4', borderRadius: 6 }}
          />
        )}
      </ReactFlow>
    </div>
  )
}

export default ServiceTopology
