<script setup lang="ts">
import type { FormInstance } from 'vant'
import XFormItem from '@af-mobile-client-vue3/components/data/XFormItem/index.vue'
import XOlMap from '@af-mobile-client-vue3/components/data/XOlMap/index.vue'
import { formatDate } from '@af-mobile-client-vue3/hooks/useCommon'
import { addOrModifyEntity, getConfigByName, runLogic } from '@af-mobile-client-vue3/services/api/common'
import { useUserStore } from '@af-mobile-client-vue3/stores'

import {
  showFailToast,
  showSuccessToast,
  Button as VanButton,
  CellGroup as VanCellGroup,
  Form as VanForm,
} from 'vant'
import { computed, inject, nextTick, onBeforeMount, onBeforeUnmount, reactive, ref, watch } from 'vue'

interface FormItem {
  addOrEdit: string
  isOnlyAddOrEdit?: boolean
  type?: string
  model?: string
  name?: string
  rule?: {
    type: string
    required: string
  }
}

interface SilenceAddFormItem extends FormItem {
  silencePurpose: string
  silenceSource?: string
}

interface GroupFormItems {
  btnName?: string
  formJson: any[] // 根据实际类型调整
  showSubmitBtn?: boolean
  groupName?: string
  tableName?: string
  paramLogicName?: string
  isGroupForm?: boolean
  isKeyHandle?: boolean
}

interface InitParams {
  formItems?: GroupFormItems
  formData?: object
  getDataParams?: object
}

const props = withDefaults(defineProps<{
  configName?: string
  groupTitle?: string
  groupFormItems?: GroupFormItems
  serviceName?: string
  formData?: object
  formName?: string
  mode?: string
  submitButton?: boolean
  isHandleFormKey?: boolean
  paramLogicNameParam?: any
  isGroupForm?: boolean
  // 整体表单只读：为 true 时，所有表单项不可交互
  formReadonly?: boolean
  // 控制上传——异步/同步
  isAsyncUpload?: boolean
  // 可选：自定义水印内容数组（将拼接在组件默认行之后）
  watermarkCustomLines?: string[]
  // 表单文本位置 center、left、right、top
  labelAlign?: string
  // 表单文本对齐方式 left、center、right
  inputAlign?: string
  /** 是否启用提交按钮 loading（默认不启用，保持历史行为） */
  enableSubmitLoading?: boolean
}>(), {
  configName: undefined,
  groupTitle: undefined,
  groupFormItems: null,
  serviceName: undefined,
  formData: null,
  formName: 'default',
  mode: '查询',
  submitButton: true,
  isHandleFormKey: true,
  paramLogicNameParam: {},
  isGroupForm: false,
  formReadonly: false,
  isAsyncUpload: false,
  watermarkCustomLines: () => [],
  labelAlign: undefined,
  inputAlign: undefined,
  enableSubmitLoading: false,
})

const emits = defineEmits(['onSubmit', 'xFormItemEmitFunc', 'photoQualityChange'])
const userStore = useUserStore()

// inject
const formDataChange = inject('formDataChange', null)

// 核心状态
const xFormRef = ref<FormInstance>()
const loaded = ref(false)
const form = ref({})
const rules = reactive({})
const myGetDataParams = ref({})
const isKeyHandle = ref(false)
const submitLoading = ref(false)
let navigateTimer: number | null = null

// 配置相关状态
const formConfig = ref<GroupFormItems | null>(null)
const formGroupName = ref<string>('default')
const myServiceName = ref('')
const tableName = ref('')
// 水印基础配置（从配置中心加载）
const watermarkBaseConfig = ref<any | null>(null)

// 计算属性（获取全部表单项信息）
const realJsonData = computed(() => {
  const sourceFormItems = formConfig.value?.formJson
  if (!sourceFormItems)
    return []

  return sourceFormItems.filter((item) => {
    return item.addOrEdit !== 'no'
  })
})

// 过滤出用于新增/修改/只读场景的表单项
const addOrEditJsonData = computed(() => {
  return realJsonData.value.filter((item) => {
    return item.addOrEdit === 'all' || item.addOrEdit === 'add' || item.addOrEdit === 'edit' || item.addOrEdit === 'readonly'
  })
})

// 过滤出用于静默新增场景的表单项
const silenceAddJsonData = computed(() => {
  return realJsonData.value.filter((item) => {
    return item.addOrEdit === 'silenceAdd'
  }) as SilenceAddFormItem[]
})

const resolvedSubmitButton = computed(() => {
  if (props.configName && formConfig.value?.showSubmitBtn !== undefined) {
    return formConfig.value.showSubmitBtn
  }
  return props.submitButton
})

