<template>
  <ContentWrap>
    <!-- 搜索工作栏 -->
    <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
      <el-form-item :label="t('DataCollection.DeviceModel.code')" prop="code">
        <el-input
          v-model="queryParams.code"
          :placeholder="t('DataCollection.DeviceModel.placeholderCode')"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px" />
      </el-form-item>
      <el-form-item :label="t('DataCollection.DeviceModel.name')" prop="name">
        <el-input
          v-model="queryParams.name"
          :placeholder="t('DataCollection.DeviceModel.placeholderName')"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px" />
      </el-form-item>

      <el-form-item :label="t('DataCollection.DeviceModel.protocol')" prop="protocol">
        <el-select
          v-model="queryParams.protocol"
          :placeholder="t('DataCollection.DeviceModel.placeholderProtocol')"
          clearable
          class="!w-240px">
          <el-option
v-for="dict in getStrDictOptions(DICT_TYPE.IOT_PROTOCOL)" :key="dict.value" :label="dict.label"
            :value="dict.value" />
        </el-select>
      </el-form-item>

      <!-- <el-form-item label="备注" prop="remark">
        <el-input
          v-model="queryParams.remark"
          placeholder="请输入备注"
          clearable
          @keyup.enter="handleQuery"
          class="!w-240px"
        />
      </el-form-item> -->
      <!-- <el-form-item label="创建时间" prop="createTime">
        <el-date-picker
          v-model="queryParams.createTime"
          value-format="YYYY-MM-DD HH:mm:ss"
          type="daterange"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
          class="!w-220px"
        />
      </el-form-item> -->
      <el-form-item>
        <el-button @click="handleQuery">
          <Icon icon="ep:search" class="mr-5px" /> {{ t('DataCollection.DeviceModel.search') }}
        </el-button>
        <el-button @click="resetQuery">
          <Icon icon="ep:refresh" class="mr-5px" /> {{ t('DataCollection.DeviceModel.reset') }}
        </el-button>
        <el-button type="primary" plain @click="openForm('create')" v-hasPermi="['iot:device-model:create']">
          <Icon icon="ep:plus" class="mr-5px" /> {{ t('DataCollection.DeviceModel.create') }}
        </el-button>
        <el-button type="danger" plain @click="handleBatchDelete" v-hasPermi="['iot:device-model:delete']">
          <Icon icon="ep:delete" class="mr-5px" /> {{ t('DataCollection.DeviceModel.batchDelete') }}
        </el-button>
        <el-button
type="success" plain @click="handleExport" :loading="exportLoading"
          v-hasPermi="['iot:device-model:export']">
          <Icon icon="ep:download" class="mr-5px" /> {{ t('DataCollection.DeviceModel.export') }}
        </el-button>
      </el-form-item>
    </el-form>
  </ContentWrap>
  <!-- 列表 -->
  <ContentWrap>
    <el-table
      ref="tableRef" v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"
      highlight-current-row row-key="id" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" reserve-selection />
      <el-table-column :label="t('DataCollection.DeviceModel.code')" align="center" prop="code" />
      <el-table-column :label="t('DataCollection.DeviceModel.name')" align="center" prop="name" />
      <el-table-column align="center" :label="t('DataCollection.DeviceModel.protocol')" prop="protocol" min-width="150">
        <template #default="scope">
          <dict-tag :type="DICT_TYPE.IOT_PROTOCOL" :value="scope.row.protocol" />
        </template>
      </el-table-column>
      <el-table-column :label="t('DataCollection.DeviceModel.remark')" align="center" prop="remark" />
      <!-- <el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" /> -->
      <el-table-column :label="t('DataCollection.DeviceModel.operate')" align="center" min-width="120px">
        <template #default="scope">
          <el-button link type="primary" @click.stop="handleShowAttribute(scope.row)">{{ t('DataCollection.DeviceModel.attributeModuleName') }}</el-button>
          <el-button link type="primary" @click="handleCopy(scope.row.id)" v-hasPermi="['iot:device-model:create']">
            {{ t('action.copy') }}
          </el-button>
          <el-button
