import type { VariableBinding } from '@/types/variables'
import type { Variable, VariableGroup } from '@/types/variables'
import type { BaseWidget } from '@/types/baseWidget'

/**
 * 判断属性值是否绑定了变量
 */
export function isVariableBound(value: any): value is VariableBinding {
  return typeof value === 'object' && 'varId' in value
}

/**
 * 获取属性的实际显示值
 * 如果绑定了变量，返回变量的当前值；否则返回原值
 */
export function getPropertyDisplayValue(propValue: any, allVariables: VariableGroup[]): any {
  if (!isVariableBound(propValue)) {
    return propValue
  }

  const variable = findVariableById(propValue.varId, allVariables)
  return resolveBoundValue(propValue, variable?.value)
}

/**
 * 绑定变量到属性
 */
export function bindVariableToProperty(
  propValue: any,
  varId: string,
  source: 'page' | 'global',
  enumMap?: Record<number | string, string>
): VariableBinding {
  return {
    varId,
    originValue: propValue,
    source,
    enumMap
  }
}

/**
 * 解绑属性变量，恢复原始值
 */
export function unbindPropertyVariable(boundValue: VariableBinding): any {
  return boundValue.originValue
}

/**
 * 根据ID查找变量
 */
export function findVariableById(varId: string, allVariables: VariableGroup[]): Variable | null {
  for (const group of allVariables) {
    const found = group.variables.find((v) => v.id === varId)
    if (found) return found
  }
  return null
}

/**
 * 解析绑定变量的最终值
 * 变量值优先；当变量值为 null/undefined 时回退到原始值。
 * 枚举变量存储为 key，这里还原为控件实际使用的 value。
 */
export function resolveBoundValue(boundValue: VariableBinding, variableValue?: any): any {
  const rawValue = variableValue ?? boundValue.originValue
  if (boundValue.enumMap && rawValue !== null && rawValue !== undefined) {
    const enumValue = boundValue.enumMap[rawValue]
    if (enumValue !== undefined) {
      return enumValue
    }
  }
  return rawValue
}

/**
 * 递归解析对象中的变量绑定值
 */
export function resolveVariableBoundValue(value: any, allVariables: VariableGroup[]): any {
  if (isVariableBound(value)) {
    const variable = findVariableById(value.varId, allVariables)
    return resolveBoundValue(value, variable?.value)
  }

  if (Array.isArray(value)) {
    return value.map((item) => resolveVariableBoundValue(item, allVariables))
  }

  if (value && typeof value === 'object') {
    const result = {}
    Object.keys(value).forEach((key) => {
      result[key] = resolveVariableBoundValue(value[key], allVariables)
    })
    return result
  }

  return value
}

/**
 * 获取所有变量（全局 + 当前页面）
 */
export function getAllVariables(
  projectVariables: VariableGroup[],
  pageVariables?: Variable[]
): VariableGroup[] {
  const allVars = [...projectVariables]
  if (pageVariables && pageVariables.length > 0) {
    allVars.push({
      id: 'page-vars',
      name: '页面变量',
      variables: pageVariables
    })
  }
  return allVars
}

/**
 * 查找使用某个变量的所有控件属性
 */
export function findVariableUsages(
  varId: string,
  widgets: BaseWidget[]
): Array<{ widgetId: string; widgetName: string; fieldPath: string }> {
  const usages: Array<{ widgetId: string; widgetName: string; fieldPath: string }> = []

  function traverse(widget: BaseWidget, parentPath: string = '') {
    const widgetPath = parentPath ? `${parentPath}.${widget.name}` : widget.name

    if (widget.props) {
      for (const [key, value] of Object.entries(widget.props)) {
        const fieldPath = `${widgetPath}.props.${key}`

        if (isVariableBound(value) && value.varId === varId) {
          usages.push({
            widgetId: widget.id,
            widgetName: widget.name,
            fieldPath
          })
        }
      }
    }

    if (widget.children) {
      widget.children.forEach((child) => traverse(child, widgetPath))
    }
  }

  widgets.forEach((widget) => traverse(widget))
  return usages
}

/**
 * 自动解绑指定变量的所有引用
 */
export function unbindAllVariableReferences(varId: string, widgets: BaseWidget[]): void {
  function traverse(widget: BaseWidget) {
    if (widget.props) {
      for (const [key, value] of Object.entries(widget.props)) {
        if (isVariableBound(value) && value.varId === varId) {
          widget.props[key] = value.originValue
        }
      }
    }

    if (widget.children) {
      widget.children.forEach((child) => traverse(child))
    }
  }

  widgets.forEach((widget) => traverse(widget))
}

/**
 * 获取嵌套对象属性的值
 */
export function getNestedValue(obj: any, path: string): any {
  const keys = path.split('.')
  let result = obj

  for (const key of keys) {
    if (result === undefined || result === null) {
      return undefined
    }
    result = result[key]
  }

  return result
}

/**
 * 设置嵌套对象属性的值
 */
export function setNestedValue(obj: any, path: string, value: any): void {
  const keys = path.split('.')
  let current = obj

  for (let i = 0; i < keys.length - 1; i++) {
    const key = keys[i]
    if (!(key in current)) {
      current[key] = {}
    }
    current = current[key]
  }

  current[keys[keys.length - 1]] = value
}