const fieldErrors = ref<Record<string, string>>({})

function handleValidateError(model: string, error: string) {
  fieldErrors.value[model] = error
}

// 地图预览相关
const previewMapRef = ref(null)
const previewLonLatKey = computed(() => {
  const item = realJsonData.value.find(i => i.type === 'addressSearch')
  return item ? (item[`${item.model}_lon_lat`] || item[`${item.model}_lng_lat`]) : null
})

const previewMapPoint = computed(() => {
  const val = form.value[previewLonLatKey.value]
  if (previewMapRef.value && val && typeof val === 'string' && val.includes(',')) {
    const [lon, lat] = val.split(',').map(Number)
    if (!Number.isNaN(lon) && !Number.isNaN(lat)) {
      return [lon, lat]
    }
  }
  return null
})

// 地图初始化逻辑
const previewMapInited = ref(false)
const stopWatchPreviewMapPoint = watch(previewMapPoint, async (val) => {
  await nextTick()
  if (val && previewMapRef.value) {
    if (!previewMapInited.value) {
      await previewMapRef.value.init({ center: val, zoom: 16, isPreview: true })
      previewMapInited.value = true
    }
    previewMapRef.value.setCenter(val, true)
    previewMapRef.value.updateLocationMarker(val)
  }
}, { immediate: true })

// 统一的初始化函数 - 仅在组件挂载时调用
async function initializeForm() {
  loaded.value = false

  try {
    if (props.configName) {
      await loadFormConfig()
    }
    else if (props.groupFormItems) {
      await initWithGroupFormItems()
    }
    else {
      console.warn('未提供配置名称或表单配置，等待 init 函数调用')
      resetForm()
    }

    // 按需加载水印配置
    await loadWatermarkConfig()
    // 应用水印到图片类表单项
    applyWatermarkToItems()
  }
  catch (error) {
    console.error('表单初始化失败:', error)
    resetForm()
  }
  finally {
    loaded.value = true
  }
}

// 加载配置的方式初始化
async function loadFormConfig(): Promise<void> {
  return new Promise((resolve, reject) => {
    getConfigByName(props.configName!, (result) => {
      if (result) {
        setupFormConfig(result)
        resolve()
      }
      else {
        console.warn(`配置 '${props.configName}' 不存在`)
        reject(new Error(`配置 '${props.configName}' 不存在`))
      }
    }, props.serviceName)
  })
}

// 直接使用 groupFormItems 初始化
async function initWithGroupFormItems() {
  if (!props.groupFormItems) {
    throw new Error('groupFormItems 不能为空')
  }

  setupFormConfig(props.groupFormItems)

  // 设置表名
  if (props.groupFormItems.tableName) {
    tableName.value = props.groupFormItems.tableName.split(' ')[0] || ''
  }
}

// 设置表单配置
async function setupFormConfig(config: GroupFormItems) {
  await loadParamLogicNameData(config.paramLogicName)
  formConfig.value = config
  isKeyHandle.value = config.isKeyHandle
  myServiceName.value = props.serviceName || undefined
  formGroupName.value = config.groupName || 'default'
  // 清理并重新设置验证规则
  setupValidationRules()
}

// 设置验证规则
function setupValidationRules() {
  // 清理现有规则
  Object.keys(rules).forEach(key => delete rules[key])

  // 为每个表单项设置规则
  for (const item of realJsonData.value) {
    if (item.rule) {
      setFormRule(item)
    }

    // 统一处理 image 和 file 类型的 minAcceptCount 验证（无论是否有 rule）
    if ((item.type === 'image' || item.type === 'file') && (item as any).minAcceptCount !== undefined && (item as any).minAcceptCount !== null) {
      setMinAcceptCountRule(item)
    }
  }
}

// 设置单个表单项的验证规则
function setFormRule(item: FormItem) {
  if (!item.model || !item.rule)
    return

  rules[item.model] = []
  let defaultValue: any
  let message: string

  switch (item.rule.type) {
    case 'number':
      message = '数字'
      defaultValue = 0
      break
    case 'integer':
      message = '整数'
      defaultValue = 0
      break
    case 'float':
      message = '小数'
      defaultValue = 0.0
      break
    case 'string':
      message = '字符串'
      defaultValue = ''
      break
    default:
      return
  }

  rules[item.model].push({
    type: item.rule.type,
    message: `${item.name || item.model}必须为${message}`,
    transform: (value: any) => {
      if (value && value.length !== 0) {
        return Number(value)
      }
      else {
        return defaultValue
      }
    },
    trigger: 'blur',
  })

  // 为 image 和 file 类型添加 minAcceptCount 验证
  if ((item.type === 'image' || item.type === 'file') && (item as any).minAcceptCount !== undefined && (item as any).minAcceptCount !== null) {
    setMinAcceptCountRule(item)
  }
}