link type="primary" @click="openForm('update', scope.row.id)"
            v-hasPermi="['iot:device-model:update']">
            {{ t('action.edit') }}
          </el-button>
          <el-button link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['iot:device-model:delete']">
            {{ t('action.del') }}
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <Pagination
      :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
      @pagination="getList" />
  </ContentWrap>

  <ContentWrap>
    <template v-if="attributeModelId">
      <div class="mb-10px text-sm text-gray-500">
        {{ t('DataCollection.DeviceModel.moduleName') }}：<span class="font-medium text-gray-700">{{ attributeModelName || '-' }}</span>
      </div>
      <el-tabs model-value="modelAttribute">
        <el-tab-pane :label="t('DataCollection.DeviceModel.attributeModuleName')" name="modelAttribute">
          <ModelAttributeList :id="attributeModelId" />
        </el-tab-pane>
        <el-tab-pane :label="t('DataCollection.DeviceModel.ruleTabLabel')" name="modelRule">
          <el-form class="-mb-15px" :model="ruleQueryParams" ref="ruleQueryFormRef" :inline="true" label-width="120px">
            <el-form-item :label="t('DataCollection.DeviceModel.ruleIdentifier')" prop="identifier">
              <el-input
                v-model="ruleQueryParams.identifier"
                :placeholder="t('DataCollection.DeviceModel.ruleSearchIdentifierPlaceholder')"
                clearable
                @keyup.enter="handleRuleQuery"
                class="!w-200px"
              />
            </el-form-item>
            <el-form-item :label="t('DataCollection.DeviceModel.ruleFieldName')" prop="fieldName">
              <el-input
                v-model="ruleQueryParams.fieldName"
                :placeholder="t('DataCollection.DeviceModel.ruleSearchFieldNamePlaceholder')"
                clearable
                @keyup.enter="handleRuleQuery"
                class="!w-200px"
              />
            </el-form-item>
            <el-form-item :label="t('DataCollection.DeviceModel.ruleDefaultValue')" prop="defaultValue">
              <el-input
                v-model="ruleQueryParams.defaultValue"
                :placeholder="t('DataCollection.DeviceModel.ruleSearchDefaultValuePlaceholder')"
                clearable
                @keyup.enter="handleRuleQuery"
                class="!w-200px"
              />
            </el-form-item>
            <el-form-item>
              <el-button @click="handleRuleQuery">
                <Icon icon="ep:search" class="mr-5px" /> {{ t('DataCollection.DeviceModel.ruleSearch') }}
              </el-button>
              <el-button @click="resetRuleQuery">
                <Icon icon="ep:refresh" class="mr-5px" /> {{ t('DataCollection.DeviceModel.ruleReset') }}
              </el-button>
            </el-form-item>
          </el-form>

          <div class="mb-10px text-right">
            <el-button type="primary" @click="openCreateRuleForm">
              {{ t('DataCollection.DeviceModel.ruleCreateButton') }}
            </el-button>
          </div>

          <el-table
            v-loading="ruleLoading"
            :data="ruleList"
            :stripe="true"
            :show-overflow-tooltip="true"
            row-key="id"
          >
            <el-table-column :label="t('DataCollection.DeviceModel.ruleIdentifier')" align="center" prop="identifier" />
            <el-table-column :label="t('DataCollection.DeviceModel.ruleFieldName')" align="center" prop="fieldName" />
            <el-table-column :label="t('DataCollection.DeviceModel.ruleFieldRule')" align="center" prop="fieldRule" />
            <el-table-column :label="t('DataCollection.DeviceModel.ruleDefaultValue')" align="center" prop="defaultValue" />
            <el-table-column :label="t('DataCollection.DeviceModel.ruleCreateTime')" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
            <el-table-column :label="t('DataCollection.DeviceModel.ruleOperate')" align="center" width="160px">
              <template #default="scope">
                <el-button link type="primary" @click="openRuleForm(scope.row)">
                  {{ t('DataCollection.DeviceModel.ruleEditRuleButton') }}
                </el-button>
                <el-button
                  v-if="(scope.row.identifier || '').toString().toUpperCase() === 'ALARM'"
                  link
                  type="danger"
                  @click="handleRuleDelete(scope.row.id)"
                >
                  {{ t('DataCollection.DeviceModel.ruleDeleteRuleButton') }}
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          <Pagination
            :total="ruleTotal"
            v-model:page="ruleQueryParams.pageNo"
            v-model:limit="ruleQueryParams.pageSize"
            @pagination="getRuleList"
          />
          <el-dialog v-model="ruleDialogVisible" :title="t('DataCollection.DeviceModel.ruleDialogTitle')" width="880px" draggable>
            <el-form :model="ruleForm" ref="ruleFormRef" label-width="120px">
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogIdentifier')">
                <el-input v-model="ruleForm.identifier" disabled />
              </el-form-item>
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogFieldName')">
                <el-input v-model="ruleForm.fieldName" disabled />
              </el-form-item>
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogDefaultValue')">
                <el-input v-model="ruleForm.defaultValue" disabled />
              </el-form-item>
              <el-form-item
                v-if="(ruleForm.identifier || '').toString().toUpperCase() === 'ALARM'"
                :label="t('DataCollection.DeviceModel.ruleDialogAlarmLevel')"
              >
                <el-select
                  v-model="ruleForm.alarmLevel"
                  :placeholder="t('DataCollection.DeviceModel.ruleDialogAlarmLevelPlaceholder')"
                >
                  <el-option
                    v-for="dict in getStrDictOptions(DICT_TYPE.IOT_ALARM_REGISTRATION)"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  />
                </el-select>
              </el-form-item>

              <div class="flex flex-col w-full">
                <div class="border border-gray-200 dark:border-gray-600 rounded-md py-12px">
                  <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogFieldRule')">
                    <el-select
                      v-model="ruleForm.fieldRule"
                      :placeholder="t('DataCollection.DeviceModel.ruleDialogFieldRulePlaceholder')"
                      class="!w-240px"
                      :disabled="!currentRuleOptions.length"
                    >
                      <el-option
                        v-for="item in currentRuleOptions"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                        :disabled="isRuleDisabled(item.value, ruleForm.fieldRule)"
                      />
                    </el-select>
                  </el-form-item>
                  <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogRule')">
                    <div class="flex items-center gap-8px">
                      <el-select
                        v-model="ruleForm.ruleAttributeId"
                        :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleAttributePlaceholder')"
                        class="!w-240px"
                      >
                        <el-option
                          v-for="item in ruleAttributeOptions"
                          :key="item.id"
                          :label="item.attributeName || item.attributeCode"
                          :value="item.id"
                        />
                      </el-select>
                      <el-select
                        v-model="ruleForm.ruleOperator"
                        :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleOperatorPlaceholder')"
                        class="!w-160px"
                      >
                        <el-option
                          v-for="opt in ruleOperatorOptions"
                          :key="opt.value"
                          :label="opt.label"
                          :value="opt.value"
                        />
                      </el-select>
                      <el-input
                        v-if="ruleForm.ruleOperator !== 'TRUE' && ruleForm.ruleOperator !== 'FALSE'"
                        v-model="ruleForm.ruleValue"
                        :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleValuePlaceholder')"
                        class="!w-200px"
                      />
                    </div>
                  </el-form-item>
                </div>

                <div
                  v-for="(item, index) in extraPointRules"
                  :key="index"
                  class="border border-gray-200 dark:border-gray-600 rounded-md px-16px py-12px"
                >
                  <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogFieldRule')">
                    <el-select
                      v-model="item.rule"
                      :placeholder="t('DataCollection.DeviceModel.ruleDialogFieldRulePlaceholder')"
                      class="!w-240px"
                    >
                      <el-option
                        v-for="opt in currentRuleOptions"
                        :key="opt.value"
                        :label="opt.label"
                        :value="opt.value"
                        :disabled="isRuleDisabled(opt.value, item.rule)"
                      />
                    </el-select>
                  </el-form-item>
                  <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogRule')">
                    <div class="flex items-center gap-8px">
                      <el-select
                        v-model="item.id"
                        :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleAttributePlaceholder')"
                        class="!w-240px"
                      >
                        <el-option
                          v-for="attr in ruleAttributeOptions"
                          :key="attr.id"
                          :label="attr.attributeName || attr.attributeCode"
                          :value="attr.id"
                        />
                      </el-select>
                      <el-select
                        v-model="item.operator"
                        :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleOperatorPlaceholder')"
                        class="!w-160px"
                      >
                        <el-option
                          v-for="opt in ruleOperatorOptions"
                          :key="opt.value"
                          :label="opt.label"
                          :value="opt.value"
                        />
                      </el-select>
                      <el-input
                        v-if="item.operator !== 'TRUE' && item.operator !== 'FALSE'"
                        v-model="item.operatorRule"
                        :placeholder="t('DataCollection.DeviceModel.ruleDialogRuleValuePlaceholder')"
                        class="!w-200px"
                      />
                      <el-button type="danger" link @click="handleRemovePointRule(index)">
                        {{ t('DataCollection.DeviceModel.ruleDeleteRuleButton') }}
                      </el-button>
                    </div>
                  </el-form-item>
                </div>

                <el-form-item v-if="isRunningIdentifier" label=" ">
                  <el-button type="primary" link @click="handleAddPointRule">
                    + {{ t('DataCollection.DeviceModel.ruleCreateButton') }}
                  </el-button>
                </el-form-item>
              </div>
            </el-form>
            <template #footer>
              <span class="dialog-footer">
                <el-button @click="ruleDialogVisible = false">{{ t('DataCollection.DeviceModel.dialogCancel') }}</el-button>
                <el-button type="primary" :loading="ruleFormLoading" @click="handleRuleSubmit">{{ t('DataCollection.DeviceModel.dialogOk') }}</el-button>
              </span>
            </template>
          </el-dialog>
          <el-dialog v-model="createRuleDialogVisible" :title="t('DataCollection.DeviceModel.ruleCreateButton')" width="520px" draggable>
            <el-form :model="createRuleForm" ref="createRuleFormRef" label-width="120px">
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogIdentifier')">
                <el-input v-model="createRuleForm.identifier" disabled />
              </el-form-item>
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogFieldName')">
                <el-input
                  v-model="createRuleForm.fieldName"
                  :placeholder="t('DataCollection.DeviceModel.ruleSearchFieldNamePlaceholder')"
                />
              </el-form-item>
              <el-form-item :label="t('DataCollection.DeviceModel.ruleDialogDefaultValue')">
                <el-input v-model="createRuleForm.defaultValue" disabled />
              </el-form-item>
            </el-form>
            <template #footer>
              <span class="dialog-footer">
                <el-button @click="createRuleDialogVisible = false">{{ t('DataCollection.DeviceModel.dialogCancel') }}</el-button>
                <el-button type="primary" :loading="createRuleFormLoading" @click="handleCreateRuleSubmit">
                  {{ t('DataCollection.DeviceModel.dialogOk') }}
                </el-button>
              </span>
            </template>
          </el-dialog>
        </el-tab-pane>
      </el-tabs>
    </template>
    <el-empty
      v-else
      :description="t('DataCollection.DeviceModel.moduleName') + t('-') + t('DataCollection.DeviceModel.attributeModuleName')"
    />
  </ContentWrap>
  <!-- 表单弹窗：添加/修改 -->
  <DeviceModelForm ref="formRef" @success="getList" />
