<template>
  <ContentWrap v-loading="formLoading" class="device-main-wrap" :body-style="{ padding: '0' }">
    <div class="device-main">
      <div class="device-media">
        <button class="device-image-frame" type="button" @click="imagePreview(defaultPicUrl)">
          <el-image :src="defaultPicUrl" class="device-image" fit="cover">
            <template #error>
              <div class="device-image__empty">
                <Icon icon="ep:picture" />
              </div>
            </template>
          </el-image>
          <span class="image-preview-mask">
            <Icon icon="ep:zoom-in" />
            <span>{{ t('action.preview') }}</span>
          </span>
        </button>
      </div>

      <div class="device-content">
        <div class="device-head">
          <div class="device-head__main">
            <div class="device-title-row">
              <h1 class="device-title">{{ formatValue(formData.deviceName) }}</h1>
              <el-tag class="device-status" effect="light" round>
                {{ statusLabel }}
              </el-tag>
            </div>
            <div class="device-subtitle">
              <Icon icon="ep:collection-tag" />
              <span>{{ assetPropertyLabel }}</span>
            </div>
          </div>
        </div>

        <div class="device-info-grid">
          <div v-for="field in mainInfoFields" :key="field.prop" class="device-info-item">
            <span class="device-info-item__label">
              <Icon :icon="field.icon" />
              {{ field.label }}
            </span>
            <strong>{{ field.value }}</strong>
          </div>
        </div>
      </div>
    </div>
  </ContentWrap>

  <ContentWrap
    v-loading="formLoading"
    class="device-detail-wrap"
    :body-style="{ padding: '0 18px 18px' }">
    <el-tabs v-model="activeName" class="device-tabs">
      <el-tab-pane :label="t('deviceInfo.basicInformation')" name="info">
        <DeviceBasicInfo :device="formData" :template-fields="templateFields" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.fileLibrary')" name="file">
        <DeviceFileLibrary
          v-if="activeName === 'file'"
          :device-id="deviceId"
          :device-name="formData.deviceName" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.deviceBOM')" name="bom">
        <DeviceBomLibrary
          v-if="activeName === 'bom'"
          :device-id="deviceId"
          :device-category-name="formData.assetClassName" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.operationRecords')" name="record">
        <DeviceOperationRecord v-if="activeName === 'record'" :device-id="deviceId" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.faultRecords')" name="failure">
        <DeviceFailureRecord v-if="activeName === 'failure'" :device-id="deviceId" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.repairRecords')" name="maintain">
        <DeviceMaintainRecord v-if="activeName === 'maintain'" :device-id="deviceId" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.maintenanceRecords')" name="maintenance">
        <DeviceMaintenanceRecord v-if="activeName === 'maintenance'" :device-id="deviceId" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.inspectionRecords')" name="inspect">
        <DeviceInspectRecord v-if="activeName === 'inspect'" :device-id="deviceId" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.transferRecords')" name="allot">
        <DeviceAllotRecord v-if="activeName === 'allot'" :device-id="deviceId" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.statusChangeRecords')" name="status">
        <DeviceStatusRecord v-if="activeName === 'status'" :device-id="deviceId" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.RPAdjustmentRecords')" name="person">
        <DevicePersonRecord v-if="activeName === 'person'" :device-id="deviceId" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.checkCert')" name="cert">
        <CheckCertificate v-if="activeName === 'cert'" :device-id="deviceId" />
      </el-tab-pane>
      <el-tab-pane :label="t('deviceInfo.associationDevice')" name="association">
        <DeviceAssociationRecord v-if="activeName === 'association'" :device-id="deviceId" />
      </el-tab-pane>
    </el-tabs>
  </ContentWrap>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
import { createImageViewer } from '@/components/ImageViewer'
import { getAccessToken } from '@/utils/auth'
import { DICT_TYPE, getDictLabel } from '@/utils/dict'
import DeviceBasicInfo from './DeviceBasicInfo.vue'
import DeviceAssociationRecord from './DeviceAssociationRecord.vue'
import DeviceAllotRecord from './DeviceAllotRecord.vue'
import DeviceBomLibrary from './DeviceBomLibrary.vue'
import DeviceFailureRecord from './DeviceFailureRecord.vue'
import DeviceFileLibrary from './DeviceFileLibrary.vue'
import DeviceInspectRecord from './DeviceInspectRecord.vue'
import DeviceMaintenanceRecord from './DeviceMaintenanceRecord.vue'
import DeviceMaintainRecord from './DeviceMaintainRecord.vue'
import DeviceOperationRecord from './DeviceOperationRecord.vue'
import DevicePersonRecord from './DevicePersonRecord.vue'
import DeviceStatusRecord from './DeviceStatusRecord.vue'
import CheckCertificate from './CheckCertificate.vue'

defineOptions({ name: 'DeviceInfo' })

type DeviceDetail = Partial<
  Omit<
    IotDeviceVO,
    | 'model'
    | 'manDate'
    | 'expires'
    | 'plPrice'
    | 'plDate'
    | 'plYear'
    | 'plStartDate'
    | 'plMonthed'
    | 'plAmounted'
    | 'remainAmount'
    | 'monthAmount'
    | 'totalMonth'
  >
