import type { IProject } from '@/store/modules/project'
import type { ComponentSchema } from '@/lvgl-widgets/type'
import type {
  WidgetEventActionData,
  WidgetEventTargetData,
  WidgetEventTriggerData
} from '@/types/event'
import type { OptionType } from './type'

import { get, set } from 'lodash-es'
import { klona } from 'klona'
import { bfsWalk } from 'simple-mind-map/src/utils'

import LvglWidgets from '@/lvgl-widgets'
import { flagOptions, stateOptions } from '@/constants'

type SchemaActionDescriptor = {
  actionKey: string
  defaultValue: any
  label: string
  schemas: ComponentSchema[]
  groupKey?: string
  groupLabel?: string
  groupOrder?: number
}

type EventSettableSchema = ComponentSchema & {
  canUseEventSet?: boolean
  dependency?: (values: Record<string, any>) => ComponentSchema[] | ComponentSchema
  name?: string[]
}

type EventStyleSchema = ComponentSchema & {
  key: string
}

const pageLoadAnimationOptions = [
  { label: '无', value: 'none' },
  { label: '覆盖左侧', value: 'over_left' },
  { label: '覆盖右侧', value: 'over_right' },
  { label: '覆盖顶部', value: 'over_top' },
  { label: '覆盖底部', value: 'over_bottom' },
  { label: '左移', value: 'move_left' },
  { label: '右移', value: 'move_right' },
  { label: '上移', value: 'move_top' },
  { label: '下移', value: 'move_bottom' },
  { label: '淡入', value: 'fade_in' },
  { label: '淡开', value: 'fade_on' },
  { label: '淡出', value: 'fade_out' },
  { label: '退出左侧', value: 'out_left' },
  { label: '退出右侧', value: 'out_right' },
  { label: '退出顶部', value: 'out_top' },
  { label: '退出底部', value: 'out_bottom' }
]

const eventOption = (
  label: string,
  eventCode: string,
  extra: Omit<WidgetEventTriggerData, 'eventCode'> = {}
) =>
  ({
    label,
    value:
      extra.key || extra.direction ? `${eventCode}:${extra.key || extra.direction}` : eventCode,
    data: {
      eventCode,
      ...extra
    } satisfies WidgetEventTriggerData
  }) satisfies OptionType

const commonEventOptions = [
  eventOption('Clicked', 'LV_EVENT_CLICKED'),
  eventOption('Short Clicked', 'LV_EVENT_SHORT_CLICKED'),
  eventOption('Single Clicked', 'LV_EVENT_SINGLE_CLICKED'),
  eventOption('Double Clicked', 'LV_EVENT_DOUBLE_CLICKED'),
  eventOption('Triple Clicked', 'LV_EVENT_TRIPLE_CLICKED'),
  eventOption('Pressed', 'LV_EVENT_PRESSED'),
  eventOption('Pressing', 'LV_EVENT_PRESSING'),
  eventOption('Press Lost', 'LV_EVENT_PRESS_LOST'),
  eventOption('Long Pressed', 'LV_EVENT_LONG_PRESSED'),
  eventOption('Long Pressed Repeat', 'LV_EVENT_LONG_PRESSED_REPEAT'),
  eventOption('Released', 'LV_EVENT_RELEASED'),
  eventOption('Value Changed', 'LV_EVENT_VALUE_CHANGED'),
  eventOption('Scroll', 'LV_EVENT_SCROLL'),
  eventOption('Scroll Begin', 'LV_EVENT_SCROLL_BEGIN'),
  eventOption('Scroll End', 'LV_EVENT_SCROLL_END'),
  eventOption('Gesture Top', 'LV_EVENT_GESTURE', { direction: 'LV_DIR_TOP' }),
  eventOption('Gesture Bottom', 'LV_EVENT_GESTURE', { direction: 'LV_DIR_BOTTOM' }),
  eventOption('Gesture Left', 'LV_EVENT_GESTURE', { direction: 'LV_DIR_LEFT' }),
  eventOption('Gesture Right', 'LV_EVENT_GESTURE', { direction: 'LV_DIR_RIGHT' }),
  eventOption('Key', 'LV_EVENT_KEY'),
  eventOption('Key Up', 'LV_EVENT_KEY', { key: 'LV_KEY_UP' }),
  eventOption('Key Down', 'LV_EVENT_KEY', { key: 'LV_KEY_DOWN' }),
  eventOption('Key Right', 'LV_EVENT_KEY', { key: 'LV_KEY_RIGHT' }),
  eventOption('Key Left', 'LV_EVENT_KEY', { key: 'LV_KEY_LEFT' }),
  eventOption('Key Esc', 'LV_EVENT_KEY', { key: 'LV_KEY_ESC' }),
  eventOption('Key Del', 'LV_EVENT_KEY', { key: 'LV_KEY_DEL' }),
  eventOption('Key Backspace', 'LV_EVENT_KEY', { key: 'LV_KEY_BACKSPACE' }),
  eventOption('Key Enter', 'LV_EVENT_KEY', { key: 'LV_KEY_ENTER' }),
  eventOption('Key Next', 'LV_EVENT_KEY', { key: 'LV_KEY_NEXT' }),
  eventOption('Key Prev', 'LV_EVENT_KEY', { key: 'LV_KEY_PREV' }),
  eventOption('Key Home', 'LV_EVENT_KEY', { key: 'LV_KEY_HOME' }),
  eventOption('Key End', 'LV_EVENT_KEY', { key: 'LV_KEY_END' }),
  eventOption('Focused', 'LV_EVENT_FOCUSED'),
  eventOption('Defocused', 'LV_EVENT_DEFOCUSED'),
  eventOption('Leave', 'LV_EVENT_LEAVE'),
  eventOption('Hit Test', 'LV_EVENT_HIT_TEST'),
  eventOption('Insert', 'LV_EVENT_INSERT'),
  eventOption('Ready', 'LV_EVENT_READY'),
  eventOption('Cancel', 'LV_EVENT_CANCEL')
]

