<script setup lang="ts">
import { useTableComponents } from '@/components/ZmTable/useTableComponents'
import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
import { IotMainWorkOrderApi } from '@/api/pms/iotmainworkorder'
import { useUserStore } from '@/store/modules/user'
import { DICT_TYPE } from '@/utils/dict'
import download from '@/utils/download'
import DeviceAlarmBomList from '@/views/pms/iotmainworkorder/DeviceAlarmBomList.vue'

defineOptions({ name: 'IotDeviceMainAlarm' })

type DeviceMainAlarmRow = IotDeviceVO & {
  mainDistance?: string | number | null
  workOrderId?: number
  planId?: number
  responsibleNames?: string
}

interface QueryParams extends PageParam {
  deptId?: number
  deviceCode?: string
  deviceName?: string
  brand?: string
  model?: string | number
  deviceStatus?: string
  assetProperty?: string
  picUrl?: string
  remark?: string
  manufacturerId?: number
  supplierId?: number
  manDate?: string[]
  nameplate?: string
  expires?: number
  plPrice?: number
  plDate?: string[]
  plYear?: number
  plStartDate?: string[]
  plMonthed?: number
  plAmounted?: number
  remainAmount?: number
  infoId?: number
  infoType?: string
  infoName?: string
  infoRemark?: string
  infoUrl?: string
  templateJson?: string
  creator?: string
  setFlag?: string
}

const { t } = useI18n()
const { push } = useRouter()
const { ZmTable, ZmTableColumn } = useTableComponents<DeviceMainAlarmRow>()

const rootDeptId = 156
const deptId = useUserStore().getUser.deptId || rootDeptId

const initQuery: QueryParams = {
  pageNo: 1,
  pageSize: 10,
  deptId: undefined,
  deviceCode: undefined,
  deviceName: undefined,
  brand: undefined,
  model: undefined,
  deviceStatus: undefined,
  assetProperty: undefined,
  picUrl: undefined,
  remark: undefined,
  manufacturerId: undefined,
  supplierId: undefined,
  manDate: [],
  nameplate: undefined,
  expires: undefined,
  plPrice: undefined,
  plDate: [],
  plYear: undefined,
  plStartDate: [],
  plMonthed: undefined,
  plAmounted: undefined,
  remainAmount: undefined,
  infoId: undefined,
  infoType: undefined,
  infoName: undefined,
  infoRemark: undefined,
  infoUrl: undefined,
  templateJson: undefined,
  creator: undefined,
  setFlag: ''
}

const queryParams = reactive<QueryParams>({ ...initQuery })
const queryFormRef = ref()
const loading = ref(false)
const exportLoading = ref(false)
const list = ref<DeviceMainAlarmRow[]>([])
const total = ref(0)
const flag = ref()
const modelFormRef = ref()

const showRunTime = computed(() => {
  return list.value.some((item) => Boolean(item.totalRunTime))
})

const showMileage = computed(() => {
  return list.value.some((item) => Boolean(item.totalMileage))
})

const showMultiAttrs = computed(() => {
  const values = list.value
    .map((item) => item.multiAttrsTotalRuntime)
    .concat(list.value.map((item) => item.multiAttrsTotalMileage))
    .flatMap((item) => Object.values(item ?? {}))

  return values.some((item) => Boolean(item))
})

const getList = async () => {
  loading.value = true
  try {
    const data = await IotMainWorkOrderApi.deviceMainDistances(queryParams)
    list.value = data.list
    total.value = data.total
  } finally {
    loading.value = false
  }
}

const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

const resetQuery = () => {
  Object.assign(queryParams, { ...initQuery })
  queryFormRef.value?.resetFields()
  handleQuery()
}

const handleSizeChange = (val: number) => {
  queryParams.pageSize = val
  handleQuery()
}

const handleCurrentChange = (val: number) => {
  queryParams.pageNo = val
  getList()
}

const handleDeptNodeClick = async (row: Tree) => {
  queryParams.deptId = row.id
  queryParams.pageNo = 1
  await getList()
}

