<script>
import { v4 as uuidv4 } from 'uuid'
import {
  FormModel,
  Input,
  Button,
  Row,
  Col,
  Card,
  Divider,
  message,
  Select,
  Spin
} from 'ant-design-vue'
import { getConfigByNameAsync, runLogic } from '@vue2-client/services/api/common'
import { mapState } from 'vuex'
import { debounce } from 'lodash'

export default {
  name: 'HAddNativeForm',
  components: {
    'a-form-model': FormModel,
    'a-form-item': FormModel.Item,
    'a-input': Input,
    'a-button': Button,
    'a-row': Row,
    'a-col': Col,
    'a-card': Card,
    'a-divider': Divider,
    'a-select': Select,
    'a-select-option': Select.Option,
    'a-spin': Spin
  },
  props: {
    queryParamsName: {
      type: String,
      required: true
    },
    serviceName: {
      type: String,
      default: process.env.VUE_APP_SYSTEM_NAME
    }
  },
  data () {
    return {
      loading: true,
      config: {},
      formInstances: [],
      // 从配置读取的样式标识（默认值）
      formStyle: 'defaultForm'
    }
  },
  computed: {
    formItemLayoutComputed () {
      // 如果是 inline 布局，则不绑定 formItemLayout，让其使用 Ant Design Vue 默认的 inline 样式
      if (this.config.xAddFormLayout === 'inline') {
        return {}
      }
      if (this.config.formItemLayout) {
        return {
          labelCol: { span: this.config.formItemLayout.labelCol },
          wrapperCol: { span: this.config.formItemLayout.wrapperCol }
        }
      }
      // 如果是 horizontal 布局但未提供 formItemLayout，则提供一个默认值
      return {
        labelCol: { span: 6 }, // 默认标签宽度
        wrapperCol: { span: 18 } // 默认控件宽度，确保输入框足够宽
      }
    },
    ...mapState('account', { currUser: 'user' })
  },
  created () {
    this.debouncedSearch = debounce(this.performSearch, 500)
    this.fetchConfigAndInitializeForms()
  },
  methods: {
    async fetchConfigAndInitializeForms () {
      try {
        this.loading = true
        const res = await getConfigByNameAsync(this.queryParamsName, this.serviceName)
        if (res) {
          this.config = res
          // 从接口配置设置样式标识
          if (this.config.formStyle) {
            this.formStyle = this.config.formStyle
          }
          if (this.config.manyForm) {
            this.addFormInstance()
          } else {
            this.addFormInstance()
          }
        } else {
          console.error('HAddNativeForm: 未能获取到配置内容。')
          message.error('未能获取到表单配置，请检查配置名称或网络。')
        }
      } catch (error) {
        console.error('HAddNativeForm: 获取配置时发生错误:', error)
        message.error('获取表单配置时发生错误。')
      } finally {
        this.loading = false
      }
    },
    async getOptions (item, formDataContext, searchKeyword = '') {
      if (!item.keyName) {
        return
      }

      this.$set(item, 'loadingOptions', true)
      let fetchedOptions = []

      try {
        if (item.keyName.startsWith('logic@')) {
          const logicName = item.keyName.substring(6)
          const result = await runLogic(logicName, { searchKeyword: searchKeyword }, this.serviceName)

          if (Array.isArray(result)) {
            fetchedOptions = result.map(opt => ({
              label: opt.label || opt.name || opt.text,
              value: (opt.value || opt.id) + '',
              ...opt // 将所有原始属性也添加到选项中
            }))
          } else {
            console.warn(`Logic '${logicName}' did not return an array for options. Result:`, result)
          }
        } else if (item.keyName.startsWith('config@')) {
          const configName = item.keyName.substring(7)
          const res = await getConfigByNameAsync(configName, this.serviceName)
          if (res && res.value && Array.isArray(res.value)) {
            fetchedOptions = res.value.map(opt => ({
              label: opt.label || opt.name || opt.text,
              value: (opt.value || opt.id) + '',
              ...opt // 将所有原始属性也添加到选项中
            }))
          } else {
            console.warn(`Config '${configName}' did not return a valid 'value' array for options. Result:`, res)
          }
        } else {
          // 全局字典
          if (this.$appdata && typeof this.$appdata.getDictByKeyAsync === 'function') {
            const dictionaryList = await this.$appdata.getDictByKeyAsync(item.keyName)
            if (Array.isArray(dictionaryList)) {
              fetchedOptions = dictionaryList.map(opt => ({
                label: opt.label,
                value: opt.value + '',
                ...opt // 将所有原始属性也添加到选项中
              }))
            } else {
              console.warn(`Global dictionary '${item.keyName}' did not return an array. Result:`, dictionaryList)
            }
          } else {
            console.error('$appdata.getDictionaryList is not available. Please ensure it\'s globally provided.')
          }
        }
      } catch (error) {
        console.error(`Error fetching options for item '${item.key}':`, error)
        fetchedOptions = []
      } finally {
        this.$set(item, 'options', fetchedOptions)
        this.$set(item, 'loadingOptions', false)
      }
    },
    // 搜索处理函数，使用 debounce 优化性能
    handleSelectSearch (value, item, formDataContext) {
      // 更新搜索关键字，并触发 debouncedSearch
      this.$set(item, 'searchKeyword', value)
      this.debouncedSearch(item, formDataContext)
    },
    // 执行实际的搜索操作
    performSearch (item, formDataContext) {
      this.getOptions(item, formDataContext, item.searchKeyword)
    },
    // 当选择框获得焦点时，重新加载选项（如果没有搜索关键字）
    handleSelectFocus (item, formDataContext) {
      if (!item.searchKeyword || item.searchKeyword === '') {
        this.getOptions(item, formDataContext)
      }
    },
    // 批量设置所有表单值
    setAllFormsData (dataList) {
      // 确保有足够多的表单实例来容纳所有数据
      while (this.formInstances.length < dataList.length) {
        this.addFormInstance()
      }
      dataList.forEach((data, index) => {
        if (this.formInstances[index]) {
          Object.assign(this.formInstances[index].formData, data)
        }
      })
      this.$forceUpdate()
    },
    addFormInstance () {
      const newId = uuidv4()
      const newFormData = {}
      const clonedFormItems = this.config.formItem ? JSON.parse(JSON.stringify(this.config.formItem)) : []

      if (clonedFormItems.length > 0) {
        for (const item of clonedFormItems) {
          newFormData[item.key] = undefined
          if (item.formType === 'select' && item.keyName) {
            this.$set(item, 'options', [])
            this.$set(item, 'loadingOptions', false)
            this.$set(item, 'searchKeyword', '')
            this.getOptions(item, newFormData)
          }
        }
      }

      this.formInstances.push({
        id: newId,
        formData: newFormData,
        formItems: clonedFormItems
      })
    },
    deleteFormInstance (id) {
      if (this.formInstances.length > 1) {
        this.formInstances = this.formInstances.filter(instance => instance.id !== id)
      } else {
        message.warning('至少需要保留一个表单实例。')
      }
    },
    getRules (item) {
      const rules = []
      if (item.rule && (item.rule.required === true || item.rule.required === 'true')) {
        rules.push({
          required: true,
          message: `请输入${item.title}`,
          trigger: 'blur'
        })
      }
      return rules
    },
    async onSubmit () {
      let allFormsValid = true
      const allFormsData = []

      for (const instance of this.formInstances) {
        const formRef = this.$refs['formModel_' + instance.id][0]
        if (formRef) {
          try {
            await formRef.validate()
            allFormsData.push(instance.formData)
          } catch (error) {
            allFormsValid = false
            break
          }
        }
      }

      if (allFormsValid) {
        message.success('表单提交成功！')
        this.$emit('submit', allFormsData)
      } else {
        message.error('部分表单校验失败，请检查。')
      }
    },
    getAllFormsData () {
      return this.formInstances.map(instance => {
        return instance.formData
      })
    },
    handleSelectChange (value, option, selectItem, formData, allFormItems) {
      // 直接获取option.data.props中的完整数据
      const selectedOptionData = option?.data?.props
      if (selectedOptionData) {
        for (const key in selectedOptionData) {
          if (Object.prototype.hasOwnProperty.call(selectedOptionData, key) && !['label', 'value'].includes(key)) {
            const targetItem = allFormItems.find(item => item.key === key)
            if (targetItem) {
              formData[key] = selectedOptionData[key]
              this.$forceUpdate()
            }
          }
        }
      }
    }
  }
}
</script>