/**
 * 事件编辑统一样式配置
 * 仅在控件自身存在 config.styles 时启用
 */
const styleSchemas: EventStyleSchema[] = [
  {
    key: 'background.color',
    label: '背景颜色',
    field: 'background.color',
    valueType: 'color',
    defaultValue: '#000000ff'
  },
  {
    key: 'background.alpha',
    label: '背景透明度',
    field: 'background.alpha',
    valueType: 'color',
    defaultValue: '#000000ff'
  },
  {
    key: 'background.gradient.direction',
    label: '背景渐变方向',
    field: 'background.alpha',
    valueType: 'select',
    defaultValue: 'none',
    componentProps: {
      options: [
        { label: 'None', value: 'none' },
        { label: 'Horizontal', value: 'horizontal' },
        { label: 'Vertical', value: 'vertical' }
      ]
    }
  },
  {
    key: 'background.gradient.color',
    label: '背景渐变颜色',
    field: 'background.gradient.color',
    valueType: 'color',
    defaultValue: '#000000ff'
  },
  {
    key: 'background.gradient.alpha',
    label: '背景渐变透明度',
    field: 'background.gradient.alpha',
    valueType: 'number',
    defaultValue: 255,
    componentProps: {
      min: 0,
      max: 255
    }
  },
  {
    key: 'background.gradient.start',
    label: '背景渐变起始点',
    field: 'background.gradient.start',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 255
    }
  },
  {
    key: 'background.gradient.end',
    label: '背景渐变结束点',
    field: 'background.gradient.end',
    valueType: 'number',
    defaultValue: 255,
    componentProps: {
      min: 0,
      max: 255
    }
  },
  {
    key: 'background.image.imgId',
    label: '背景图',
    field: 'background.image.imgId',
    valueType: 'image'
  },
  {
    key: 'background.image.recolor',
    label: '背景图片遮罩',
    field: 'background.image.recolor',
    valueType: 'color',
    defaultValue: '#ffffff00'
  },
  {
    key: 'background.image.alpha',
    label: '背景透明度',
    field: 'background.image.alpha',
    valueType: 'number',
    defaultValue: 255,
    componentProps: {
      min: 0,
      max: 255
    }
  },
  {
    key: 'text.color',
    label: '字体颜色',
    field: 'text.color',
    valueType: 'color',
    defaultValue: '#000000ff'
  },
  {
    key: 'text.alpha',
    label: '字体透明度',
    field: 'text.alpha',
    valueType: 'number',
    defaultValue: 255,
    componentProps: {
      min: 0,
      max: 255
    }
  },
  {
    key: 'text.family',
    label: '字体',
    field: 'text.family',
    valueType: 'family',
    defaultValue: 'montserratMedium'
  },
  {
    key: 'text.align',
    label: '字体对齐',
    field: 'text.align',
    valueType: 'select',
    defaultValue: 'left',
    componentProps: {
      options: [
        { label: '左对齐', value: 'left' },
        { label: '居中对齐', value: 'center' },
        { label: '右对齐', value: 'right' }
      ]
    }
  },
  {
    key: 'text.decoration',
    label: '字体装饰',
    field: 'text.decoration',
    valueType: 'select',
    defaultValue: 'none',
    componentProps: {
      options: [
        { label: 'None', value: 'none' },
        { label: 'Underline', value: 'underline' },
        { label: 'Strikethrough', value: 'line-through' },
        { label: 'Underline&Strikethrough', value: 'underline line-through' }
      ]
    }
  },
  {
    key: 'spacer.letterSpacing',
    label: '字间距',
    field: 'spacer.letterSpacing',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -10000,
      max: 10000
    }
  },
  {
    key: 'spacer.lineHeight',
    label: '行间距',
    field: 'spacer.lineHeight',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -10000,
      max: 10000
    }
  },
  {
    key: 'border.color',
    label: '边框颜色',
    field: 'border.color',
    valueType: 'color',
    defaultValue: '#000000ff'
  },
  {
    key: 'border.alpha',
    label: '边框透明度',
    field: 'border.alpha',
    valueType: 'number',
    defaultValue: 255,
    componentProps: {
      min: 0,
      max: 255
    }
  },
  {
    key: 'border.width',
    label: '边框宽度',
    field: 'border.width',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'border.radius',
    label: '边框圆角',
    field: 'border.radius',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'border.side',
    label: '边框选择',
    field: 'border.side',
    valueType: 'checkbox',
    defaultValue: ['all'],
    componentProps: {
      options: [
        { label: '所有边框', value: 'all' },
        { label: '左边框', value: 'left' },
        { label: '上边框', value: 'top' },
        { label: '下边框', value: 'bottom' },
        { label: '右边框', value: 'right' }
      ]
    }
  },
  {
    key: 'outline.color',
    label: '轮廓颜色',
    field: 'outline.color',
    valueType: 'color',
    defaultValue: '#000000ff'
  },
  {
    key: 'outline.alpha',
    label: '轮廓透明度',
    field: 'outline.alpha',
    valueType: 'number',
    defaultValue: 255,
    componentProps: {
      min: 0,
      max: 255
    }
  },
  {
    key: 'outline.width',
    label: '轮廓宽度',
    field: 'outline.width',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'outline.pad',
    label: '轮廓间距',
    field: 'outline.pad',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'padding.top',
    label: '内上边距',
    field: 'padding.top',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'padding.bottom',
    label: '内下边距',
    field: 'padding.bottom',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'padding.left',
    label: '内左边距',
    field: 'padding.left',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'padding.right',
    label: '内右边距',
    field: 'padding.right',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'padding.row',
    label: '内行边距',
    field: 'padding.row',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'padding.column',
    label: '内列边距',
    field: 'padding.column',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'margin.top',
    label: '外上边距',
    field: 'margin.top',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'margin.bottom',
    label: '外下边距',
    field: 'margin.bottom',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'margin.left',
    label: '外左边距',
    field: 'margin.left',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'margin.right',
    label: '外右边距',
    field: 'margin.right',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'shadow.color',
    label: '阴影颜色',
    field: 'shadow.color',
    valueType: 'color',
    defaultValue: '#000000ff'
  },
  {
    key: 'shadow.alpha',
    label: '阴影透明度',
    field: 'shadow.alpha',
    valueType: 'number',
    defaultValue: 255,
    componentProps: {
      min: 0,
      max: 255
    }
  },
  {
    key: 'shadow.offsetX',
    label: '阴影偏移X',
    field: 'shadow.offsetX',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -10000,
      max: 10000
    }
  },
  {
    key: 'shadow.offsetY',
    label: '阴影偏移Y',
    field: 'shadow.offsetY',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -10000,
      max: 10000
    }
  },
  {
    key: 'shadow.spread',
    label: '阴影扩散',
    field: 'shadow.spread',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'shadow.width',
    label: '阴影宽度',
    field: 'shadow.width',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'transform.width',
    label: '宽变换',
    field: 'transform.width',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -10000,
      max: 10000
    }
  },
  {
    key: 'transform.height',
    label: '高变换',
    field: 'transform.height',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -10000,
      max: 10000
    }
  },
  {
    key: 'transform.translateX',
    label: 'X变换',
    field: 'transform.translateX',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -10000,
      max: 10000
    }
  },
  {
    key: 'transform.translateY',
    label: 'Y变换',
    field: 'transform.translateY',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -10000,
      max: 10000
    }
  },
  {
    key: 'transform.originX',
    label: '中心X',
    field: 'transform.originX',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -10000,
      max: 10000
    }
  },
  {
    key: 'transform.originY',
    label: '中心Y',
    field: 'transform.originY',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -10000,
      max: 10000
    }
  },
  {
    key: 'transform.rotate',
    label: '旋转角度',
    field: 'transform.rotate',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: -3600,
      max: 3600
    }
  },
  {
    key: 'transform.scale',
    label: '缩放',
    field: 'transform.scale',
    valueType: 'number',
    defaultValue: 256,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'imageStyle.alpha',
    label: '图片透明度',
    field: 'imageStyle.alpha',
    valueType: 'number',
    defaultValue: 255,
    componentProps: {
      min: 0,
      max: 255
    }
  },
  {
    key: 'imageStyle.recolor',
    label: '图片遮罩',
    field: 'imageStyle.recolor',
    valueType: 'color',
    defaultValue: '#ffffff00'
  },
  {
    key: 'line.color',
    label: '直线颜色',
    field: 'line.color',
    valueType: 'color',
    defaultValue: '#000000ff'
  },
  {
    key: 'line.width',
    label: '直线宽度',
    field: 'line.width',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'line.radius',
    label: '直线圆角',
    field: 'line.radius',
    valueType: 'switch',
    defaultValue: false
  },
  {
    key: 'line.dashWidth',
    label: '虚线宽度',
    field: 'line.dashWidth',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'line.dashGap',
    label: '虚线间隔',
    field: 'line.dashGap',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'curve.color',
    label: '曲线颜色',
    field: 'curve.color',
    valueType: 'color',
    defaultValue: '#000000ff'
  },
  {
    key: 'curve.image',
    label: '曲线图片',
    field: 'curve.image',
    valueType: 'image',
    defaultValue: ''
  },
  {
    key: 'curve.width',
    label: '曲线宽度',
    field: 'curve.width',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'curve.radius',
    label: '曲线圆角',
    field: 'curve.radius',
    valueType: 'switch',
    defaultValue: false
  },
  {
    key: 'other.length',
    label: '长度',
    field: 'other.length',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 10000
    }
  },
  {
    key: 'animation.time',
    label: '动画时间',
    field: 'animation.time',
    valueType: 'number',
    defaultValue: 0,
    componentProps: {
      min: 0,
      max: 100000
    }
  }
]

