<script setup lang="ts">
import type {
  AddDeviceEmits,
  AddDeviceProps,
  DeviceFormExposedMethods,
  DeviceTypeAction,
} from './types/device'

import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
import { getConfigByName } from '@af-mobile-client-vue3/services/api/common'
import { useUserStore } from '@af-mobile-client-vue3/stores/modules/user'
import SecurityFormItem from '@af-mobile-client-vue3/views/SafeInspection/SecurityFormItem/index.vue'
import {
  showConfirmDialog,
  showToast,
  ActionSheet as VanActionSheet,
  Button as VanButton,
  Cell as VanCell,
  CellGroup as VanCellGroup,
  Empty as VanEmpty,
  Form as VanForm,
  Icon as VanIcon,
  NoticeBar as VanNoticeBar,
} from 'vant'
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useDeviceForm } from './composables/useDeviceForm'

const props = withDefaults(defineProps<AddDeviceProps & {
  row?: any // 添加row参数用于接收安检项配置
  isViewMode?: boolean // 是否为查看模式（由父组件传入）
  userDetail?: any
}>(), {
  setRef: () => {},
  removeRef: () => {},
  formGroupName: 'devices',
  formData: () => ([]),
  configName: '',
  serviceName: '',
  row: () => ({}),
  isViewMode: false,
})

const emit = defineEmits<AddDeviceEmits>()

// 检查是否为查看模式（有设备数据需要回显）
const isViewMode = computed(() => {
  return !!props.isViewMode
})

const userInfo = useUserStore().getUserInfo()

// 使用组合式函数管理设备状态
const {
  devices,
  addDevice,
  removeDevice,
  resetDevices,
  setDevices,
  getDevices,
  error,
  clearError,
} = useDeviceForm(props.formData || [])

// XForm组件引用
const xFormRefs = ref<any[]>([])
// 安检项表单引用（父组件内的 van-form）
const securityFormRefs = ref<any[]>([])

const deviceTypes = ref<DeviceTypeAction[]>([])
const safeConfig = ref<any>(null)

// 用于强制重渲染“设备安检项”区域（解决程序化写入图片后不回显的问题）
const securityItemsRenderKey = ref(0)

// 为每个设备创建独立的安检项数据（按传入 code 过滤，item.code 为逗号分隔字符串）
function createDeviceItems(code?: string): any[] {
  try {
    const items = Array.isArray(props?.row?.items) ? props.row.items : []
    const targetCode = (code ?? '').trim()
    // 未传入 code 时，返回全部安检项的深拷贝
    if (!targetCode)
      return items.map((it: any) => ({ ...(it || {}) }))

    return items
      .filter((it: any) => {
        const raw = (it?.f_code ?? '').toString()
        // f_code 为空也需要渲染
        if (!raw)
          return true
        const codeList = raw.split(',').map((s: string) => s.trim()).filter(Boolean)
        return codeList.includes(targetCode)
      })
      .map((it: any) => ({ ...(it || {}) }))
  }
  catch (error) {
    return []
  }
}

// 获取设备对应的表单配置名称
function getDeviceFormConfig(deviceType: string): string {
  const matchedType = deviceTypes.value.find((type: any) => type.value === deviceType)
  return matchedType?.formConfig || props.configName
}

// 获取设备对应的服务名称
function getDeviceServiceName(deviceType: string): string {
  const matchedType = deviceTypes.value.find((type: any) => type.value === deviceType)
  // 如果从 formConfig 中获取到值，则使用 af-revenue，否则使用默认的 af-safecheck
  return matchedType?.formConfig ? 'af-revenue' : 'af-safecheck'
}

// 确保每个设备都有独立的安检项数据
function ensureDeviceItems(): void {
  if (!Array.isArray(devices.value))
    return

  devices.value.forEach((device: any, index: number) => {
    try {
      if (!device.deviceId) {
        device.deviceId = `device_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`
      }
      if (!device.deviceItems) {
        device.deviceItems = createDeviceItems(device.deviceCode)
      }
    }
    catch (error) {
      device.deviceItems = []
    }
  })
}

// 设备类型选择弹窗与选项
const showTypeSheet = ref(false)

