/**
 * 字段联动管理器
 * 管理字段之间的依赖关系和联动逻辑
 */

import type { FieldDependency, FormData } from '@/types/form'

/**
 * 字段联动管理器类
 */
export class FieldDependencyManager {
  /** 联动配置列表 */
  private dependencies: FieldDependency[] = []

  /** 字段变化回调 */
  private callbacks: Map<string, Set<(targetField: string, action: any) => void>> = new Map()

  /**
   * 添加联动配置
   * @param dep 联动配置
   */
  addDependency(dep: FieldDependency): void {
    // 检查是否已存在相同的联动配置
    const existingIndex = this.dependencies.findIndex(
      (d) => d.sourceField === dep.sourceField && d.targetField === dep.targetField
    )

    if (existingIndex >= 0) {
      // 替换现有配置
      this.dependencies[existingIndex] = dep
    } else {
      // 添加新配置
      this.dependencies.push(dep)
    }
  }

  /**
   * 批量添加联动配置
   * @param deps 联动配置列表
   */
  addDependencies(deps: FieldDependency[]): void {
    deps.forEach((dep) => this.addDependency(dep))
  }

  /**
   * 移除联动配置
   * @param sourceField 源字段
   * @param targetField 目标字段
   */
  removeDependency(sourceField: string, targetField: string): void {
    this.dependencies = this.dependencies.filter(
      (d) => !(d.sourceField === sourceField && d.targetField === targetField)
    )
  }

  /**
   * 清空所有联动配置
   */
  clear(): void {
    this.dependencies = []
    this.callbacks.clear()
  }

  /**
   * 触发联动
   * @param sourceField 源字段名称
   * @param sourceValue 源字段值
   * @param allFormData 所有表单数据
   * @returns 联动结果 { [targetField]: { type, value } }
   */
  trigger(
    sourceField: string,
    sourceValue: any,
    allFormData: FormData
  ): Record<string, { type: string; value?: any }> {
    const results: Record<string, { type: string; value?: any }> = {}

    // 找到所有与源字段相关的联动配置
    const relatedDeps = this.dependencies.filter((dep) => dep.sourceField === sourceField)

    relatedDeps.forEach((dep) => {
      // 检查条件是否满足
      if (dep.condition(sourceValue, allFormData)) {
        let result: any = undefined

        // 执行联动动作
        switch (dep.type) {
          case 'show':
          case 'hide':
            result = dep.type === 'show'
            break

          case 'enable':
          case 'disable':
            result = dep.type !== 'disable'
            break

          case 'setValue':
            if (dep.action) {
              result = dep.action(
                allFormData[dep.targetField],
                sourceValue,
                allFormData
              )
            }
            break

          case 'setOptions':
            if (dep.action) {
              result = dep.action(
                allFormData[dep.targetField],
                sourceValue,
                allFormData
              )
            }
            break
        }

        results[dep.targetField] = {
          type: dep.type,
          value: result
        }

        // 触发回调
        this.emit(sourceField, dep.targetField, { type: dep.type, value: result })
      }
    })

    return results
  }

  /**
   * 注册字段变化回调
   * @param sourceField 源字段
   * @param callback 回调函数
   */
  on(sourceField: string, callback: (targetField: string, action: any) => void): void {
    if (!this.callbacks.has(sourceField)) {
      this.callbacks.set(sourceField, new Set())
    }
    this.callbacks.get(sourceField)!.add(callback)
  }

  /**
   * 取消注册回调
   * @param sourceField 源字段
   * @param callback 回调函数
   */
  off(sourceField: string, callback: (targetField: string, action: any) => void): void {
    const callbacks = this.callbacks.get(sourceField)
    if (callbacks) {
      callbacks.delete(callback)
    }
  }

  /**
   * 触发回调
   */
  private emit(sourceField: string, targetField: string, action: any): void {
    const callbacks = this.callbacks.get(sourceField)
    if (callbacks) {
      callbacks.forEach((cb) => cb(targetField, action))
    }
  }

  /**
   * 获取所有联动配置
   */
  getDependencies(): FieldDependency[] {
    return [...this.dependencies]
  }

  /**
   * 获取与指定字段相关的所有联动
   * @param fieldName 字段名称
   */
  getFieldDependencies(fieldName: string): {
    asSource: FieldDependency[]
    asTarget: FieldDependency[]
  } {
    return {
      asSource: this.dependencies.filter((dep) => dep.sourceField === fieldName),
      asTarget: this.dependencies.filter((dep) => dep.targetField === fieldName)
    }
  }
}

/**
 * 创建常用的联动条件函数
 */
export const DependencyConditions = {
  /**
   * 等于某个值
   */
  equals: (value: any) => (sourceValue: any) => sourceValue === value,

  /**
   * 不等于某个值
   */
  notEquals: (value: any) => (sourceValue: any) => sourceValue !== value,

  /**
   * 包含某个值（用于数组）
   */
  contains: (value: any) => (sourceValue: any) => {
    if (Array.isArray(sourceValue)) {
      return sourceValue.includes(value)
    }
    return sourceValue === value
  },

  /**
   * 不包含某个值
   */
  notContains: (value: any) => (sourceValue: any) => {
    if (Array.isArray(sourceValue)) {
      return !sourceValue.includes(value)
    }
    return sourceValue !== value
  },

  /**
   * 大于某个值
   */
  greaterThan: (value: any) => (sourceValue: any) => Number(sourceValue) > Number(value),

  /**
   * 小于某个值
   */
  lessThan: (value: any) => (sourceValue: any) => Number(sourceValue) < Number(value),

  /**
   * 在某个范围内
   */
  between: (min: number, max: number) => (sourceValue: any) => {
    const num = Number(sourceValue)
    return num >= min && num <= max
  },

  /**
   * 值为真
   */
  isTrue: () => (sourceValue: any) => Boolean(sourceValue),

  /**
   * 值为假
   */
  isFalse: () => (sourceValue: any) => !Boolean(sourceValue)
}

/**
 * 创建常用的联动动作函数
 */
export const DependencyActions = {
  /**
   * 设置为固定值
   */
  setValue: (value: any) => () => value,

  /**
   * 清空值
   */
  clearValue: () => () => undefined,

  /**
   * 根据源值设置目标值
   */
  copyValue: () => (_target: any, source: any) => source,

  /**
   * 动态加载选项
   */
  loadOptions: (optionsLoader: (sourceValue: any) => Array<{ label: string; value: any }>) => {
    return () => async (_target: any, source: any, allData: FormData) => {
      return await optionsLoader(source)
    }
  }
}

/**
 * 导出单例实例
 */
export const fieldDependencyManager = new FieldDependencyManager()