export const widgetEventOptions = [...commonEventOptions]

export const pageEventOptions = [
  ...commonEventOptions,
  eventOption('Load Start', 'LV_EVENT_SCREEN_LOAD_START'),
  eventOption('Loaded', 'LV_EVENT_SCREEN_LOADED'),
  eventOption('Unload Start', 'LV_EVENT_SCREEN_UNLOAD_START'),
  eventOption('Unloaded', 'LV_EVENT_SCREEN_UNLOADED')
]

function getSchemaLabel(schema: ComponentSchema): string {
  if (schema.label) return schema.label

  const prefix = typeof schema.slots === 'object' ? schema.slots?.prefix : undefined
  if (typeof prefix === 'string' && prefix.trim()) return prefix

  return schema.field?.split('.').pop() || '动作'
}

function isSchemaActionable(schema?: ComponentSchema): boolean {
  if (!schema?.field) return false
  if (schema.valueType === 'dependency') return false
  if (schema.valueType === 'part') return false
  if (schema.valueType === 'code') return false
  if (!schema.valueType) return false
  if (schema.field === 'name') return false
  if (schema.field === 'props.head_code') return false
  if (schema.field === 'props.feature_code') return false
  return true
}

function createDefaultValue(schema: ComponentSchema): any {
  if ((schema as any).defaultValue !== undefined) return klona((schema as any).defaultValue)

  switch (schema.valueType) {
    case 'number':
    case 'slider':
      return 0
    case 'switch':
      return false
    case 'checkbox':
      return []
    case 'select':
    case 'text':
    case 'textarea':
    case 'image':
    case 'file':
    case 'symbol':
    case 'date':
    case 'time':
    case 'font':
      return ''
    case 'color':
      return '#000000ff'
    case 'group':
      return {}
    case 'animation':
      return {
        animation: undefined,
        before: undefined,
        after: undefined
      }
    case 'rotate':
      return {
        x: 0,
        y: 0,
        angle: 0
      }
    default:
      return {}
  }
}