// 每个设备卡片的展开/收起状态（默认展开）
const expandedStates = ref<boolean[]>([])
expandedStates.value = (devices.value || []).map(() => true)

// 设备数量变化时，保持状态数组长度一致
const stopWatchDevicesLength = watch(() => devices.value.length, (len, oldLen) => {
  const newStates = Array.from({ length: len }, () => true)
  for (let i = 0; i < len; i++) {
    newStates[i] = expandedStates.value[i] ?? true
  }
  expandedStates.value = newStates
})

function toggleCollapse(index: number): void {
  expandedStates.value[index] = !expandedStates.value[index]
}

// 监听外部数据变化
// watch(() => props.formData, (newValue) => {
//   setDevices(newValue || [])
//   // 确保每个设备都有独立的安检项数据
//   ensureDeviceItems()
// }, { deep: true })

// 监听内部数据变化并同步到父组件
const stopWatchDevices = watch(devices, (newValue) => {
  emit('update:formData', [...newValue])
  emit('change', [...newValue])
}, { deep: true })

// 获取表单数据方法
function getFormData(): any[] {
  return getDevices()
}

// 重置表单
function resetForm(): void {
  resetDevices()
}

// 验证所有设备表单（同时验证基础表单与安检项表单）
async function validate(): Promise<void> {
  if (!devices.value || devices.value.length === 0)
    return Promise.resolve()

  const allErrors: any[] = []
  const validationPromises: Promise<any>[] = []
  devices.value.forEach((_, index) => {
    // 验证 XForm
    if (xFormRefs.value && xFormRefs.value[index] && typeof xFormRefs.value[index].validate === 'function') {
      validationPromises.push(
        xFormRefs.value[index]
          .validate()
          .then(() => null)
          .catch((error: any) => {
            if (Array.isArray(error))
              allErrors.push(...error)
            else if (error)
              allErrors.push(error)
            return null
          }),
      )
    }
    // 验证安检项表单（van-form）
    if (securityFormRefs.value && securityFormRefs.value[index] && typeof securityFormRefs.value[index].validate === 'function') {
      validationPromises.push(
        securityFormRefs.value[index]
          .validate()
          .then(() => null)
          .catch((error: any) => {
            if (Array.isArray(error))
              allErrors.push(...error)
            else if (error)
              allErrors.push(error)
            return null
          }),
      )
    }
  })

  await Promise.all(validationPromises)
  if (allErrors.length > 0)
    return Promise.reject(allErrors)
  return Promise.resolve()
}

// 确认添加设备
function selectDevice(): void {
  // 先弹出设备类型选择
  showTypeSheet.value = true
}

// 根据设备名称。获取第一个设备
function getDeviceDetailsByName(name: string) {
  return (devices.value || [])
    .map((item: any, index: number) => ({
      index,
      payload: {
        deviceId: item.deviceId,
        deviceType: item.f_devices_type,
        groupName: props.row.itemname,
      },
      match: item.f_devices_type === name,
    }))
    .filter((item: any) => item.match)
    .map(({ index, payload }) => ({
      index,
      payload,
    }))
}

// 根据ai识别的设备名称。判断是否存在这个设备。没有新增
function addDeviceByName(name: string): void {
  if (devices.value.find((device: any) => device.f_devices_type === name)) {
    return
  }
  const device = deviceTypes.value.find((type: any) => type.name === name)
  if (!device) {
    return
  }
  onTypeSelected(device)
}

// 选择了设备类型后创建设备，并将类型写入表单数据
function onTypeSelected(action: DeviceTypeAction): void {
  try {
    showTypeSheet.value = false
    const deviceId = `device_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`
    const success = addDevice(userInfo, {
      f_devices_type: action.value ?? action.name,
      deviceId,
      // 每个设备的表单配置名称，渲染 XForm 时使用
      // formConfig: action.formConfig,
      deviceCode: action.code,
      deviceItems: createDeviceItems(action.code), // 为每个设备创建独立的安检项数据
    })
    if (success) {
      showToast('添加成功')
    }
  }
  catch (error) {
    console.error('添加设备失败:', error)
    showToast('添加设备失败')
  }
}
// 删除设备
function delDevice(index: number): void {
  showConfirmDialog({
    title: '确定要删除设备？',
    message: '删除后不可恢复',
    confirmButtonText: '删除',
    cancelButtonText: '取消',
  }).then(() => {
    const dev = devices.value[index]
    const deviceId = dev?.deviceId
    removeDevice(index)
    if (deviceId) {
      ;(emit as any)('device-deleted', deviceId, props.row.itemname)
    }
  }).catch(() => {
    // 用户取消删除
  })
}