</template>

<script setup lang="ts">
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import request from '@/config/axios'
import { DeviceModelApi, DeviceModelVO } from '@/api/iot/devicemodel'
import { DeviceModelAttributeApi, DeviceModelAttributeVO } from '@/api/iot/devicemodelattribute'
import DeviceModelForm from './DeviceModelForm.vue'
import ModelAttributeList from './components/ModelAttributeList.vue'

/** 采集设备模型 列表 */
defineOptions({ name: 'DeviceModel' })

const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化

const tableRef = ref()

const loading = ref(true) // 列表的加载中
const list = ref<DeviceModelVO[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  code: undefined,
  name: undefined,
  protocol: undefined,
  remark: undefined,
  createTime: [],
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中

const selectedIds = ref<number[]>([])
const handleSelectionChange = (rows: any[]) => {
  selectedIds.value = rows?.map((row) => row.id).filter((id) => id !== undefined) ?? []
}

/** 查询列表 */
const getList = async () => {
  loading.value = true
  try {
    const data = await DeviceModelApi.getDeviceModelPage(queryParams)
    list.value = data.list
    total.value = data.total
  } finally {
    loading.value = false
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
  formRef.value.open(type, id)
}

/** 删除按钮操作 */
const buildIdsParam = (ids: number | number[]) => {
  return Array.isArray(ids) ? ids.join(',') : String(ids)
}

const handleDelete = async (ids: number | number[]) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await DeviceModelApi.deleteDeviceModel(buildIdsParam(ids))
    message.success(t('common.delSuccess'))
    selectedIds.value = []
    tableRef.value?.clearSelection?.()
    // 刷新列表
    await getList()
  } catch { }
}