function createSchemaDefaultValue(defaultRoot: any, schema: ComponentSchema) {
  if (schema.field) {
    const currentValue = get(defaultRoot, schema.field)
    if (currentValue !== undefined) return klona(currentValue)
  }

  if (schema.valueType === 'group') {
    return createGroupDefaultValue(defaultRoot, schema)
  }

  return createDefaultValue(schema)
}

function splitFieldPath(field?: string): string[] {
  return String(field || '')
    .split('.')
    .map((item) => item.trim())
    .filter(Boolean)
}

function joinFieldPath(paths: string[]): string {
  return paths.filter(Boolean).join('.')
}

function getCommonFieldPrefix(fields: string[]): string[] {
  const pathList = fields.map((item) => splitFieldPath(item)).filter((item) => item.length)
  if (!pathList.length) return []

  const [firstPath, ...restPaths] = pathList
  let length = firstPath.length

  restPaths.forEach((paths) => {
    length = Math.min(length, paths.length)
    for (let i = 0; i < length; i += 1) {
      if (firstPath[i] !== paths[i]) {
        length = i
        break
      }
    }
  })

  return firstPath.slice(0, length)
}

function collectSchemaFields(schema?: ComponentSchema): string[] {
  if (!schema) return []

  const fields: string[] = []
  if (schema.field) fields.push(schema.field)
  ;(schema.children || []).forEach((child) => {
    fields.push(...collectSchemaFields(child))
  })

  return fields
}

