import { VNode, h, onMounted, ref, watch } from 'vue'
import { VxeUI, getIcon, getI18n } from '@vxe-ui/core'
import VxeFormItemComponent from '../../../form/src/form-item'
import VxeButtonComponent from '../../../button/src/button'
import VxeTextareaComponent from '../../../textarea/src/textarea'
import VxeTipComponent from '../../../tip/src/tip'

import type { VxeGlobalRendererHandles } from '../../../../types'

export interface WidgetDataSourceOptionSubObjVO {
  value: string,
}

export interface WidgetDataSourceOptionObjVO {
  value: string,
  options?: WidgetDataSourceOptionSubObjVO[]
}

export function useWidgetPropDataSource (props: {
  readonly renderOpts: VxeGlobalRendererHandles.RenderFormDesignWidgetFormViewOptions
  readonly renderParams: VxeGlobalRendererHandles.RenderFormDesignWidgetFormViewParams<{
    options: WidgetDataSourceOptionObjVO[]
  }>
}, renderConfig?: {
  isSubOption?: boolean
}) {
  const renConf = Object.assign({}, renderConfig)
  const isSubOption = renConf.isSubOption

  const optionsContent = ref('')
  const expandIndexList = ref<number[]>([])

  const addOptionEvent = () => {
    const { renderParams } = props
    const { widget } = renderParams
    const options = widget.options.options || []
    options.push({
      value: getI18n('vxe.formDesign.widgetProp.dataSource.defValue', [options.length + 1])
    })
    widget.options.options = [...options]
  }

  const subRE = /^(\s|\t)+/

  const hasSubOption = (str: string) => {
    return subRE.test(str)
  }

  const expandAllOption = () => {
    const { renderParams } = props
    const { widget } = renderParams
    const options = widget.options.options || []
    const indexList: number[] = []
    options.forEach((group, gIndex) => {
      const { options } = group
      if (options && options.length) {
        indexList.push(gIndex)
      }
    })
    expandIndexList.value = indexList
  }

  const toggleExpandOption = (item: WidgetDataSourceOptionSubObjVO, gIndex: number) => {
    if (expandIndexList.value.includes(gIndex)) {
      expandIndexList.value = expandIndexList.value.filter(num => num !== gIndex)
    } else {
      expandIndexList.value.push(gIndex)
    }
  }

  const removeOptionEvent = (item: WidgetDataSourceOptionSubObjVO, group: WidgetDataSourceOptionObjVO | null) => {
    const { renderParams } = props
    const { widget } = renderParams
    const { options } = widget
    if (group) {
      if (group.options) {
        group.options = group.options.filter(obj => obj !== item)
      }
    } else {
      options.options = options.options.filter(obj => obj !== item)
    }
  }

  const confirmBatchAddOptionEvent = () => {
    const { renderParams } = props
    const { widget } = renderParams
    const optList: WidgetDataSourceOptionSubObjVO[] = []
    const rowList = optionsContent.value.split('\n')
    let prevGroup: Required<WidgetDataSourceOptionObjVO> | null = null
    if (isSubOption) {
      rowList.forEach((str, index) => {
        const nextStr = rowList[index + 1]
        const value = str.trim()
        if (!value) {
          return
        }
        const item: WidgetDataSourceOptionSubObjVO = {
          value
        }
        if (prevGroup) {
          if (hasSubOption(str)) {
            prevGroup.options.push(item)
            return
          }
          prevGroup = null
          optList.push(item)
        } else {
          optList.push(item)
        }
        if (nextStr) {
          if (hasSubOption(nextStr)) {
            prevGroup = Object.assign(item, { options: [] })
          }
        }
      })
    } else {
      rowList.forEach((str) => {
        optList.push({
          value: str.trim()
        })
      })
    }
    widget.options.options = optList
    expandAllOption()
  }

  const openPopupEditEvent = () => {
    const { renderParams } = props
    const { widget } = renderParams

    const contList: string[] = []
    widget.options.options?.forEach(group => {
      contList.push(group.value)
      group.options?.forEach(item => {
        contList.push(`\t${item.value}`)
      })
    })

    optionsContent.value = contList.join('\n')

    VxeUI.modal.open({
      title: `${widget.title} - ${getI18n('vxe.formDesign.widgetProp.dataSource.batchEditOption')}`,
      width: 500,
      height: '50vh ',
      resize: true,
      showFooter: true,
      showCancelButton: true,
      showConfirmButton: true,
      confirmButtonText: getI18n('vxe.formDesign.widgetProp.dataSource.buildOption'),
      onConfirm: confirmBatchAddOptionEvent,
      slots: {
        default () {
          return h('div', {
            class: 'vxe-form-design--widget-form-item-data-source-popup'
          }, [
            h(VxeTipComponent, {
              status: 'primary',
              title: '',
              content: getI18n(`vxe.formDesign.widgetProp.dataSource.${isSubOption ? 'batchEditSubTip' : 'batchEditTip'}`)
            }),
            h(VxeTextareaComponent, {
              resize: 'none',
              modelValue: optionsContent.value,
              'onUpdate:modelValue' (val) {
                optionsContent.value = val
              }
            })
          ])
        }
      }
    })
  }

  const renderOption = (item: WidgetDataSourceOptionSubObjVO, group: WidgetDataSourceOptionObjVO | null, isExpand: boolean, gIndex: number, hasSub: boolean, isFirst: boolean, isLast: boolean) => {
    const hasFirstLevel = !group
    return h('div', {
      class: ['vxe-form-design--widget-form-item-data-source-option', {
        'is--first': isFirst,
        'is--last': isLast
      }]
    }, [
      h('div', {
        class: 'vxe-form-design--widget-expand-btn'
      }, hasFirstLevel && hasSub
        ? [
            h('i', {
              class: isExpand ? getIcon().FORM_DESIGN_WIDGET_OPTION_EXPAND_CLOSE : getIcon().FORM_DESIGN_WIDGET_OPTION_EXPAND_OPEN,
              onClick () {
                toggleExpandOption(item, gIndex)
              }
            })
          ]
        : []),
      h('input', {
        class: 'vxe-default-input',
        value: item.value,
        onInput (evnt: InputEvent & { target: HTMLInputElement }) {
          item.value = evnt.target.value
        }
      }),
      h(VxeButtonComponent, {
        status: 'danger',
        mode: 'text',
        icon: getIcon().FORM_DESIGN_WIDGET_DELETE,
        onClick () {
          removeOptionEvent(item, group)
        }
      })
    ])
  }

  const renderOptions = () => {
    const { renderParams } = props
    const { widget } = renderParams
    const { options } = widget
    const groups = options.options
    const optVNs: VNode[] = []
    if (groups) {
      groups.forEach((group, gIndex) => {
        const { options } = group
        const isExpand = expandIndexList.value.includes(gIndex)
        if (options && options.length) {
          optVNs.push(renderOption(group, null, isExpand, gIndex, true, gIndex === 0, gIndex === groups.length - 1))
          if (isExpand) {
            optVNs.push(
              h('div', {
                class: 'vxe-form-design--widget-form-item-data-source-sub-option'
              }, options.map(item => renderOption(item, group, isExpand, 0, false, false, false)))
            )
          }
        } else {
          optVNs.push(renderOption(group, null, isExpand, gIndex, false, gIndex === 0, gIndex === groups.length - 1))
        }
      })
    }
    return optVNs
  }

  watch(() => props.renderParams.widget, () => {
    expandAllOption()
  })

  onMounted(() => {
    expandAllOption()
  })

  const renderDataSourceFormItemContent = () => {
    return [
      h('div', {}, [
        h(VxeButtonComponent, {
          status: 'primary',
          mode: 'text',
          content: getI18n('vxe.formDesign.widgetProp.dataSource.addOption'),
          onClick: addOptionEvent
        }),
        h(VxeButtonComponent, {
          status: 'primary',
          mode: 'text',
          content: getI18n('vxe.formDesign.widgetProp.dataSource.batchEditOption'),
          onClick: openPopupEditEvent
        })
      ]),
      h('div', {
        class: 'vxe-form-design--widget-form-item-data-source-wrapper'
      }, renderOptions())
    ]
  }

  return {
    renderDataSourceFormItem () {
      return h(VxeFormItemComponent, {
        title: getI18n('vxe.formDesign.widgetProp.dataSource.name'),
        field: 'options'
      }, {
        default () {
          return renderDataSourceFormItemContent()
        }
      })
    },
    renderDataSourceFormItemContent
  }
}