const handleBatchDelete = async () => {
  if (!selectedIds.value.length) {
    message.error('请选择需要删除的数据')
    return
  }
  await handleDelete(selectedIds.value)
}

/** 导出按钮操作 */
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const params: any = {
      ...queryParams,
      ids: selectedIds.value.length ? selectedIds.value.join(',') : undefined
    }
    const data = await DeviceModelApi.exportDeviceModel(params)
    download.excel(data, '采集设备模型.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}

const attributeModelId = ref<number | undefined>(undefined)
const attributeModelName = ref('')

const modelAttributeTabLabel = computed(() => {
  return '采集点'
})

const modelRuleTabLabel = computed(() => {
  return '点位规则'
})

interface DeviceModelRuleVO {
  id: number
  identifier: string
  fieldName: string
  fieldRule: string
  defaultValue: string
  modelId: number
  createTime?: string | number | Date
  ruleAttributeId?: number
  ruleOperator?: string
  ruleValue?: string | number
  alarmLevel?: string
}

const ruleLoading = ref(false)
const ruleList = ref<DeviceModelRuleVO[]>([])
const ruleTotal = ref(0)
const ruleQueryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  identifier: undefined as string | undefined,
  fieldName: undefined as string | undefined,
  fieldRule: undefined as string | undefined,
  defaultValue: undefined as string | undefined,
  alarmLevel: undefined as string | undefined,
  modelId: undefined as number | undefined,
})
const ruleQueryFormRef = ref()