const parseDistanceNumber = (distance: number | string | null | undefined) => {
  if (distance === null || distance === undefined || distance === '') return undefined
  if (typeof distance === 'number') return distance
  const numericPart = distance.match(/[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?/)?.[0]
  return numericPart ? Number(numericPart) : undefined
}

const getDistanceClass = (distance: number | string | null | undefined) => {
  const value = parseDistanceNumber(distance)
  if (value === undefined || value === 0) return ''
  return value < 0 ? 'negative-distance' : 'positive-distance'
}

const hasMaintenancePlan = (mainDistance: unknown) => {
  return mainDistance !== null && mainDistance !== undefined && mainDistance !== ''
}

const handleDetail = (id: number) => {
  push({ name: 'DeviceDetailInfo', params: { id } })
}

const openBomForm = async (row: DeviceMainAlarmRow) => {
  const deviceInfo = {
    deviceId: row.id,
    deviceCode: row.deviceCode,
    deviceName: row.deviceName,
    model: row.model
  }

  if (row.workOrderId) {
    flag.value = 'workOrder'
    modelFormRef.value?.open(row.workOrderId, flag.value, row.id)
  } else if (row.planId) {
    flag.value = 'plan'
    modelFormRef.value?.open(row.planId, flag.value, deviceInfo)
  }
}

const handleExport = async () => {
  exportLoading.value = true
  try {
    const data = await IotDeviceApi.exportIotDeviceMainAlarm(queryParams)
    download.excel(data, '保养查询.xls')
  } finally {
    exportLoading.value = false
  }
}

onMounted(() => {
  getList()
})
</script>

<template>
  <div
    class="device-main-alarm-page grid grid-cols-[auto_1fr] grid-rows-[auto_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]">
    <DeptTreeSelect
      :top-id="rootDeptId"
      :deptId="deptId"
      v-model="queryParams.deptId"
      :init-select="false"
      :show-title="false"
      request-api="getSimpleDeptList"
      class="device-main-alarm-tree row-span-2"
      @node-click="handleDeptNodeClick" />

    <el-form
      ref="queryFormRef"
      :model="queryParams"
      size="default"
      label-width="80px"
      class="device-main-alarm-query bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-6 py-3 min-w-0">
      <div class="query-row">
        <el-form-item :label="t('iotDevice.code')" prop="deviceCode">
          <el-input
            v-model="queryParams.deviceCode"
            :placeholder="t('iotDevice.codeHolder')"
            clearable
            class="query-control"
            @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item :label="t('iotDevice.name')" prop="deviceName">
          <el-input
            v-model="queryParams.deviceName"
            :placeholder="t('iotDevice.nameHolder')"
            clearable
            class="query-control"
            @keyup.enter="handleQuery" />
        </el-form-item>
      </div>

      <el-form-item class="query-actions">
        <el-button type="primary" @click="handleQuery">
          <Icon icon="ep:search" class="mr-5px" />{{ t('file.search') }}
        </el-button>
        <el-button @click="resetQuery">
          <Icon icon="ep:refresh" class="mr-5px" />{{ t('file.reset') }}
        </el-button>
        <el-button
          type="success"
          plain
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['rq:iot-device:export']">
          <Icon icon="ep:download" class="mr-5px" />导出
        </el-button>
      </el-form-item>
    </el-form>

    <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg flex flex-col p-4 min-w-0 min-h-0">
      <div class="flex-1 relative min-h-0">
        <el-auto-resizer class="absolute">
          <template #default="{ width, height }">
            <ZmTable
              :data="list"
              :loading="loading"
              :width="width"
              :height="height"
              :max-height="height"
              show-border>
              <ZmTableColumn
                type="index"
                :label="t('monitor.serial')"
                :width="70"
                fixed="left"
                hide-in-column-settings />
              <ZmTableColumn prop="deviceCode" :label="t('iotDevice.code')" fixed="left" />
              <ZmTableColumn prop="deviceName" :label="t('iotDevice.name')" fixed="left">
                <template #default="{ row }">
                  <el-link :underline="false" type="primary" @click="handleDetail(row.id)">
                    {{ row.deviceName }}
                  </el-link>
                </template>
              </ZmTableColumn>
              <ZmTableColumn :label="t('bomList.serviceDue')" min-width="140">
                <template #default="{ row }">
                  <template v-if="hasMaintenancePlan(row.mainDistance)">
                    <span :class="getDistanceClass(row.mainDistance)">
                      {{ row.mainDistance }}
                    </span>
                  </template>
                  <span v-else>无保养计划</span>
                </template>
              </ZmTableColumn>
              <ZmTableColumn
                v-if="showRunTime"
                prop="totalRunTime"
                label="累计运行时长H"
                min-width="140" />
              <ZmTableColumn
                v-if="showMileage"
                prop="totalMileage"
                label="累计运行里程KM"
                min-width="150" />
              <ZmTableColumn v-if="showMultiAttrs" label="多属性累计值" min-width="200">
                <template #default="{ row }">
                  <template v-for="(value, key) in row.multiAttrsTotalRuntime" :key="key">
                    <span v-if="value && key">{{ key }}: {{ value }}&nbsp;&nbsp;</span>
                  </template>
                  <template v-for="(value, key) in row.multiAttrsTotalMileage" :key="key">
                    <span v-if="value && key">{{ key }}: {{ value }}&nbsp;&nbsp;</span>
                  </template>
                </template>
              </ZmTableColumn>
              <ZmTableColumn prop="deptName" :label="t('iotDevice.dept')" />
              <ZmTableColumn prop="responsibleNames" :label="t('devicePerson.rp')" />
              <ZmTableColumn prop="deviceStatus" :label="t('monitor.status')">
                <template #default="{ row }">
                  <dict-tag :type="DICT_TYPE.PMS_DEVICE_STATUS" :value="row.deviceStatus" />
                </template>
              </ZmTableColumn>
              <ZmTableColumn :label="t('operationFill.status')" min-width="150">
                <template #default="{ row }">
                  <span v-if="row.shouldWorkOrder && row.runningWorkOrder">
                    {{ t('mainPlan.generatedNotExecuted') }}
                  </span>
                  <span v-else-if="row.shouldWorkOrder && !row.runningWorkOrder">
                    {{ t('mainPlan.notGenerated') }}
                  </span>
                  <span v-else>-</span>
                </template>
              </ZmTableColumn>
              <ZmTableColumn :label="t('monitor.operation')" width="80" fixed="right" action>
                <template #default="{ row }">
                  <el-button
                    v-if="hasMaintenancePlan(row.mainDistance)"
                    link
                    type="primary"
                    @click="openBomForm(row)"
                    v-hasPermi="['rq:iot-device:query']">
                    {{ t('monitor.details') }}
                  </el-button>
                </template>
              </ZmTableColumn>
            </ZmTable>
          </template>
        </el-auto-resizer>
      </div>

      <div class="h-8 mt-2 flex items-center justify-end">
        <el-pagination
          v-show="total > 0"
          size="default"
          :current-page="queryParams.pageNo"
          :page-size="queryParams.pageSize"
          :background="true"
          :page-sizes="[10, 20, 30, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange" />
      </div>
    </div>
  </div>

  <DeviceAlarmBomList ref="modelFormRef" :flag="flag" />
</template>

<style scoped>
.device-main-alarm-query {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
}

.query-row {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 24px;
  min-width: 0;
}

.query-row :deep(.el-form-item__label) {
  white-space: nowrap;
}

.query-actions {
  flex: 0 0 auto;
}

.query-actions :deep(.el-form-item__content) {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
}

.query-actions :deep(.el-button) {
  margin-left: 0;
}

.query-control {
  width: 200px;
}

.positive-distance {
  display: inline-block;
  padding: 2px 8px;
  color: #67c23a;
  background-color: rgb(103 194 58 / 10%);
  border-radius: 4px;
}

.negative-distance {
  display: inline-block;
  padding: 2px 8px;
  color: #f56c6c;
  background-color: rgb(245 108 108 / 10%);
  border-radius: 4px;
}

:deep(.el-form-item) {
  margin-bottom: 0;
}

@media (width >= 2200px) {
  .device-main-alarm-query,
  .query-row {
    flex-wrap: nowrap;
  }
}

@media (width <= 1500px) {
  .device-main-alarm-query,
  .query-row {
    gap: 12px 18px;
  }

  .query-control {
    width: 180px;
  }
}

@media (width <= 1200px) {
  .device-main-alarm-page {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto minmax(480px, 1fr);
    height: auto;
    min-height: calc(
      100vh - 20px - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height)
    );
  }

  :deep(.device-main-alarm-tree) {
    grid-row: auto !important;
    width: 100% !important;
    height: 320px !important;
    min-width: 0 !important;
  }

  .query-actions {
    width: 100%;
  }
}

@media (width <= 768px) {
  .device-main-alarm-query {
    padding: 12px;
  }

  .query-row,
  .query-row :deep(.el-form-item),
  .query-actions {
    width: 100%;
  }

  .query-control {
    width: 100%;
  }

  .query-actions :deep(.el-form-item__content) {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    width: 100%;
  }

  .query-actions :deep(.el-button) {
    width: 100%;
    margin-left: 0;
  }
}
</style>