<template>
  <div class="h-add-native-form-group" :class="[`h-add-native-form-${formStyle}`]">
    <a-skeleton :loading="loading" :paragraph="{ rows: 4 }" />
    <div v-if="!loading">
      <div v-for="(formInstance, formIndex) in formInstances" :key="formInstance.id" class="form-instance-wrapper">
        <!-- <div v-if="config.manyForm" class="form-instance-title">药品 {{ formIndex + 1 }}</div> -->
        <a-form-model
          :ref="'formModel_' + formInstance.id"
          :model="formInstance.formData"
          v-bind="formItemLayoutComputed"
          :layout="config.xAddFormLayout || 'horizontal'"
        >
          <a-row :gutter="16">
            <a-col
              v-for="(item, itemIndex) in formInstance.formItems"
              :key="itemIndex"
              :xs="24"
              :sm="12"
              :md="8"
              :lg="6"
              :xl="6"
            >
              <a-form-item
                :label="item.title"
                :prop="item.key"
                :rules="getRules(item)"
              >
                <a-input
                  v-if="item.formType === 'input'"
                  v-model="formInstance.formData[item.key]"
                  :placeholder="'请输入' + item.title"
                  style="width: 100%"
                />
                <a-select
                  v-else-if="item.formType === 'select'"
                  v-model="formInstance.formData[item.key]"
                  :placeholder=" '请选择' + item.title"
                  :options="item.options"
                  :loading="item.loadingOptions"
                  show-search
                  allowClear
                  :filter-option="false"
                  @search="(value) => handleSelectSearch(value, item, formInstance.formData)"
                  @focus="() => handleSelectFocus(item, formInstance.formData)"
                  @change="(value, option) => handleSelectChange(value, option, item, formInstance.formData, formInstance.formItems)"
                  :dropdownMatchSelectWidth="false"
                  :dropdownStyle="{ minWidth: '200px' }"
                  style="width: 100%"
                >
                  <a-spin v-if="item.loadingOptions" slot="notFoundContent" size="small" />
                </a-select>
                <!-- 可以根据需要添加其他表单类型，例如 select, datePicker 等 -->
              </a-form-item>
            </a-col>
          </a-row>
        </a-form-model>
        <a-divider style="margin: 10px" v-if="config.manyForm && formIndex < formInstances.length - 1" />
      </div>

      <!-- 全局添加/删除按钮，只在所有表单实例之后显示 -->
      <a-row v-if="config.manyForm" type="flex" justify="start" style="margin-top: 20px; gap: 10px;">
        <a-button v-if="config.showAddButton" class="form-action-button" icon="plus" @click="addFormInstance"></a-button>
        <a-button v-if="config.showDeleteButton && formInstances.length > 1" class="form-action-button" style="margin-left: 0px" icon="minus" @click="deleteFormInstance(formInstances[formInstances.length - 1].id)"></a-button>
      </a-row>

      <a-row v-if="config.showSubmitBtn" type="flex" justify="start" style="margin-top: 20px;">
        <a-col>
          <a-button type="primary" @click="onSubmit">{{ config.btnName || '提交' }}</a-button>
        </a-col>
      </a-row>
    </div>
  </div>