const ruleAttributeOptions = ref<DeviceModelAttributeVO[]>([])

const getRuleList = async () => {
  if (!attributeModelId.value) return
  ruleLoading.value = true
  try {
    const params = {
      ...ruleQueryParams,
      modelId: attributeModelId.value,
    }
    const data = await request.get({ url: '/iot/device-model-rules/page', params })
    const listData = Array.isArray((data as any)?.list) ? (data as any).list : (Array.isArray(data) ? data : [])
    const totalData = (data as any)?.total ?? listData.length
    ruleList.value = listData as DeviceModelRuleVO[]
    ruleTotal.value = totalData
  } finally {
    ruleLoading.value = false
  }
}

const handleRuleQuery = () => {
  if (!attributeModelId.value) return
  ruleQueryParams.pageNo = 1
  getRuleList()
}

const resetRuleQuery = () => {
  if (!attributeModelId.value) return
  ruleQueryFormRef.value?.resetFields?.()
  handleRuleQuery()
}

const loadRuleAttributeOptions = async (modelId: number) => {
  try {
    const res = await DeviceModelAttributeApi.getDeviceModelAttributeList(modelId)
    const data = Array.isArray(res) ? res : (res as any)?.list ?? []
    ruleAttributeOptions.value = data as DeviceModelAttributeVO[]
  } catch {
    ruleAttributeOptions.value = []
  }
}

watch(
  () => attributeModelId.value,
  async (val) => {
    ruleQueryParams.modelId = val ?? undefined
    if (!val) {
      ruleList.value = []
      ruleTotal.value = 0
      ruleAttributeOptions.value = []
      return
    }
    ruleQueryParams.pageNo = 1
    await Promise.all([getRuleList(), loadRuleAttributeOptions(val)])
  }
)