> & {
  yfDeviceCode?: string
  brandName?: string
  assetClass?: number
  assetClassName?: string
  model?: string | number
  responsibleNames?: string
  devicePersons?: string
  zzName?: string
  supplierName?: string
  manufacturerName?: string
  manDate?: number | string | Date
  expires?: number | string | Date
  plDate?: number | string | Date
  plStartDate?: number | string | Date
  enableDate?: number | string | Date
  nameplate?: string
  plPrice?: number | string
  plYear?: number | string
  plMonthed?: number | string
  plAmounted?: number | string
  remainAmount?: number | string
  monthAmount?: number | string
  totalMonth?: number | string
  currency?: string
  templateJson?: string
}

interface TemplateField {
  sort?: number
  name?: string
  value?: string | number | null
  identifier?: string
}

interface MainInfoField {
  prop: keyof DeviceDetail | 'assetPropertyLabel' | 'responsibleNames'
  label: string
  value: string
  icon: string
}

const defaultDevicePic =
  import.meta.env.VITE_BASE_URL + '/admin-api/infra/file/29/get/IntegratedSolution.png'

const { t } = useI18n()
const { params, query } = useRoute()

const formLoading = ref(false)
const activeName = ref('info')
const defaultPicUrl = ref(defaultDevicePic)
const formData = ref<DeviceDetail>({})

const deviceId = computed(() => {
  const id = params.id ?? query.id
  const normalizedId = Array.isArray(id) ? id[0] : id
  return normalizedId ? Number(normalizedId) : undefined
})

const formatValue = (value?: string | number | null) => {
  return value || value === 0 ? String(value) : '-'
}

const statusLabel = computed(() => {
  return (
    getDictLabel(DICT_TYPE.PMS_DEVICE_STATUS, formData.value.deviceStatus) ||
    formData.value.deviceStatusName ||
    '-'
  )
})

const assetPropertyLabel = computed(() => {
  return getDictLabel(DICT_TYPE.PMS_ASSET_PROPERTY, formData.value.assetProperty) || '-'
})

const responsibleNames = computed(() => {
  return formData.value.responsibleNames || formData.value.devicePersons || '-'
})

const templateFields = computed<TemplateField[]>(() => {
  if (!formData.value.templateJson) return []

  try {
    const fields = JSON.parse(formData.value.templateJson)
    return Array.isArray(fields) ? fields : []
  } catch {
    return []
  }
})

const mainInfoFields = computed<MainInfoField[]>(() => [
  {
    prop: 'yfDeviceCode',
    label: t('iotDevice.yfCode'),
    value: formatValue(formData.value.yfDeviceCode),
    icon: 'ep:postcard'
  },
  {
    prop: 'deviceCode',
    label: t('iotDevice.code'),
    value: formatValue(formData.value.deviceCode),
    icon: 'ep:ticket'
  },
  {
    prop: 'deviceName',
    label: t('iotDevice.name'),
    value: formatValue(formData.value.deviceName),
    icon: 'ep:cpu'
  },
  {
    prop: 'brandName',
    label: t('iotDevice.brand'),
    value: formatValue(formData.value.brandName),
    icon: 'ep:medal'
  },
  {
    prop: 'deptName',
    label: t('iotDevice.dept'),
    value: formatValue(formData.value.deptName),
    icon: 'ep:office-building'
  },
  {
    prop: 'assetClassName',
    label: t('info.deviceClass'),
    value: formatValue(formData.value.assetClassName),
    icon: 'ep:grid'
  },
  {
    prop: 'deviceStatus',
    label: '施工状态',
    value: statusLabel.value,
    icon: 'ep:operation'
  },
  {
    prop: 'assetPropertyLabel',
    label: t('iotDevice.assets'),
    value: assetPropertyLabel.value,
    icon: 'ep:collection-tag'
  },
  {
    prop: 'model',
    label: t('deviceForm.model'),
    value: formatValue(formData.value.model),
    icon: 'ep:set-up'
  },
  {
    prop: 'responsibleNames',
    label: t('devicePerson.rp'),
    value: responsibleNames.value,
    icon: 'ep:user'
  }
])

const getDetail = async () => {
  if (!deviceId.value) return

  formLoading.value = true
  try {
    const detail = (await IotDeviceApi.getIotDevice(deviceId.value)) as DeviceDetail
    formData.value = detail || {}
    defaultPicUrl.value = detail?.picUrl || defaultDevicePic
  } finally {
    formLoading.value = false
  }
}

const imagePreview = (imgUrl: string) => {
  if (!imgUrl) return

  const token = getAccessToken()
  createImageViewer({
    urlList: [imgUrl],
    headers: {
      Authorization: `Bearer ${token}`
    }
  })
}

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

<style scoped lang="scss">
.device-main-wrap {
  overflow: hidden;
  border: 0;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgb(31 45 61 / 7%);
}

.device-detail-wrap {
  margin-top: 14px;
  overflow: hidden;
  border: 0;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgb(31 45 61 / 6%);
}

