import { defineComponent, PropType, ref, computed, h } from 'vue'
import type { Component } from 'vue'
import { ElInput, ElForm, ElFormItem } from 'element-plus'
import type { FormInstance } from 'element-plus'
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 Switch from './Form/Switch .vue'
import './Form/form.scss'

import type { FormItemRule } from 'element-plus'

type SimpleFormData = Record<string, unknown>

// 定义表单项配置接口
export interface IFormConfig {
  fixed?: string
  title?: string | boolean
  prop?: string
  label?: string
  type?: string
  btn?: JSX.Element | (() => JSX.Element)
  attrs?: SimpleFormData
  isIncludeProp?: boolean
  rules?: FormItemRule | FormItemRule[]
  render?: (
    item?: IFormConfig,
    formData?: SimpleFormData,
    index?: number,
  ) => VNode | VNode[] | JSX.Element
}

// 定义组件类型
type ComponentType = Component

// 支持的组件映射
const componentConfig: Record<string, ComponentType> = {
  input: ElInput,
  amountInput: AmountInput,
  dateRangePicker: DateRangePicker,
  datePicker: DatePicker,
  select: Select,
  switch: Switch,
  // 这里可以根据需要添加更多组件类型
}

export default defineComponent({
  name: 'CustomizeForm',
  props: {
    config: {
      type: Array as PropType<IFormConfig[]>,
      default: () => [],
    },
    labelWidth: {
      type: [String, Number],
      default: 100,
    },
    formItemWidth: {
      type: [String, Number],
      default: '50%',
    },
    modelValue: {
      type: Object,
      default: () => ({}),
    },
    size: {
      type: String as PropType<'large' | 'default' | 'small'>,
      default: 'default',
    },
    inline: {
      type: Boolean,
      default: false,
    },
    labelPosition: {
      type: String as PropType<'left' | 'right' | 'top'>,
      default: 'right',
    },
  },
  emits: ['update:modelValue', 'validate'],
  setup(props, { emit, attrs }) {
    const formRef = ref<FormInstance>()
    const formData = ref<Record<string, unknown>>(props.modelValue)
    const tableConfig = shallowRef<IFormConfig[]>([])

    watch(
      () => props.config,
      (val) => {
        console.log(89, val)

        tableConfig.value = val.filter((item) => !item.isIncludeProp)
      },
      { immediate: true, deep: true },
    )
    // 监听表单数据变化
    watch(
      () => formData.value,
      (val) => {
        emit('update:modelValue', val)
      },
      { deep: true },
    )

    // 监听外部数据变化
    watch(
      () => props.modelValue,
      (val) => {
        formData.value = val
      },
      { immediate: true, deep: true },
    )

    // 获取form表单的属性
    const getFormAttrs = computed(() => ({
      ...attrs,
      style: { width: '100%' },
    }))

    // 获取组件项的属性
    const getComponentAttrs = (item: IFormConfig) => {
      return item.attrs ? { ...item.attrs } : {}
    }

    // 表单验证方法
    const validate = async () => {
      if (!formRef.value) return false
      return await formRef.value.validate()
    }
    // 表单验证方法
    const clearValidate = async () => {
      if (!formRef.value) return false

      return await formRef.value?.clearValidate()
    }

    // 重置表单
    const resetFields = async () => {
      await formRef.value?.resetFields()
    }

    function refashConfig(showFields?: string[]) {
      if (showFields?.length) {
        const filterArr = props.config.filter((item) =>
          showFields.includes(item.prop as string),
        )

        tableConfig.value = [
          ...props.config.filter((item) => !item.isIncludeProp),
          ...filterArr,
        ]
          .filter((item) => !item.fixed)
          .concat(tableConfig.value.filter((item) => item.fixed))
      } else {
        tableConfig.value = props.config.filter((item) => !item.isIncludeProp)
      }
      console.log(154, tableConfig.value)
    }

    return {
      formRef,
      formData,
      validate,
      resetFields,
      getFormAttrs,
      getComponentAttrs,
      refashConfig,
      tableConfig,
      clearValidate,
    }
  },
  render() {
    return (
      <ElForm
        ref="formRef"
        model={this.formData}
        labelWidth={this.labelWidth}
        size={this.size}
        inline={this.inline}
        labelPosition={this.labelPosition}
        {...this.getFormAttrs}
        style={{ display: 'flex', flexWrap: 'wrap' }}
        class="customForm"
      >
        {this.tableConfig.map((item, index) =>
          item.title ? (
            <div
              style={{
                display: 'flex',
                width: '100%',
                flexWrap: 'wrap',
              }}
            >
              {typeof item.title === 'string' && item.title !== '' && (
                <div
                  style={{
                    width: '100%',
                    textAlign: 'center',
                    fontWeight: 700,
                    marginBottom: '20px',
                    fontSize: '16px',
                  }}
                >
                  {item.title}
                </div>
              )}
              {item.render && item.render(item, this.formData)}
            </div>
          ) : (
            <ElFormItem
              key={index}
              prop={item.prop}
              label={item.label}
              style={{
                width: item.attrs?.width || this.formItemWidth || '50%',
              }}
              rules={item.rules}
            >
              {item.render
                ? item.render(item)
                : h(
                    componentConfig[
                      item.type as keyof typeof componentConfig
                    ] || ElInput,
                    {
                      modelValue: this.formData[item.prop as string],
                      'onUpdate:modelValue': (value: unknown) => {
                        this.formData[item.prop as string] = value
                      },
                      disabled:
                        typeof item.attrs?.disabled === 'function'
                          ? item.attrs.disabled()
                          : item.attrs?.disabled,
                      ...this.getComponentAttrs(item),
                    },
                  )}

              {item.btn &&
                (typeof item.btn === 'function' ? item.btn() : item.btn)}
            </ElFormItem>
          ),
        )}
      </ElForm>
    )
  },
})
