import type { ComponentSchema, IComponentModelConfig } from './type'
import type { VariableType } from '@/types/variables'

type VariableConfig = {
  type: VariableType
  enumMap?: Record<number | string, string>
}

type WidgetVariableConfigMap = Record<string, Record<string, VariableConfig>>

const longModeEnumMap = { 0: 'wrap', 1: 'dot', 2: 'scroll', 3: 'circular', 4: 'clip' }
const dropdownDirectionEnumMap = { 1: 'left', 2: 'top', 4: 'bottom', 8: 'right' }
const barModeEnumMap = { 0: 'normal', 1: 'symmetrical', 2: 'range' }
const tabviewPositionEnumMap = { 1: 'left', 2: 'top', 4: 'bottom', 8: 'right' }
const arcModeEnumMap = { 0: 'normal', 1: 'symmetrical', 2: 'reverse' }
const scrollbarEnumMap = { 0: 'off', 1: 'on', 2: 'active', 3: 'auto' }
const scaleModeEnumMap = {
  0: 'horizontal_top',
  1: 'horizontal_bottom',
  2: 'vertical_left',
  4: 'vertical_right'
}
const rollerModeEnumMap = { 0: 'normal', 1: 'infinite' }
const keyboardModeEnumMap = { 0: 'lower', 1: 'upper', 2: 'special', 3: 'number' }
const videoSourceEnumMap = { 0: 'file', 1: 'signal' }
const barcodeDirectionEnumMap = { 3: 'horizontal', 12: 'vertical' }
const meterModeEnumMap = { 8: 'round_inner', 16: 'round_outer' }

const commonPositionSizeFields: Record<string, VariableConfig> = {
  'props.x': { type: 'int32_t' },
  'props.y': { type: 'int32_t' },
  'props.width': { type: 'int32_t' },
  'props.height': { type: 'int32_t' }
}

const commonWidgetVariableConfig: Record<string, VariableConfig> = {
  ...commonPositionSizeFields,
  'props.scrollbar': { type: 'enum', enumMap: scrollbarEnumMap }
}