// 设置 minAcceptCount 验证规则
function setMinAcceptCountRule(item: FormItem) {
  if (!item.model)
    return

  const minCount = (item as any).minAcceptCount
  if (minCount === undefined || minCount === null || minCount <= 0)
    return

  const isRequired = item.rule?.required === 'true'

  // 如果 rules[item.model] 不存在，先创建
  if (!rules[item.model]) {
    rules[item.model] = []
  }

  rules[item.model].push({
    validator: (value: any) => {
      const fileList = value
      const fileCount = Array.isArray(fileList) ? fileList.length : 0

      // 如果非必填且没有文件，不验证数量（允许为空）
      if (fileCount === 0 && !isRequired) {
        return true
      }

      // 如果有文件或者是必填的，验证数量
      return fileCount >= minCount
    },
    message: `至少需要上传${minCount}张图片`,
    trigger: 'change',
  })
}

// 重置表单状态
function resetForm() {
  formConfig.value = null
  formGroupName.value = 'default'
  myServiceName.value = ''
  tableName.value = ''
  form.value = {}
  Object.keys(rules).forEach(key => delete rules[key])
  myGetDataParams.value = {}
}

// 监听 formData 变化
const stopWatchFormData = watch(() => props.formData, (newVal) => {
  if (newVal) {
    Object.assign(form, newVal)
  }
})

const stopWatchForm = watch(form, (newVal) => {
  if (typeof formDataChange === 'function') {
    formDataChange(newVal)
  }
}, { deep: true })

// 组件挂载时初始化
onBeforeMount(() => {
  initializeForm()
})

onBeforeUnmount(() => {
  stopWatchPreviewMapPoint?.()
  stopWatchFormData?.()
  stopWatchForm?.()
  if (navigateTimer) {
    window.clearTimeout(navigateTimer)
    navigateTimer = null
  }
})

// 支持函数调用方式初始化
async function init(params: InitParams) {
  const {
    formItems,
    formData = {},
    getDataParams = {},
  } = params

  // 重置状态
  loaded.value = false

  try {
    if (props.configName) {
      // 通过 props 中的配置名称初始化
      await loadFormConfig()
    }
    else if (formItems) {
      // 直接使用传入的配置初始化
      setupFormConfig(formItems)
      form.value = formData || props.formData || {}
      myGetDataParams.value = getDataParams

      // 设置表名
      if (formItems.tableName) {
        tableName.value = formItems.tableName.split(' ')[0] || ''
      }
      applyWatermarkToItems()
    }
    else {
      console.warn('init 函数调用时既没有 props.configName 也没有 formItems')
      resetForm()
    }
  }
  catch (error) {
    console.error('init 函数初始化失败:', error)
    resetForm()
  }
  finally {
    loaded.value = true
  }
}

// 加载水印基础配置
async function loadWatermarkConfig(configName?: string): Promise<void> {
  return new Promise((resolve) => {
    getConfigByName('PhotoWatermarkConfig', (result) => {
      watermarkBaseConfig.value = result || null
      resolve()
    }, props.serviceName)
  })
}

// 将水印配置应用到图片/文件类表单项（attr.type === 'image' | 'file'）
function applyWatermarkToItems() {
  if (!formConfig.value || !Array.isArray(formConfig.value.formJson))
    return
  const userName = userStore.getUserInfo()?.name
  const base = watermarkBaseConfig.value
  const baseWatermark = base?.watermark ?? base ?? {}

  formConfig.value.formJson = formConfig.value.formJson.map((item: any) => {
    if (item && (item.type === 'image' || item.type === 'file')) {
      item.watermark = {
        ...baseWatermark,
        userName,
        customLines: props.watermarkCustomLines,
      }
    }
    return item
  })
}

async function loadParamLogicNameData(paramLogicName) {
  // 如果有 paramLogicName，自动请求并赋值
  if (paramLogicName && (!props.formData || (props.formData && Object.keys(props.formData).length === 0))) {
    let logicParam = props?.paramLogicNameParam || {}
    if (typeof logicParam === 'string') {
      try {
        logicParam = JSON.parse(logicParam)
      }
      catch {
        logicParam = { value: logicParam }
      }
    }
    logicParam = {
      ...logicParam,
      currUserName: userStore.getUserInfo().name,
      currUserId: userStore.getUserInfo().id,
      orgId: userStore.getUserInfo().orgid,
    }
    await runLogic(paramLogicName, logicParam || {}, props.serviceName).then((data: any) => {
      if (data) {
        form.value = data
      }
    })
  }
  else {
    form.value = props.formData || {}
  }
}