function getSchemaSourceBase(schema: ComponentSchema): string[] {
  if (schema.field) return splitFieldPath(schema.field)
  return getCommonFieldPrefix(collectSchemaFields(schema))
}

function getRelativeFieldPath(field: string | undefined, sourceBase: string[]): string[] {
  const fieldPaths = splitFieldPath(field)
  if (!sourceBase.length) return fieldPaths

  const isSourceBaseMatched = sourceBase.every((item, index) => fieldPaths[index] === item)
  return isSourceBaseMatched ? fieldPaths.slice(sourceBase.length) : fieldPaths
}

function getActionField(
  field: string | undefined,
  targetField: string,
  sourceBase: string[]
): string {
  return joinFieldPath([targetField, ...getRelativeFieldPath(field, sourceBase)]) || targetField
}

function createGroupDefaultValue(defaultRoot: any, schema: ComponentSchema): Record<string, any> {
  const result: Record<string, any> = {}
  const sourceBase = getSchemaSourceBase(schema)

  const appendValue = (item?: EventSettableSchema) => {
    if (!item) return

    if (item.valueType === 'dependency' && typeof item.dependency === 'function') {
      const dependencySchemas = item.dependency(buildDependencyValues(item.name, defaultRoot))
      const schemaList = Array.isArray(dependencySchemas) ? dependencySchemas : [dependencySchemas]
      schemaList.forEach((schemaItem) => appendValue(schemaItem as EventSettableSchema))
      return
    }

    if (item.valueType === 'group') {
      const groupValue = createSchemaDefaultValue(defaultRoot, item)
      const groupPath = item.field ? getRelativeFieldPath(item.field, sourceBase) : []

      if (!groupPath.length) {
        Object.assign(result, groupValue)
        return
      }

      set(result, joinFieldPath(groupPath), groupValue)
      return
    }

    if (!item.field) return

    const nextValue = createSchemaDefaultValue(defaultRoot, item)
    const targetPath = getRelativeFieldPath(item.field, sourceBase)

    if (!targetPath.length) return
    set(result, joinFieldPath(targetPath), nextValue)
  }

  ;(schema.children || []).forEach((item) => appendValue(item as EventSettableSchema))
  return result
}

function cloneActionSchema(schema: ComponentSchema, targetField = 'payload'): ComponentSchema {
  const cloned = klona(schema)
  cloned.field = targetField
  if (cloned.componentProps?.defaultCollapsed) {
    // 关闭默认折叠
    cloned.componentProps.defaultCollapsed = false
  }
  return cloned
}

function buildDependencyValues(names: string[] = [], defaultRoot: any) {
  return names.reduce<Record<string, any>>((result, key) => {
    result[key] = get(defaultRoot, key)
    return result
  }, {})
}