// 同步设备数据并触发value-change事件
async function syncDeviceData(deviceId: string, data: any, defectPaths: any): Promise<void> {
  const device = devices.value.find((dev: any) => dev.deviceId === deviceId)
  if (device && device.deviceItems) {
    device.deviceItems.forEach((item: any) => {
      const incoming = data?.[item.itemname]
      if (incoming !== undefined) {
        const nextValue = (incoming && typeof incoming === 'object' && 'value' in incoming) ? (incoming as any).value : incoming
        item.value = nextValue
        // 检查是否是隐患
        if (Array.isArray(item.options) && item.options.length > 0) {
          const result = item.options.find((opt: any) => opt.data === item.value)
          if (result && result.isdefect) {
            item.f_is_defect = true
            item.level = result.level
            item.f_process_mode = result.processMode
            item.defectdes = result.defectdes
            // 设置隐患照片路径
            if (defectPaths) {
              item.f_defect_paths = defectPaths
            }
          }
        }
        // 若上游已组织隐患字段（优先使用上游，便于回更/统一）
        if (incoming && typeof incoming === 'object') {
          const src: any = incoming
          if (src.f_is_defect !== undefined)
            item.f_is_defect = !!src.f_is_defect
          if (src.level !== undefined)
            item.level = src.level
          if (src.f_process_mode !== undefined)
            item.f_process_mode = src.f_process_mode
          if (src.defectdes !== undefined)
            item.defectdes = src.defectdes
          if (src.f_defect_paths !== undefined)
            item.f_defect_paths = src.f_defect_paths
        }
        // 触发value-change事件
        ;(emit as any)('value-change', null, null, item, { deviceId: device.deviceId, deviceType: device.f_devices_type, groupName: props.row.itemname })
      }
    })
  }

  // 强制重新挂载安检项区域（你之前在 successFileList 用 showConfig 的同类方案）
  // 避免程序化写入 f_defect_paths 后 UI 不回显
  securityItemsRenderKey.value++
  await nextTick()
}

// 暴露给父组件的方法
const exposeObj: DeviceFormExposedMethods = {
  getFormData,
  resetForm,
  validate,
  formGroupName: props.formGroupName,
  addDeviceByName,
  getDeviceDetailsByName,
  syncDeviceData,
}

defineExpose(exposeObj)

