/**
 * Timeline Horizontal Layout - 横向时间轴布局
 * 
 * 结构：
 * 
 *        Detail1        Detail2        Detail3
 *           │              │              │
 *           │              │              │
 *   ●───────●───────●──────●──────●──────●──────► 时间
 *   Event1       Event2       Event3
 *                 │
 *            SubDetail
 *
 * 特点：
 * - 主节点沿水平时间轴均匀排列
 * - 子节点在时间轴上方或下方交替展开
 * - 连线使用正交折线，清晰规范
 * - 强调时间顺序和进程
 * 
 * 适用场景：
 * - 项目计划/里程碑
 * - 历史事件
 * - 流程步骤
 */

import { LayoutEngine, layoutRegistry } from './LayoutEngine'
import type { Node, Point, IGraphModel } from '../core/types'

export class TimelineHorizontalLayout extends LayoutEngine {
  readonly type = 'timeline-horizontal' as const

  /** 默认配置 */
  protected config = {
    nodeSpacingX: 200,
    nodeSpacingY: 60,
    rootPosition: { x: 150, y: 250 },
    mainNodeGap: 200,       // 主节点间距（时间轴上）
    subNodeGap: 50,         // 子节点垂直间距
    branchOffset: 100,      // 子节点到时间轴的距离
    nodeHeight: 36          // 节点高度
  }

  layout(graph: IGraphModel): Map<string, Point> {
    const positions = new Map<string, Point>()
    const root = graph.root

    if (!root) return positions

    // 根节点位置（时间轴起点）
    positions.set(root.id, { ...this.config.rootPosition })

    // 获取一级子节点（主时间节点）
    const mainNodes = graph.getChildren(root.id).filter(n => !n.hidden)

    if (mainNodes.length === 0) return positions

    this.layoutMainNodes(mainNodes, graph, positions)

    return positions
  }

  /**
   * 布局主时间节点及其后代
   */
  private layoutMainNodes(
    mainNodes: Node[],
    graph: IGraphModel,
    positions: Map<string, Point>
  ): void {
    const rootPos = positions.get(graph.root!.id)!
    const timelineY = rootPos.y  // 时间轴的 Y 坐标
    
    mainNodes.forEach((node, index) => {
      // 主节点位置：沿时间轴排列
      const mainX = rootPos.x + (index + 1) * this.config.mainNodeGap
      const mainY = timelineY

      positions.set(node.id, { x: mainX, y: mainY })

      // 获取子节点
      const children = graph.getChildren(node.id).filter(n => !n.hidden)
      if (children.length === 0) return

      // 子节点交替分布在上、下方
      children.forEach((child, childIndex) => {
        // 交替上下：偶数索引在上方，奇数索引在下方
        const isAbove = childIndex % 2 === 0
        const direction = isAbove ? -1 : 1
        
        // 子节点 X 坐标：在主节点正上方/正下方
        const childX = mainX
        
        // 子节点 Y 坐标：从时间轴向上下延伸
        const childY = timelineY + direction * this.config.branchOffset

        positions.set(child.id, { x: childX, y: childY })

        // 递归布局后代节点（继续沿相同方向延伸）
        this.layoutDescendants(child, graph, positions, childX, childY, direction)
      })
    })
  }

  /**
   * 递归布局后代节点
   * 后代节点继续向远离时间轴的方向延伸
   */
  private layoutDescendants(
    node: Node,
    graph: IGraphModel,
    positions: Map<string, Point>,
    parentX: number,
    parentY: number,
    direction: -1 | 1
  ): void {
    const children = graph.getChildren(node.id).filter(n => !n.hidden)
    if (children.length === 0) return

    const nodeGap = this.config.subNodeGap + this.config.nodeHeight  // 节点中心之间的间距

    // 子节点沿 direction 方向（远离时间轴）依次排列
    children.forEach((child, index) => {
      // 子节点 X 坐标保持不变（与父节点同一垂直线）
      const childX = parentX
      
      // 子节点 Y 坐标：从父节点沿 direction 方向延伸
      const childY = parentY + direction * nodeGap * (index + 1)

      positions.set(child.id, { x: childX, y: childY })

      // 递归布局更深层
      this.layoutDescendants(child, graph, positions, childX, childY, direction)
    })
  }
}

// 注册布局引擎
layoutRegistry.register(new TimelineHorizontalLayout())

export default TimelineHorizontalLayout