function cloneEventActionSchema(
  schema: ComponentSchema,
  targetField = 'payload',
  sourceBase = getSchemaSourceBase(schema)
): ComponentSchema {
  const rewriteSchema = (item: ComponentSchema): ComponentSchema => {
    const cloned = klona(item)

    if (cloned.field) {
      cloned.field = getActionField(cloned.field, targetField, sourceBase)
    }

    if (cloned.valueType === 'dependency') {
      const dependencySchema = cloned as EventSettableSchema
      if (Array.isArray(dependencySchema.name)) {
        dependencySchema.name = dependencySchema.name.map((name) =>
          getActionField(name, targetField, sourceBase)
        )
      }
    }

    if (cloned.children?.length) {
      cloned.children = cloned.children.map((child) => rewriteSchema(child))
    }

    if (cloned.componentProps?.defaultCollapsed) {
      cloned.componentProps.defaultCollapsed = false
    }

    return cloned
  }

  return rewriteSchema(schema)
}

function flattenEventActionSchemas(
  items: EventSettableSchema[] = [],
  defaultRoot: any,
  pathTokens: string[] = []
): SchemaActionDescriptor[] {
  const result: SchemaActionDescriptor[] = []

  items.forEach((item, index) => {
    if (!item) return

    const nextPathTokens = [
      ...pathTokens,
      `${item.field || getSchemaLabel(item) || 'item'}_${index}`
    ]

    if (item.valueType === 'group') {
      if (item.canUseEventSet === true) {
        result.push({
          actionKey: item.field || `group.${nextPathTokens.join('.')}`,
          label: getSchemaLabel(item),
          groupKey: 'property',
          groupLabel: 'Property',
          groupOrder: 1,
          schemas: [cloneEventActionSchema(item)],
          defaultValue: createSchemaDefaultValue(defaultRoot, item)
        })
      }

      result.push(
        ...flattenEventActionSchemas(
          (item.children || []) as EventSettableSchema[],
          defaultRoot,
          nextPathTokens
        )
      )
      return
    }

    if (item.valueType === 'dependency' && typeof item.dependency === 'function') {
      const dependencySchemas = item.dependency(buildDependencyValues(item.name, defaultRoot))
      const schemaList = Array.isArray(dependencySchemas) ? dependencySchemas : [dependencySchemas]
      result.push(
        ...flattenEventActionSchemas(
          schemaList as EventSettableSchema[],
          defaultRoot,
          nextPathTokens
        )
      )
      return
    }

    if (item.canUseEventSet !== true) return
    if (!isSchemaActionable(item)) return

    result.push({
      actionKey: item.field!,
      label: getSchemaLabel(item),
      groupKey: 'property',
      groupLabel: 'Property',
      groupOrder: 1,
      schemas: [cloneEventActionSchema(item)],
      defaultValue: createSchemaDefaultValue(defaultRoot, item)
    })
  })

  return result
}

function createStyleStateSchema(): ComponentSchema {
  return {
    label: '状态',
    field: 'payload.state',
    labelWidth: '120px',
    valueType: 'select',
    defaultValue: 'LV_STATE_DEFAULT',
    componentProps: {
      options: stateOptions,
      clearable: true,
      placeholder: '请选择状态'
    }
  }
}

function getStyleActionDescriptors(targetData?: WidgetEventTargetData): SchemaActionDescriptor[] {
  const model = getTargetModel(targetData)
  const styleDefaults = model?.defaultSchema?.styles?.[0] || {}
  const widgetStyleSchemas = model?.config?.styles || []

  if (!widgetStyleSchemas.length) return []

  return styleSchemas.map((item) => {
    const defaultValue =
      get(styleDefaults, item.field!) !== undefined
        ? createSchemaDefaultValue(styleDefaults, item)
        : klona(item.defaultValue)

    return {
      actionKey: `style.${item.key}`,
      label: item.label || item.key || '样式',
      groupKey: 'style',
      groupLabel: '样式',
      groupOrder: 2,
      schemas: [createStyleStateSchema(), cloneActionSchema(item, 'payload.style')],
      defaultValue: {
        state: '',
        style: defaultValue
      }
    }
  })
}

function getTargetModel(targetData?: WidgetEventTargetData) {
  if (!targetData) return
  if (targetData.kind === 'page' || targetData.kind === 'load_page') return LvglWidgets.page
  if (!targetData.targetType) return
  return LvglWidgets[targetData.targetType]
}