onMounted(() => {
  getConfigByName('devicesTypeDic', (result) => {
    deviceTypes.value = result.value.map(d => ({ name: d.label, value: d.value, formConfig: d.formConfig, code: d.code, icon: d.icon, userType: d.userType }))
    // 根据用户类型过滤设备类型
    const list = deviceTypes.value
    const userType = props.userDetail?.userinfo?.f_user_type
    if (list?.length && list[0]?.userType && userType != null) {
      deviceTypes.value = list.filter(
        d => Array.isArray(d.userType) && d.userType.includes(userType),
      )
    }
    props.setRef(exposeObj)
    // 初始化时确保每个设备都有独立的安检项数据
    ensureDeviceItems()

    // 如果上层传入了已组织好的设备数据（devicesData），则按要求初始化
    try {
      const incoming = (props as any)?.row?.deviceData
      if (Array.isArray(incoming) && incoming.length > 0) {
      // 清空当前设备列表，使用传入数据重建
        resetDevices()

        incoming.forEach((d: any) => {
          const deviceId = d?.deviceId || `device_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`
          // 优先使用入参中的 code，其次通过设备类型到 props.deviceTypes 中匹配获取 code
          const matchedType = (Array.isArray(deviceTypes.value) ? deviceTypes.value : [])
            .find((a: any) => a?.value === d.f_devices_type)
          const dCode = matchedType?.code
          // 1) 先新增一条空设备，内部会创建 deviceItems 的默认副本
          addDevice(userInfo, {
            f_devices_type: d.f_devices_type,
            deviceId,
            deviceCode: dCode,
            deviceItems: createDeviceItems(dCode),
          })
          // 2) 拿到刚创建的设备引用
          const created = (devices.value || [])[devices.value.length - 1]
          if (!created)
            return
          // 3) 合并基础字段（不覆盖 deviceItems）
          const { items: _omitItems, deviceItems: _omitDeviceItems, ...rest } = d || {}
          Object.assign(created, rest)

          // 4) 从传入数据中获取源安检项数组
          const srcItems = Array.isArray(d?.items)
            ? d.items
            : (Array.isArray(d?.deviceItems) ? d.deviceItems : [])
          // 5) 按 itemname 匹配并回填 value / f_defect_paths / f_process_mode
          if (Array.isArray(created.deviceItems) && Array.isArray(srcItems)) {
            created.deviceItems.forEach((di: any) => {
              const s = srcItems.find((si: any) => (si?.itemname || si?.itemName) === di?.itemname)
              if (!s)
                return
              if (s.value !== undefined && s.value !== null) {
                di.value = Array.isArray(s.value) ? [...s.value] : s.value
                if (['radio', 'selector', 'checkbox', 'multipleSelect'].includes(di.type)) {
                  const opt = di.options.find(option => option.data === di.value)
                  di.f_is_defect = opt.isdefect
                  di.aging = opt.aging
                  di.level = opt.level
                  di.defectdes = opt.defectdes
                  di.f_process_mode = opt.processMode
                }
              }
              if (Array.isArray(s.f_defect_paths))
                di.f_defect_paths = [...s.f_defect_paths]
              if (s.f_process_mode !== undefined) {
                di.f_process_mode = s.f_process_mode
              }
              if (Array.isArray(s.f_process_paths))
                di.f_process_paths = [...s.f_process_paths]
              // 回填转维修相关数据
              if (s.f_handling_type !== undefined) {
                di.f_handling_type = s.f_handling_type
              }
              if (s.f_dispatch_dept !== undefined) {
                di.f_dispatch_dept = s.f_dispatch_dept
              }
              if (s.f_dispatch_dept_name !== undefined) {
                di.f_dispatch_dept_name = s.f_dispatch_dept_name
              }
              if (s.f_repairman !== undefined) {
                di.f_repairman = s.f_repairman
              }
              if (s.f_repairman_name !== undefined) {
                di.f_repairman_name = s.f_repairman_name
              }
              ;(emit as any)('value-change', null, null, di, { deviceId: created.deviceId, deviceType: created.f_devices_type, groupName: props.row.itemname })
            })
          }
        })
      }
    }
    catch (e) {
      console.warn('devicesData 初始化失败：', e)
    }
  }, 'af-safecheck')
  getConfigByName('SafeCheckConfig', (configData) => {
    safeConfig.value = configData
  }, 'af-safecheck')
})

onBeforeUnmount(() => {
  props.removeRef(exposeObj)
  stopWatchDevicesLength()
  stopWatchDevices()
  // 清空所有 ref，防止组件实例无法被 GC
  xFormRefs.value = []
  securityFormRefs.value = []
})
</script>

