/**
 * Layout Engine - 布局引擎接口
 * 
 * 职责：
 * - 定义布局引擎的标准接口
 * - 计算节点位置
 * - 返回位置映射
 * 
 * 设计原则：
 * - 输入：图结构
 * - 输出：节点位置
 * - 纯函数，不修改原图数据
 */

import type { Node, Point, LayoutType, LayoutConfig, IGraphModel } from '../core/types'

/**
 * 布局引擎基类
 */
export abstract class LayoutEngine {
  abstract readonly type: LayoutType
  
  /** 默认配置 */
  protected config: LayoutConfig = {
    nodeSpacingX: 200,
    nodeSpacingY: 60,
    rootPosition: { x: 400, y: 300 }
  }

  /** 设置配置 */
  setConfig(config: Partial<LayoutConfig>): void {
    this.config = { ...this.config, ...config }
  }

  /** 获取默认配置 */
  getDefaultConfig(): LayoutConfig {
    return { ...this.config }
  }

  /**
   * 执行布局计算
   * @param graph 图模型
   * @returns 节点ID -> 位置的映射
   */
  abstract layout(graph: IGraphModel): Map<string, Point>

  /**
   * 计算子树尺寸（用于布局优化）
   * 优先使用 node.size（由 TextNodeMeasurer 预计算的自适应尺寸）
   * 降级使用 nodeHeight 参数（兼容未计算尺寸的场景）
   */
  protected calcSubtreeSize(
    node: Node, 
    graph: IGraphModel,
    nodeHeight: number = 36,
    gap: number = 30
  ): number {
    const actualHeight = node.size?.height || nodeHeight
    const children = graph.getChildren(node.id)
    if (children.length === 0) {
      return actualHeight + gap
    }
    return children.reduce(
      (sum, child) => sum + this.calcSubtreeSize(child, graph, nodeHeight, gap), 
      0
    )
  }

  /**
   * 获取节点宽度（优先使用预计算的自适应宽度）
   */
  protected getNodeWidth(node: Node, defaultWidth: number = 120): number {
    return node.size?.width || defaultWidth
  }

  /**
   * 获取可见节点（非隐藏）
   */
  protected getVisibleNodes(graph: IGraphModel): Node[] {
    return graph.nodes.filter(n => !n.hidden)
  }
}

/**
 * 布局引擎注册表
 */
export class LayoutRegistry {
  private engines: Map<LayoutType, LayoutEngine> = new Map()

  /** 注册布局引擎 */
  register(engine: LayoutEngine): void {
    this.engines.set(engine.type, engine)
  }

  /** 获取布局引擎 */
  get(type: LayoutType): LayoutEngine | undefined {
    return this.engines.get(type)
  }

  /** 获取所有布局类型 */
  getTypes(): LayoutType[] {
    return Array.from(this.engines.keys())
  }
}

// 创建全局注册表实例
export const layoutRegistry = new LayoutRegistry()
