import { defineComponent, PropType, ref, computed, watch, h } from 'vue'
import type { Component } from 'vue'

import AmountInput from './Form/AmountInput.vue' // 金额输入框
import DateRangePicker from './Form/DateRangePicker.vue' // 时间范围选择器
import DatePicker from './Form/DatePicker.vue' // 单个日期选择器
import Select from './Form/Select.vue' // 普通下拉选择框
import { ElInput, ElForm, ElFormItem, ElButton } from 'element-plus'
import {
  ISearchForm,
  EComponenetType,
  ISeachFormConfig,
  EDataType,
} from '@/types/searchType'

// 组件 - 数据类型 映射
const componentDataTypeMap = new Map([
  [EComponenetType.amountInput, EDataType.string],
  [EComponenetType.input, EDataType.string],
  [EComponenetType.dateRangePicker, EDataType.array],
  [EComponenetType.datePicker, EDataType.string],
  [EComponenetType.select, EDataType.undefined],
])

type ComponentType = Component

const componentConfig: Record<EComponenetType, ComponentType> = {
  [EComponenetType.amountInput]: AmountInput,
  [EComponenetType.input]: ElInput,
  [EComponenetType.dateRangePicker]: DateRangePicker,
  [EComponenetType.datePicker]: DatePicker,
  [EComponenetType.select]: Select,
}

const styles = {
  searchForm: {
    position: 'relative',
  },
  searchFormHeader: {
    display: 'flex',
    marginBottom: '10px',
  },
  wrapper: {
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'flex-start',
    justifyContent: 'space-between',
  },
} as const

export default defineComponent({
  name: 'SearchForm',
  props: {
    config: {
      type: Array as PropType<ISeachFormConfig[]>,
      default: () => [],
    },
    labelWidth: {
      type: [String, Number],
      default: 58,
    },
    modelValue: {
      type: Object as PropType<ISearchForm>,
      default: () => ({}),
    },
    getTablelist: {
      type: Function as PropType<(...args: unknown[]) => Promise<unknown>>,
      default: null,
    },
    size: {
      type: String as PropType<'large' | 'default' | 'small'>,
      default: 'default',
    },
    addPermissionName: {
      type: [String, Array] as PropType<string | string[]>,
      default: '',
    },
    isSearchBtn: {
      type: Boolean,
      default: true,
    },
    isResetBtn: {
      type: Boolean,
      default: true,
    },
    isAddBtn: {
      type: Boolean,
      default: true,
    },
    isDeleteBtn: {
      type: Boolean,
      default: true,
    },
  },
  emits: ['search', 'reset', 'fold', 'add', 'delete', 'update:modelValue'],
  setup(props, { emit, slots, attrs }) {
    const formRef = ref()
    const formWrapperRef = ref()
    const searchForm = ref<ISearchForm>({})
    const selectResult = ref<ISeachFormConfig[]>([])
    const componentWidth = computed(() =>
      props.size === 'default' ? 200 : 220,
    )

    watch(
      () => props.modelValue,
      (val) => {
        searchForm.value = val
      },
      {
        immediate: true,
        deep: true,
      },
    )

    function initSeachForm() {
      props.config.forEach((item, index) => {
        if (componentDataTypeMap.has(item.type as EComponenetType)) {
          const prop = item.prop || `value${index}`
          if (!item.prop) {
            item.prop = prop
          }
        }
      })
    }

    watch(
      () => props.config,
      (val) => {
        if (val.length) {
          initSeachForm()
          selectResult.value = val
        }
      },
      {
        immediate: true,
      },
    )

    // 获取form表单的属性
    const getFormAttrs = computed(() => ({
      ...attrs,
    }))

    // 获取组件项传进来的attrs
    const getComponentAttrs = (item: ISeachFormConfig) => {
      return item.attrs ? { ...item.attrs } : {}
    }

    const handleSubmit = (e: Event) => {
      e.preventDefault()
    }

    return () => (
      <div style={styles.searchForm}>
        <div style={styles.searchFormHeader} class="pb-15">
          {slots['header-content'] ? (
            slots['header-content']()
          ) : (
            <div style={styles.wrapper} class="mt-15">
              <ElForm
                ref={(el) => (formRef.value = el)}
                class="w-full"
                inline
                model={searchForm.value}
                labelPosition="left"
                size={props.size}
                {...{
                  onSubmit: handleSubmit,
                }}
                {...getFormAttrs.value}
              >
                <div ref={formWrapperRef} class="formItemWrapper w-full">
                  <div class="mt--18 flex align-center flex-wrap">
                    {selectResult.value.map((item, index) => (
                      <ElFormItem
                        key={index}
                        prop={item.prop}
                        label={item.label}
                        style={{ marginBottom: '0px' }}
                      >
                        {item.render
                          ? item.render()
                          : h(componentConfig[item.type as EComponenetType], {
                              modelValue: searchForm.value[item.prop],
                              'onUpdate:modelValue': (value: unknown) => {
                                searchForm.value[item.prop] = value
                              },

                              ...getComponentAttrs(item),
                              style: { width: `${componentWidth.value}px` },
                            })}
                      </ElFormItem>
                    ))}
                  </div>
                </div>
              </ElForm>
            </div>
          )}
          <div style={{ display: 'flex', alignItems: 'center' }}>
            {props.isSearchBtn && (
              <ElButton
                class="btn"
                type="primary"
                onClick={() => emit('search', searchForm.value)}
              >
                查询
              </ElButton>
            )}
            {props.isResetBtn && (
              <ElButton
                class="btn"
                onClick={() => {
                  formRef.value?.resetFields()
                  // emit('update:modelValue', {})
                  emit('reset')
                }}
              >
                重置
              </ElButton>
            )}
            {props.isAddBtn && (
              <ElButton class="btn" type="success" onClick={() => emit('add')}>
                新增
              </ElButton>
            )}
            {props.isDeleteBtn && (
              <ElButton
                class="btn"
                type="danger"
                onClick={() => emit('delete')}
              >
                删除
              </ElButton>
            )}
          </div>
          {slots.ontherBtn?.()}
        </div>
      </div>
    )
  },
})