<template>
  <div class="device-page">
    <!-- 错误提示 -->
    <div v-if="error" class="error-message">
      <VanNoticeBar type="danger" :text="error" />
    </div>

    <div v-if="!isViewMode" class="add-button-container">
      <VanButton class="van-text-lg" type="default" block icon="plus" @click="selectDevice">
        添加设备
      </VanButton>
    </div>

    <div v-if="devices.length === 0" class="empty-list">
      <VanEmpty :description="isViewMode ? '暂无设备数据' : '暂无设备，请添加'" />
    </div>

    <div class="device-list" style="display: flex; flex-direction: column-reverse;">
      <div
        v-for="(item, index) in devices"
        :key="item?.deviceId || item"
        class="device-item"
      >
        <VanCellGroup inset class="device-card">
          <VanCell class="device-header" @click="toggleCollapse(index)">
            <template #title>
              <VanIcon :name="deviceTypes.find(a => a.name === item.f_devices_type)?.icon || 'list-switching'" color="#1989fa" size="22" />
              <span class="devicesFormTitle"># {{ index + 1 }} {{ item.f_devices_type || '设备' }}</span>
            </template>
            <template #right-icon>
              <VanIcon v-if="!isViewMode" name="delete" color="#ee0a24" @click.stop="delDevice(index)" />
            </template>
          </VanCell>
          <div v-show="expandedStates[index]" class="device-content">
            <XForm
              :ref="(el) => { if (el) xFormRefs[index] = el }"
              mode="新增"
              :form-readonly="props.isViewMode"
              :is-async-upload="true"
              :config-name="getDeviceFormConfig(item.f_devices_type)"
              :service-name="getDeviceServiceName(item.f_devices_type)"
              :form-data="item"
              :is-group-form="true"
            />
          </div>
          <!-- 安检项渲染区域 -->
          <div
            v-if="item.deviceItems && Array.isArray(item.deviceItems) && item.deviceItems.length > 0"
            v-show="expandedStates[index]"
            :key="`${item.deviceId || index}_${securityItemsRenderKey}`"
            class="security-items"
          >
            <VanForm :ref="(el) => { if (el) securityFormRefs[index] = el }">
              <SecurityFormItem
                :safe-config="safeConfig"
                :show-title="false"
                :row="{ itemname: item.f_devices_type, items: item.deviceItems }"
                :is-read-only="props.isViewMode"
                @value-change="(selVal, selObj, currentVal) => {
                  if (!isViewMode) {
                    // 值已经直接存储在 item.deviceItems 中，无需额外处理
                    ;(emit as any)('value-change', selVal, selObj, currentVal, { deviceId: item.deviceId, deviceType: item.f_devices_type, groupName: props.row.itemname })
                  }
                }"
                @process-mode-change="(securityItem, selVal, selObj) => {
                  if (!isViewMode) {
                    // 处理方式已经直接存储在 item.deviceItems 中，无需额外处理
                    // 否则无法通过校验
                    securityItem.f_process_mode = selVal
                    ;(emit as any)('process-mode-change', securityItem, selVal, selObj, index)
                  }
                }"
                @camera-view-change="(list, securityItem) => {
                  if (!isViewMode) {
                    // 照片列表已经直接存储在 item.deviceItems 中，无需额外处理
                    // 否则无法通过校验
                    securityItem.f_defect_paths = Array.isArray(list) ? list : []
                    ;(emit as any)('camera-view-change', list, securityItem, index)
                  }
                }"
                @photo-quality-change="(type: string) => emit('photoQualityChange', type)"
              />
            </VanForm>
          </div>
        </VanCellGroup>
      </div>
    </div>
    <!-- 设备类型选择弹窗 -->
    <VanActionSheet
      v-model:show="showTypeSheet"
      :actions="deviceTypes"
      cancel-text="取消"
      close-on-click-action
      @select="onTypeSelected"
    />
  </div>
</template>

<style scoped lang="less">
.device-page {
  background: #ffffff;
  padding: 12px;
}

.error-message {
  margin-bottom: 16px;
}

.add-button-container {
  padding: 0 0 12px 0;
  button {
    border-color: rgb(24 144 255);
    color: rgb(24 144 255);
  }
}

.device-list {
  display: flex;
  flex-direction: column;
  gap: 16px; // 设备之间的间隙
  .device-item {
    margin: 0;
    padding: 0;
  }
}

.device-card {
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.device-header {
  display: flex;
  align-items: center;
  :deep(.van-cell__title) {
    color: #fff;
  }

  :deep(.van-icon) {
    color: #fff;

    &.van-icon-delete {
      color: #ee0a24 !important;
    }
  }
}

.device-content {
  padding: 0;
  background: #fff;
}

.devicesFormTitle {
  font-size: 16px;
  font-weight: bold;
  // color: #336bf1;
}

.empty-list {
  margin: 40px 0;
  text-align: center;
}

/* 安检项样式 */
.security-items {
  background: #f8f9fa;
}

.security-title {
  font-size: 14px;
  font-weight: 600;
  color: #333;
  margin-bottom: 12px;
  padding-left: 8px;
  border-left: 3px solid #336bf1;
}
</style>