const ruleDialogVisible = ref(false)
const ruleFormLoading = ref(false)
const ruleFormRef = ref()
const ruleForm = reactive<Partial<DeviceModelRuleVO>>({
  id: undefined,
  identifier: '',
  fieldName: '',
  fieldRule: '',
  defaultValue: '',
  modelId: undefined,
  ruleAttributeId: undefined,
  ruleOperator: undefined,
  ruleValue: undefined,
   alarmLevel: '',
})

const createRuleDialogVisible = ref(false)
const createRuleFormLoading = ref(false)
const createRuleFormRef = ref()
const createRuleForm = reactive({
  identifier: 'ALARM',
  fieldName: '',
  defaultValue: '报警',
})

const extraPointRules = ref<
  Array<{
    id?: number
    rule?: string
    operator?: string
    operatorRule?: string | number
  }>
>([])

const runningRuleOptions = [
  { value: '1', label: '运行' },
  { value: '2', label: '待机中（不运行、没故障）' },
  { value: '3', label: '故障中（故障且待机）' },
  { value: '4', label: '报警中（故障且运行）' },
]

const alarmRuleOptions = [
  { value: '5', label: '报警' },
]

const currentRuleOptions = computed(() => {
  const id = (ruleForm.identifier || '').toString().toUpperCase()
  if (id === 'RUNNING') return runningRuleOptions
  if (id === 'ALARM') return alarmRuleOptions
  return []
})

const isRuleDisabled = (value: string, selfRule?: string | number) => {
  if (!value) return false
  const v = String(value)
  const self = selfRule != null ? String(selfRule) : undefined
  if (self === v) return false
  if (ruleForm.fieldRule && String(ruleForm.fieldRule) === v && self !== v) return true
  if (
    extraPointRules.value.some(
      (item) => item.rule != null && String(item.rule) === v && String(item.rule) !== self
    )
  ) {
    return true
  }
  return false
}

const ruleOperatorOptions = computed(() => getStrDictOptions('czsb_rules_conditions'))

const isRunningIdentifier = computed(() => {
  return (ruleForm.identifier || '').toString().toUpperCase() === 'RUNNING'
})

const openCreateRuleForm = () => {
  if (!attributeModelId.value) {
    message.error('请先选择模型')
    return
  }
  createRuleForm.identifier = 'ALARM'
  createRuleForm.fieldName = '报警'
  createRuleForm.defaultValue = '报警'
  createRuleDialogVisible.value = true
}

const openRuleForm = async (row: DeviceModelRuleVO & { pointRulesVOList?: any[] }) => {
  const modelId = row.modelId || attributeModelId.value
  if (!modelId) {
    message.error('模型信息缺失，无法加载点位规则')
    return
  }

  await loadRuleAttributeOptions(modelId)

  ruleForm.id = row.id
  ruleForm.identifier = row.identifier
  ruleForm.fieldName = row.fieldName
  ruleForm.defaultValue = row.defaultValue
  ruleForm.modelId = row.modelId
  ruleForm.alarmLevel = row.alarmLevel

  extraPointRules.value = []

  const list = Array.isArray(row.pointRulesVOList) ? row.pointRulesVOList : []

  if (list.length) {
    const first = list[0] as any
    const firstRule = first.rule ?? row.fieldRule
    const firstAttrId = (() => {
      if (first && first.code != null) {
        const target = ruleAttributeOptions.value.find(
          (item) => item.attributeCode === first.code
        )
        return target?.id
      }
      if (first && first.id != null) return first.id
      return undefined
    })()
    ruleForm.fieldRule = firstRule as any
    ruleForm.ruleAttributeId = firstAttrId as any
    ruleForm.ruleOperator = first.operator as any
    ruleForm.ruleValue = first.operatorRule as any
    extraPointRules.value = list.slice(1).map((item: any) => ({
      id: (() => {
        if (item && item.code != null) {
          const target = ruleAttributeOptions.value.find(
            (opt) => opt.attributeCode === item.code
          )
          return target?.id
        }
        if (item && item.id != null) return item.id
        return undefined
      })(),
      rule: item.rule,
      operator: item.operator,
      operatorRule: item.operatorRule,
    }))
  } else {
    ruleForm.fieldRule = row.fieldRule
    ruleForm.ruleAttributeId = row.ruleAttributeId
    ruleForm.ruleOperator = row.ruleOperator
    ruleForm.ruleValue = row.ruleValue as any
  }

  const options = currentRuleOptions.value
  if (options.length && !options.some((item) => item.value === ruleForm.fieldRule)) {
    ruleForm.fieldRule = options[0].value
  }
  ruleDialogVisible.value = true
}