</template>

<style scoped lang="less">
.h-add-native-form-group {
  // 基础样式，对应 defaultForm
  &.h-add-native-form-defaultForm {
    padding: 0px;
    // background-color: #fff;
    border-radius: 8px;
  }
  &.h-add-native-form-medicalForm {
    @media (min-width: 1200px) {
      :deep(.ant-col-xl-6) {
        display: block;
        flex: 0 0 42%;
        max-width: 42%;
        width: 42%;
      }
    }
  }
}

.form-instance-wrapper {
  margin-bottom: 0px;
  /* 移除边框和背景色，使其看起来像一个整体 */
  /* border: 1px solid #e8e8e8;
  border-radius: 4px;
  background-color: #fff; */
}

.form-instance-title {
  font-weight: bold;
  font-size: 16px;
  margin-bottom: 10px;
  padding-left: 10px; /* 与表单项对齐 */
  color: rgba(0, 0, 0, 0.85);
}

.form-action-button {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  border: 1px solid #d9d9d9;
  background-color: #fff;
  color: rgba(0, 0, 0, 0.65);
  display: flex;
  justify-content: center;
  align-items: center;
  margin-left: 95px;

  &:hover {
    border-color: #40a9ff; /* 鼠标悬停时边框颜色 */
    color: #40a9ff; /* 鼠标悬停时图标颜色 */
  }
}

// 修复表单控件宽度问题
:deep(.ant-form-item-control-wrapper) {
  width: 100%;
}

:deep(.ant-form-item-control) {
  width: 100%;
}

:deep(.ant-input),
:deep(.ant-select) {
  width: 100% !important;
}

:deep(.ant-card-extra) {
  padding: 0;
}

:deep(.ant-form-item) {
  margin-bottom: 5px; // 增加表单项间距
  display: flex;
  flex-direction: column;
  margin-left: 95px;
}

:deep(.ant-form-item-label) {
  text-align: left;
  white-space: normal;
}

:deep(.ant-form-item-control-wrapper) {
  flex: 1;
}

// 针对 inline 布局的样式调整
:deep(.ant-form-inline .ant-form-item) {
  margin-right: 0;
  margin-bottom: 16px;
  display: flex;
  flex-direction: row;
  align-items: flex-start;
}

:deep(.ant-form-inline .ant-form-item-label) {
  padding-right: 8px;
  flex: none;
}

:deep(.ant-form-inline .ant-form-item-control-wrapper) {
  flex: 1;
  min-width: 0;
}

:deep(.ant-form-inline .ant-input),
:deep(.ant-form-inline .ant-select) {
  width: 100% !important;
  min-width: 120px; // 确保有最小宽度
}

// 响应式布局调整
@media (max-width: 768px) {
  :deep(.ant-col-xs-24) {
    width: 100%;
  }

  :deep(.ant-form-item) {
    margin-bottom: 12px;
  }
}
</style>