function getSchemaActionDescriptors(targetData?: WidgetEventTargetData): SchemaActionDescriptor[] {
  const model = getTargetModel(targetData)
  if (!model) return []

  return [
    ...flattenEventActionSchemas(
      (model.config.props || []) as EventSettableSchema[],
      model.defaultSchema
    ),
    ...flattenEventActionSchemas(
      (model.config.coreProps || []) as EventSettableSchema[],
      model.defaultSchema
    ),
    ...getStyleActionDescriptors(targetData)
  ]
}

function getLoadPageActionDescriptor(
  project?: IProject,
  currentPageId?: string
): SchemaActionDescriptor {
  const pageOptions =
    project?.screens.flatMap((screen) =>
      screen.pages
        .filter((page) => page.id !== currentPageId)
        .map((page) => ({
          label: `[${screen.name}] ${page.name}`,
          value: page.id
        }))
    ) || []

  return {
    actionKey: 'builtin.load_page',
    label: '加载页面',
    groupKey: 'builtin',
    groupLabel: '动作',
    groupOrder: 1,
    defaultValue: {
      pageId: pageOptions[0]?.value || '',
      animationType: 'none',
      duration: 0,
      delay: 0,
      autoDeletePrevious: false,
      cleanupCurrent: false
    },
    schemas: [
      {
        label: '目标页面',
        field: 'payload.pageId',
        labelWidth: '120px',
        valueType: 'select',
        componentProps: {
          options: pageOptions
        }
      },
      {
        label: '动画类型',
        field: 'payload.animationType',
        labelWidth: '120px',
        valueType: 'select',
        componentProps: {
          options: pageLoadAnimationOptions
        }
      },
      {
        label: '动画时长(ms)',
        field: 'payload.duration',
        labelWidth: '120px',
        valueType: 'number',
        componentProps: {
          min: 0
        }
      },
      {
        label: '动画延时(ms)',
        field: 'payload.delay',
        labelWidth: '120px',
        valueType: 'number',
        componentProps: {
          min: 0
        }
      },
      {
        label: '自动删除旧页面',
        field: 'payload.autoDeletePrevious',
        labelWidth: '120px',
        valueType: 'switch'
      },
      {
        label: '清理当前页面',
        field: 'payload.cleanupCurrent',
        labelWidth: '120px',
        valueType: 'switch'
      }
    ]
  }
}

function getLanguageSwitchActionDescriptor(project?: IProject): SchemaActionDescriptor {
  const languageOptions =
    project?.languages.map((item) => ({
      label: item.key,
      value: item.key
    })) || []

  return {
    actionKey: 'builtin.language_switch',
    label: '语言切换',
    groupKey: 'builtin',
    groupLabel: '动作',
    groupOrder: 1,
    defaultValue: {
      languageKey: languageOptions[0]?.value || '',
      refreshPage: true
    },
    schemas: [
      {
        label: '语言',
        field: 'payload.languageKey',
        labelWidth: '120px',
        valueType: 'select',
        componentProps: {
          options: languageOptions
        }
      },
      {
        label: '刷新页面',
        field: 'payload.refreshPage',
        labelWidth: '120px',
        valueType: 'switch'
      }
    ]
  }
}

function getThemeSwitchActionDescriptor(project?: IProject): SchemaActionDescriptor {
  const themeOptions =
    project?.themes.map((item) => ({
      label: item.key,
      value: item.key
    })) || []

  const preferredTheme =
    themeOptions.find((item) => item.value !== project?.currentTheme)?.value ||
    themeOptions[0]?.value ||
    ''

  const isDualScreen = project?.meta?.screenType === 'double'

  return {
    actionKey: 'builtin.theme_switch',
    label: '主题切换',
    groupKey: 'builtin',
    groupLabel: '动作',
    groupOrder: 1,
    defaultValue: {
      screen1Theme: preferredTheme,
      ...(isDualScreen ? { screen2Theme: preferredTheme } : {})
    },
    schemas: [
      {
        label: '屏幕1主题',
        field: 'payload.screen1Theme',
        labelWidth: '120px',
        valueType: 'select',
        componentProps: {
          options: themeOptions
        }
      },
      ...(isDualScreen
        ? [
            {
              label: '屏幕2主题',
              field: 'payload.screen2Theme',
              labelWidth: '120px',
              valueType: 'select',
              componentProps: {
                options: themeOptions
              }
            } satisfies ComponentSchema
          ]
        : [])
    ]
  }
}