const handleRuleSubmit = async () => {
  if (!ruleForm.id) return
  try {
    ruleFormLoading.value = true
    const pointRulesVOList: any[] = []

    if (ruleForm.ruleAttributeId && ruleForm.ruleOperator) {
      const attr = ruleAttributeOptions.value.find(
        (item) => item.id === ruleForm.ruleAttributeId
      )
      if (attr && attr.attributeCode) {
      pointRulesVOList.push({
        code: attr.attributeCode,
        rule: ruleForm.fieldRule,
        operator: ruleForm.ruleOperator,
        operatorRule: ruleForm.ruleValue,
      })
      }
    }

    extraPointRules.value.forEach((item) => {
      if (!item.id || !item.operator) return
      const attr = ruleAttributeOptions.value.find((opt) => opt.id === item.id)
      if (!attr || !attr.attributeCode) return
      pointRulesVOList.push({
        code: attr.attributeCode,
        rule: item.rule ?? ruleForm.fieldRule,
        operator: item.operator,
        operatorRule: item.operatorRule,
      })
    })

    const payload = {
      id: ruleForm.id,
      identifier: ruleForm.identifier,
      fieldName: ruleForm.fieldName,
      defaultValue: ruleForm.defaultValue,
      modelId: ruleForm.modelId,
      alarmLevel: ruleForm.alarmLevel,
      pointRulesVOList,
    }

    await request.put({ url: '/iot/device-model-rules/update', data: payload })
    message.success('保存成功')
    ruleDialogVisible.value = false
    await getRuleList()
  } finally {
    ruleFormLoading.value = false
  }
}

const handleRuleDelete = async (id: number) => {
  if (!id) return
  try {
    await message.delConfirm()
    await request.delete({ url: '/iot/device-model-rules/delete?id=' + id })
    message.success(t('common.delSuccess'))
    await getRuleList()
  } catch { }
}

const handleAddPointRule = () => {
  if (!isRunningIdentifier.value) return
  const allOptions = currentRuleOptions.value || []
  const used = new Set<string>()
  if (ruleForm.fieldRule) used.add(String(ruleForm.fieldRule))
  extraPointRules.value.forEach((item) => {
    if (item.rule != null) used.add(String(item.rule))
  })
  const next = allOptions.find((opt) => !used.has(String(opt.value)))
  if (!next) {
    message.warning('已没有可用的点位规则可选')
    return
  }
  extraPointRules.value.push({
    rule: next.value as any,
    id: undefined,
    operator: undefined,
    operatorRule: undefined,
  })
}

const handleCreateRuleSubmit = async () => {
  if (!attributeModelId.value) return
  if (!createRuleForm.fieldName) {
    message.warning('请输入名称')
    return
  }
  try {
    createRuleFormLoading.value = true
    const payload = {
      identifier: createRuleForm.identifier,
      fieldName: createRuleForm.fieldName,
      defaultValue: createRuleForm.defaultValue,
      modelId: attributeModelId.value,
    }
    await request.post({ url: '/iot/device-model-rules/create', data: payload })
    message.success('新增成功')
    createRuleDialogVisible.value = false
    await getRuleList()
  } finally {
    createRuleFormLoading.value = false
  }
}

const handleRemovePointRule = (index: number) => {
  if (index < 0 || index >= extraPointRules.value.length) return
  extraPointRules.value.splice(index, 1)
}

const handleShowAttribute = (row: any) => {
  attributeModelId.value = row?.id
  attributeModelName.value = row?.name ?? ''
}

const handleCopy = async (id: number) => {
  try {
    // 二次确认
    await message.confirm('是否复制模型?')
    await DeviceModelApi.copyDeviceModel(id)
    message.success('复制成功')
    await getList()
  } catch { }
}

/** 初始化 **/
onMounted(() => {
  getList()
})
</script>