.device-main {
  display: grid;
  grid-template-columns: 292px minmax(0, 1fr);
  min-height: 286px;
  padding: 24px;
  background: radial-gradient(circle at 18px 22px, rgb(44 123 229 / 12%), transparent 30%),
    linear-gradient(135deg, #f7fbff 0%, var(--el-bg-color) 42%, #fbfcfe 100%);
}

.device-media {
  display: flex;
  align-items: stretch;
  justify-content: center;
}

.device-image-frame {
  position: relative;
  width: 260px;
  height: 226px;
  padding: 8px;
  overflow: hidden;
  font: inherit;
  cursor: zoom-in;
  background: var(--el-bg-color);
  border: 1px solid rgb(44 123 229 / 14%);
  border-radius: 12px;
  box-shadow: 0 14px 32px rgb(39 83 135 / 15%);
  appearance: none;

  &:hover {
    .device-image {
      transform: scale(1.035);
    }

    .image-preview-mask {
      opacity: 1;
    }
  }
}

.device-image {
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 8px;
  transition: transform 0.3s ease;
}

.device-image__empty {
  display: flex;
  width: 100%;
  height: 100%;
  font-size: 34px;
  color: var(--el-text-color-placeholder);
  background: var(--el-fill-color-light);
  align-items: center;
  justify-content: center;
}

.image-preview-mask {
  position: absolute;
  right: 18px;
  bottom: 18px;
  display: flex;
  gap: 6px;
  padding: 7px 12px;
  font-size: 12px;
  line-height: 16px;
  color: #fff;
  pointer-events: none;
  background: rgb(20 29 43 / 74%);
  border: 1px solid rgb(255 255 255 / 22%);
  border-radius: 16px;
  opacity: 0.88;
  backdrop-filter: blur(6px);
  align-items: center;
  transition: opacity 0.2s ease;
}

.device-content {
  min-width: 0;
  padding: 2px 4px 0 30px;
}

.device-head {
  display: flex;
  gap: 24px;
  min-height: 78px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--el-border-color-lighter);
  align-items: flex-start;
  justify-content: space-between;
}

.device-head__main {
  min-width: 0;
}

.device-title-row {
  display: flex;
  gap: 12px;
  min-width: 0;
  align-items: center;
}

.device-title {
  max-width: 760px;
  margin: 0;
  overflow: hidden;
  font-size: 24px;
  font-weight: 700;
  line-height: 34px;
  color: var(--el-text-color-primary);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.device-status {
  flex: none;
  padding: 0 12px;
  font-weight: 600;
}

.device-subtitle {
  display: flex;
  gap: 6px;
  margin-top: 9px;
  font-size: 13px;
  line-height: 20px;
  color: #7a5a13;
  align-items: center;
}

.device-info-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(132px, 1fr));
  gap: 0 22px;
  padding-top: 14px;
}

.device-info-item {
  display: flex;
  min-width: 0;
  min-height: 68px;
  padding: 11px 0;
  border-bottom: 1px dashed var(--el-border-color-lighter);
  flex-direction: column;
  justify-content: center;

  strong {
    margin-top: 7px;
    overflow: hidden;
    font-size: 14px;
    font-weight: 600;
    line-height: 21px;
    color: var(--el-text-color-primary);
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

.device-info-item__label {
  display: flex;
  gap: 6px;
  min-width: 0;
  font-size: 12px;
  line-height: 18px;
  color: var(--el-text-color-secondary);
  align-items: center;
}

.device-tabs {
  :deep(.el-tabs__header) {
    padding: 0 20px;
    margin: 0 -18px 18px;
    background: var(--el-bg-color);
  }

  :deep(.el-tabs__nav-wrap::after) {
    height: 1px;
    background-color: var(--el-border-color-lighter);
  }

  :deep(.el-tabs__item) {
    height: 54px;
    padding: 0 17px;
    font-weight: 500;
    color: var(--el-text-color-regular);
  }

  :deep(.el-tabs__item.is-active) {
    font-weight: 600;
    color: var(--el-color-primary);
  }

  :deep(.el-tabs__active-bar) {
    height: 3px;
    border-radius: 3px 3px 0 0;
  }
}

@media (width <= 1399px) {
  .device-main {
    grid-template-columns: 260px minmax(0, 1fr);
  }

  .device-image-frame {
    width: 232px;
    height: 208px;
  }

  .device-info-grid {
    grid-template-columns: repeat(4, minmax(132px, 1fr));
  }
}

@media (width <= 991px) {
  .device-main {
    grid-template-columns: 1fr;
  }

  .device-content {
    padding: 24px 0 0;
  }

  .device-info-grid {
    grid-template-columns: repeat(2, minmax(132px, 1fr));
  }
}

@media (width <= 575px) {
  .device-main {
    padding: 18px;
  }

  .device-head {
    gap: 12px;
    flex-direction: column;
  }

  .device-title {
    font-size: 20px;
    line-height: 30px;
  }

  .device-info-grid {
    grid-template-columns: 1fr;
  }
}
</style>