function getBuiltinActionDescriptors(
  targetData?: WidgetEventTargetData,
  project?: IProject,
  currentPageId?: string
) {
  if (!targetData) return []

  switch (targetData.kind) {
    case 'load_page':
      return [getLoadPageActionDescriptor(project, currentPageId)]
    case 'language_switch':
      return [getLanguageSwitchActionDescriptor(project)]
    case 'theme_switch':
      return [getThemeSwitchActionDescriptor(project)]
    case 'custom_code':
      return []
    default:
      return getSchemaActionDescriptors(targetData)
  }
}

export function isBuiltinTarget(targetData?: WidgetEventTargetData) {
  return (
    targetData?.kind === 'custom_code' ||
    targetData?.kind === 'load_page' ||
    targetData?.kind === 'language_switch' ||
    targetData?.kind === 'theme_switch'
  )
}

export function getBuiltinActionData(
  targetData?: WidgetEventTargetData
): WidgetEventActionData | null {
  if (!targetData) return null

  switch (targetData.kind) {
    case 'load_page':
      return { actionKey: 'builtin.load_page' }
    case 'language_switch':
      return { actionKey: 'builtin.language_switch' }
    case 'theme_switch':
      return { actionKey: 'builtin.theme_switch' }
    default:
      return null
  }
}

export function getEventOptions(widgetType?: string) {
  return widgetType === 'page' ? pageEventOptions : widgetEventOptions
}

export function getTargetOptions(project?: IProject): OptionType[] {
  const options: OptionType[] = [
    {
      label: '加载页面',
      value: 'builtin:load_page',
      data: {
        kind: 'load_page'
      } satisfies WidgetEventTargetData
    },
    {
      label: '自定义代码',
      value: 'builtin:custom_code',
      data: {
        kind: 'custom_code'
      } satisfies WidgetEventTargetData
    },
    {
      label: '语言切换',
      value: 'builtin:language_switch',
      data: {
        kind: 'language_switch'
      } satisfies WidgetEventTargetData
    },
    {
      label: '主题切换',
      value: 'builtin:theme_switch',
      data: {
        kind: 'theme_switch'
      } satisfies WidgetEventTargetData
    }
  ]

  project?.screens.forEach((screen) => {
    screen.pages.forEach((page) => {
      options.push({
        label: `[${screen.name}] ${page.name}`,
        value: `page:${page.id}`,
        data: {
          kind: 'page',
          pageId: page.id,
          screenId: screen.id,
          targetId: page.id,
          targetType: 'page'
        } satisfies WidgetEventTargetData
      })

      bfsWalk(page, (child) => {
        if (child.id === page.id) return
        if (!child.id) return

        options.push({
          label: `[${screen.name}] [${page.name}] ${child.name}`,
          value: `${child.id}`,
          data: {
            kind: 'widget',
            pageId: page.id,
            screenId: screen.id,
            targetId: child.id,
            targetType: child.type
          } satisfies WidgetEventTargetData
        })
      })
    })
  })

  return options
}

export function getActionOptions(
  targetData?: WidgetEventTargetData,
  project?: IProject,
  currentPageId?: string
): OptionType[] {
  const descriptors = getBuiltinActionDescriptors(targetData, project, currentPageId)

  return descriptors.map((item) => ({
    label: item.label,
    value: item.actionKey,
    groupKey: item.groupKey,
    groupLabel: item.groupLabel,
    groupOrder: item.groupOrder,
    data: {
      actionKey: item.actionKey
    } satisfies WidgetEventActionData,
    defaultValue: klona(item.defaultValue)
  }))
}

export function resolveActionDescriptor(
  targetData?: WidgetEventTargetData,
  actionData?: WidgetEventActionData,
  project?: IProject,
  currentPageId?: string
) {
  if (!targetData || !actionData?.actionKey) return

  return getBuiltinActionDescriptors(targetData, project, currentPageId).find(
    (item) => item.actionKey === actionData.actionKey
  )
}

export const optionMap = {
  visible: [
    { label: '显示', value: true },
    { label: '隐藏', value: false }
  ],
  flags: flagOptions,
  states: [{ label: 'Default', value: 'LV_STATE_DEFAULT' }, ...stateOptions]
}