const widgetVariableConfigMap: WidgetVariableConfigMap = {
  lv_button: {
    ...commonPositionSizeFields,
    'props.text': { type: 'char' },
    'props.longMode': { type: 'enum', enumMap: longModeEnumMap }
  },
  lv_imagebutton: {
    ...commonPositionSizeFields,
    'props.text': { type: 'char' }
  },
  lv_label: {
    ...commonPositionSizeFields,
    'props.text': { type: 'char' },
    'props.longMode': { type: 'enum', enumMap: longModeEnumMap },
    'props.lightStart': { type: 'uint32_t' },
    'props.lightEnd': { type: 'uint32_t' }
  },
  lv_span: {
    ...commonPositionSizeFields,
    'props.mode': { type: 'enum', enumMap: { 0: 'fixed', 1: 'expand', 2: 'break' } }
  },
  lv_textarea: {
    ...commonPositionSizeFields,
    'props.text': { type: 'char' },
    'props.placeholder': { type: 'char' },
    'props.maxLength': { type: 'uint32_t' },
    'props.allowString': { type: 'char' },
    'props.passwordReplaceText': { type: 'char' },
    'props.passwordMode': { type: 'bool' },
    'props.nowrap': { type: 'bool' }
  },
  lv_dropdown: {
    ...commonPositionSizeFields,
    'props.direction': { type: 'enum', enumMap: dropdownDirectionEnumMap }
  },
  lv_checkbox: {
    'props.x': { type: 'int32_t' },
    'props.y': { type: 'int32_t' },
    'props.text': { type: 'char' }
  },
  lv_bar: {
    ...commonPositionSizeFields,
    'props.min': { type: 'int32_t' },
    'props.max': { type: 'int32_t' },
    'props.value': { type: 'int32_t' },
    'props.animationTime': { type: 'uint32_t' },
    'props.animation': { type: 'bool' },
    'props.mode': { type: 'enum', enumMap: barModeEnumMap },
    'props.startValue': { type: 'int32_t' }
  },
  lv_slider: {
    ...commonPositionSizeFields,
    'props.min': { type: 'int32_t' },
    'props.max': { type: 'int32_t' },
    'props.value': { type: 'int32_t' },
    'props.mode': { type: 'enum', enumMap: barModeEnumMap },
    'props.startValue': { type: 'int32_t' }
  },
  lv_tabview: {
    ...commonPositionSizeFields,
    'props.size': { type: 'int32_t' },
    'props.position': { type: 'enum', enumMap: tabviewPositionEnumMap }
  },
  lv_msgbox: {
    ...commonPositionSizeFields,
    'props.title': { type: 'char' },
    'props.content': { type: 'char' },
    'props.btnWidth': { type: 'int32_t' },
    'props.btnHeight': { type: 'int32_t' }
  },
  lv_win: {
    ...commonPositionSizeFields,
    'props.title': { type: 'char' },
    'props.titleHeight': { type: 'int32_t' },
    'props.text': { type: 'char' }
  },
  lv_line: {
    ...commonPositionSizeFields
  },
  lv_arc: {
    ...commonPositionSizeFields,
    'props.mode': { type: 'enum', enumMap: arcModeEnumMap },
    'props.rangeStart': { type: 'int32_t' },
    'props.rangeEnd': { type: 'int32_t' },
    'props.value': { type: 'int32_t' },
    'props.angleStart': { type: 'int16_t' },
    'props.angleEnd': { type: 'int16_t' },
    'props.rotate': { type: 'int32_t' },
    'props.rotateOffset': { type: 'bool' },
    'props.rotateOffsetValue': { type: 'int32_t' },
    'props.changeRate': { type: 'uint32_t' }
  },
  lv_scale: {
    ...commonPositionSizeFields,
    'props.mode': { type: 'enum', enumMap: scaleModeEnumMap },
    'props.tick': { type: 'uint32_t' },
    'props.mainTick': { type: 'uint32_t' },
    'props.rangeStart': { type: 'int32_t' },
    'props.rangeEnd': { type: 'int32_t' },
    'props.enableLabels': { type: 'bool' },
    'props.labels': { type: 'char' }
  },
  lv_led: {
    ...commonPositionSizeFields,
    'props.led_color': { type: 'int32_t' },
    'props.led_set_bright': { type: 'uint8_t' }
  },
  lv_canvas: {
    ...commonPositionSizeFields,
    'props.background_color': { type: 'int32_t' },
    'props.background_alpha': { type: 'uint8_t' }
  },
  lv_spinner: {
    ...commonPositionSizeFields,
    'props.length': { type: 'uint32_t' },
    'props.time': { type: 'uint32_t' }
  },
  lv_roller: {
    ...commonPositionSizeFields,
    'props.direction': { type: 'enum', enumMap: rollerModeEnumMap }
  },
  lv_spinbox: {
    ...commonPositionSizeFields,
    'props.rangeMin': { type: 'int32_t' },
    'props.rangeMax': { type: 'int32_t' },
    'props.step': { type: 'int32_t' },
    'props.integerDigits': { type: 'uint32_t' },
    'props.decimalPlaces': { type: 'uint32_t' },
    'props.value': { type: 'int32_t' },
    'props.rollOver': { type: 'bool' }
  },
  lv_keyboard: {
    ...commonPositionSizeFields,
    'props.mode': { type: 'enum', enumMap: keyboardModeEnumMap },
    'props.showPopovers': { type: 'bool' }
  },
  lv_animimg: {
    ...commonPositionSizeFields,
    'props.time': { type: 'uint32_t' },
    'props.repeatCount': { type: 'int32_t' },
    'props.playback': { type: 'bool' },
    'props.playbackTime': { type: 'uint32_t' },
    'props.playbackDelay': { type: 'uint32_t' },
    'props.autoPlay': { type: 'bool' },
    'props.reverse': { type: 'bool' }
  },
  lv_calendar: {
    ...commonPositionSizeFields,
    'props.currentDate': { type: 'char' },
    'props.displayDate': { type: 'char' },
    'props.showLunar': { type: 'bool' }
  },
  dagital_clock: {
    ...commonPositionSizeFields,
    'props.timeText': { type: 'char' },
    'props.showSecond': { type: 'bool' },
    'props.showAmPm': { type: 'bool' }
  },
  video: {
    ...commonPositionSizeFields,
    'props.source.type': { type: 'enum', enumMap: videoSourceEnumMap },
    'props.source.file.sd_path': { type: 'char' },
    'props.source.file.autoplay': { type: 'bool' },
    'props.source.file.loop': { type: 'bool' }
  },
  qrcode: {
    'props.x': { type: 'int32_t' },
    'props.y': { type: 'int32_t' },
    'props.lightColor': { type: 'int32_t' },
    'props.darkColor': { type: 'int32_t' },
    'props.size': { type: 'int32_t' },
    'props.text': { type: 'char' }
  },
  barcode: {
    'props.x': { type: 'int32_t' },
    'props.y': { type: 'int32_t' },
    'props.height': { type: 'int32_t' },
    'props.lightColor': { type: 'int32_t' },
    'props.darkColor': { type: 'int32_t' },
    'props.scale': { type: 'uint16_t' },
    'props.direction': { type: 'enum', enumMap: barcodeDirectionEnumMap },
    'props.text': { type: 'char' }
  },
  base_meter: {
    ...commonPositionSizeFields,
    'props.mode': { type: 'enum', enumMap: meterModeEnumMap },
    'props.tick': { type: 'uint32_t' },
    'props.mainTick': { type: 'uint32_t' },
    'props.rangeStart': { type: 'int32_t' },
    'props.rangeEnd': { type: 'int32_t' },
    'props.angleRange': { type: 'int32_t' },
    'props.rotationAngle': { type: 'int32_t' },
    'props.enableText': { type: 'bool' },
    'props.labels': { type: 'char' }
  }
}

const withVariableConfig = (
  schema: ComponentSchema,
  configMap: Record<string, VariableConfig>
): ComponentSchema => {
  const nextSchema: ComponentSchema = {
    ...schema
  }

  if (schema.field && configMap[schema.field] && !schema.variableConfig) {
    nextSchema.variableConfig = configMap[schema.field]
  }

  if (schema.children?.length) {
    nextSchema.children = schema.children.map((child) => withVariableConfig(child, configMap))
  }

  if (schema.valueType === 'dependency' && typeof schema.dependency === 'function') {
    const dependency = schema.dependency
    nextSchema.dependency = (...args: any[]) => {
      const result = dependency(...args)
      const items = Array.isArray(result) ? result : result ? [result] : []
      return items.map((item) => withVariableConfig(item, configMap))
    }
  }

  return nextSchema
}

export const enhanceWidgetVariableConfig = (widget: IComponentModelConfig): IComponentModelConfig => {
  const configMap = {
    ...commonWidgetVariableConfig,
    ...(widgetVariableConfigMap[widget.key] || {})
  }

  return {
    ...widget,
    config: {
      ...widget.config,
      props: widget.config.props?.map((item) => withVariableConfig(item, configMap)),
      coreProps: widget.config.coreProps?.map((item) => withVariableConfig(item, configMap)),
      styles: widget.config.styles?.map((item) => withVariableConfig(item, configMap))
    }
  }
}