function setForm(obj: object) {
  Object.assign(form.value, obj)
}

function setFormData(obj: object) {
  form.value = obj
}
// 获取表单字段实际值
function getRealKey(key: string, mustHandleKey = false) {
  if (key === 'selected_id')
    return key
  if (props.isHandleFormKey || mustHandleKey) {
    return key.substring(key.indexOf('_') + 1)
  }
  else {
    return key
  }
}

async function asyncSubmit() {
  return new Promise((resolve, reject) => {
    validate().then(async () => {
      let realForm = prepareForm()
      await appendSilenceAddFields(realForm)
      if (isKeyHandle.value)
        realForm = handleFormKeys(realForm)
      resolve({
        realForm,
        mode: props.mode,
        serviceName: props.serviceName,
        currUserName: userStore.getUserInfo().name,
        currUserId: userStore.getUserInfo().id,
        orgId: userStore.getUserInfo().orgid,
      })
    }).catch((error) => {
      reject(error)
    })
  })
}

function handleFormKeys(form: any, mustHandleKey = false) {
  const realForm: any = {}
  for (const key of Object.keys(form)) {
    const value = form[key]
    const extraFormKeyTagIndex = key.indexOf('@')
    if (extraFormKeyTagIndex !== -1) {
      const extraFormKey = key.substring(0, extraFormKeyTagIndex)
      const realKey = key.substring(extraFormKeyTagIndex + 1)
      if (!realForm[extraFormKey]) {
        realForm[extraFormKey] = {}
      }
      realForm[extraFormKey][realKey] = value
    }
    else {
      const realKey = props.isHandleFormKey || mustHandleKey ? getRealKey(key, mustHandleKey) : key
      // 如果发生重名，不覆盖，把key的别名带上
      if (realForm[realKey]) {
        realForm[key] = value
      }
      else {
        realForm[realKey] = value
      }
    }
  }
  return realForm
}

async function appendSilenceAddFields(form: any) {
  if (props.mode === '新增') {
    for (const item of silenceAddJsonData.value) {
      switch (item.silencePurpose) {
        case 'createTime':
          form[item.model] = formatDate(new Date())
          break
        case 'operator':
          form[item.model] = userStore.getUserInfo().name
          break
        case 'operatorId':
          form[item.model] = userStore.getUserInfo().id
          break
        case 'orgId':
          form[item.model] = userStore.getUserInfo().orgid
          break
        case 'orgName':
          form[item.model] = userStore.getUserInfo().orgs
          break
        case 'depId':
          form[item.model] = userStore.getUserInfo().depids
          break
        case 'depName':
          form[item.model] = userStore.getUserInfo().deps
          break
      }
    }
    for (const item of silenceAddJsonData.value.filter(item => item.silencePurpose === 'customize')) {
      const result: any = await runLogic(item.silenceSource!, form, props.serviceName)
      if (result) {
        const keys = Object.keys(result)
        if (keys.length === 1 && keys[0] === 'value') {
          form[item.model] = result.value
        }
        else {
          form[item.model] = result
        }
      }
      else {
        form[item.model] = result
      }
    }
  }
}

function prepareForm() {
  const formObj = { ...form.value }
  const cleanedForm: any = {}

  for (const key of Object.keys(formObj)) {
    const value = formObj[key]

    // 跳过无效值
    if (value === null || value === undefined || value === '') {
      continue
    }

    // 处理数组
    if (Array.isArray(value)) {
      // 过滤掉空字符串、null、undefined
      const filteredArray = value.filter(item =>
        item !== null && item !== undefined && item !== '',
      )
      // 只有当数组不为空时才添加
      if (filteredArray.length > 0) {
        cleanedForm[key] = filteredArray
      }
      continue
    }

    // 处理对象
    if (typeof value === 'object' && value !== null) {
      // 检查对象是否为空
      const objectKeys = Object.keys(value)
      if (objectKeys.length === 0) {
        continue
      }

      // 递归清理对象内部
      const cleanedObject: any = {}
      let hasValidValue = false

      for (const objKey of objectKeys) {
        const objValue = value[objKey]
        if (objValue !== null && objValue !== undefined && objValue !== '') {
          cleanedObject[objKey] = objValue
          hasValidValue = true
        }
      }

      // 只有当对象有有效值时才添加
      if (hasValidValue) {
        cleanedForm[key] = cleanedObject
      }
      continue
    }

    // 处理基本类型
    if (value !== null && value !== undefined && value !== '') {
      cleanedForm[key] = value
    }
  }

  return cleanedForm
}

function getFormData() {
  return prepareForm()
}

async function onSubmit() {
  if (props.enableSubmitLoading) {
    if (submitLoading.value)
      return
    submitLoading.value = true
  }
  try {
    await validate()
    // 清理表单数据
    let realForm = prepareForm()
    await appendSilenceAddFields(realForm)
    if (!props.configName && props.groupFormItems) {
      // 只有单表才可以成功，多表关联或者自定义sql不行
      realForm = handleFormKeys(realForm)

      try {
        addOrModifyEntity(realForm, tableName.value, props.serviceName || import.meta.env.VITE_APP_SYSTEM_NAME).then(() => {
          showSuccessToast('提交成功!！')
        })
      }
      catch (error) {
        showFailToast('提交失败!！')
      }
      finally {
        navigateTimer = window.setTimeout(() => {
          history.back()
        }, 1000)
      }
    }
    else {
      if (isKeyHandle.value)
        realForm = handleFormKeys(realForm)
      // 使用清理后的数据
      emits('onSubmit', realForm)
    }
  }
  catch {
    if (props.enableSubmitLoading)
      submitLoading.value = false
  }
}
async function validate() {
  await xFormRef.value?.validate()
  const hasError = Object.values(fieldErrors.value).some(err => err && err.length > 0)
  if (hasError) {
    // 将错误转换为 Vant 格式
    const errors = Object.entries(fieldErrors.value)
      .filter(([_, msg]) => msg)
      .map(([model, message]) => ({ name: model, message }))
    return Promise.reject(errors)
  }
}
function emitFunc(func: any, data: any, value: any, attr: any) {
  emits(func, data, value, attr)
  emits('xFormItemEmitFunc', func, data, value, attr)
}

function openLoading() {
  if (props.enableSubmitLoading)
    submitLoading.value = true
}

function closeLoading() {
  if (props.enableSubmitLoading)
    submitLoading.value = false
}

defineExpose({ init, form, formGroupName, validate, asyncSubmit, setForm, getFormData, setFormData, openLoading, closeLoading })
</script>

<template>
  <VanForm v-if="loaded" ref="xFormRef" class="x-form-container" :class="{ 'use-full-height': !props.isGroupForm }" @submit="onSubmit">
    <div class="form-fields-scrollable">
      <VanCellGroup :title="groupTitle">
        <XFormItem
          v-for="(item, index) in addOrEditJsonData"
          :key="index"
          v-model="form[item.model]"
          :mode="props.mode"
          :form="form"
          :attr="item"
          :rules="rules"
          :service-name="myServiceName"
          :get-data-params="myGetDataParams"
          :form-readonly="props.formReadonly"
          :is-async-upload="props.isAsyncUpload"
          :label-align="labelAlign"
          :input-align="props.inputAlign"
          @set-form="setForm"
          @x-form-item-emit-func="emitFunc"
          @validate-error="handleValidateError"
          @photo-quality-change="(type) => emits('photoQualityChange', type)"
        />
        <slot name="extraFormItem" />
      </VanCellGroup>
      <slot name="extraCellGroup" />
      <!-- 地图预览，统一放在表单项下方，只在有经纬度时显示 -->
      <div v-if="previewLonLatKey" v-show="previewMapPoint" style="height: 200px; margin-top: 12px; position: relative;">
        <XOlMap
          ref="previewMapRef"
          :center="previewMapPoint"
          :style="{ height: '100%' }"
        />
        <div class="map-mask" />
      </div>
    </div>
    <div v-if="resolvedSubmitButton && props.mode !== '预览' && !props.formReadonly" class="form-footer-fixed">
      <VanButton
        class="action-btn"
        round
        block
        type="primary"
        native-type="submit"
        :loading="props.enableSubmitLoading && submitLoading"
        :disabled="props.enableSubmitLoading && submitLoading"
      >
        {{ props.groupFormItems?.btnName ? props.groupFormItems.btnName : '提交' }}
      </VanButton>
      <slot />
    </div>
    <slot name="extraActionSpace" />
  </VanForm>
</template>

<style scoped>
.use-full-height {
  height: 100%;
}

.x-form-container {
  display: flex;
  flex-direction: column;
  max-height: 100vh;
  overflow: hidden;
}

.form-fields-scrollable {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

.form-footer-fixed {
  margin: 16px;
  flex-shrink: 0;
  .action-btn {
    border-radius: 10px;
  }
}
.map-mask {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  pointer-events: all;
  background: transparent;
  z-index: 10;
}
</style>
