<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle" width="900" :scroll="true" max-height="80vh" align-center>
    <div class="single-device-dialog">
      <el-form class="-mb-15px history-single-device-form" :inline="true" label-width="auto">
        <el-form-item :label="t('DataCollection.HistoryData.dialogCollectionTimeLabel')">
          <el-date-picker
            v-model="collectionTimeRange"
            value-format="YYYY-MM-DD HH:mm:ss"
            type="datetimerange"
            :start-placeholder="t('DataCollection.HistoryData.dialogCollectionTimeStartPlaceholder')"
            :end-placeholder="t('DataCollection.HistoryData.dialogCollectionTimeEndPlaceholder')"
            :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
            class="!w-360px"
          />
        </el-form-item>
        <el-form-item>
          <el-button @click="handleQuery">{{ t('DataCollection.HistoryData.dialogSearchButtonText') }}</el-button>
          <el-button @click="resetQuery">{{ t('DataCollection.HistoryData.dialogResetButtonText') }}</el-button>
        </el-form-item>
      </el-form>
      <ContentWrap v-loading="loading">
        <div v-if="recordGroups.length" class="single-device-dialog__record-list">
          <div v-for="group in recordGroups" :key="group.key" class="single-device-dialog__record">
            <div class="single-device-dialog__record-title">
              {{ t('DataCollection.HistoryData.dialogRecordCollectionTimePrefix') }}{{ group.collectTime || '-' }}
            </div>
            <div v-if="group.sections.length" class="single-device-dialog__table-grid">
              <div
v-for="section in group.sections" :key="`${group.key}-${section.key}`"
                class="single-device-dialog__section">
                <div class="single-device-dialog__section-title">
                  {{ section.title }}
                </div>
                <el-empty
                  v-if="!section.columns.length"
                  :description="t('DataCollection.HistoryData.emptyDescription')"
                />
                <el-table
v-else :data="section.rows" :border="true" :header-cell-style="headerCellStyle"
                  :cell-style="bodyCellStyle" size="small">
                  <el-table-column
v-for="col in section.columns" :key="col.prop" :prop="col.prop" :label="col.label"
                    align="center">
                    <template #default="scope">
                      <span>{{ formatCell(scope.row[col.prop]) }}</span>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </div>
            <el-empty v-else :description="t('DataCollection.HistoryData.emptyDescription')" />
          </div>
        </div>
        <el-empty v-else :description="t('DataCollection.HistoryData.emptyDescription')" />
      </ContentWrap>
    </div>
    <template #footer>
      <Pagination
        v-if="total > 0"
        :total="total"
        v-model:page="queryParams.pageNo"
        v-model:limit="queryParams.pageSize"
        @pagination="fetchHistory"
      />
    </template>
  </Dialog>
</template>

<script setup lang="ts">
import { DeviceApi } from '@/api/iot/device'

type SectionColumn = {
  prop: string
  label: string
}

type SectionRow = Record<string, string | number | null>

type Section = {
  key: string
  title: string
  columns: SectionColumn[]
  rows: SectionRow[]
}

type RecordGroup = {
  key: string
  collectTime?: string
  sections: Section[]
}

const { t } = useI18n()

const props = defineProps<{
  modelValue: boolean
  deviceId?: string | number
  deviceName?: string
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
}>()

const dialogVisible = computed({
  get() {
    return props.modelValue
  },
  set(value: boolean) {
    emit('update:modelValue', value)
  }
})

const dialogTitle = computed(() => {
  const name = props.deviceName ? props.deviceName : '-'
  return `${t('DataCollection.HistoryData.dialogTitlePrefix')}${name}`
})

const queryParams = reactive({
  pageNo: 1,
  pageSize: 10
})
const total = ref(0)

const loading = ref(false)
const recordGroups = ref<RecordGroup[]>([])

const collectionTimeRange = ref<string[]>([])

const formatDateTime = (date: Date) => {
  const pad = (value: number) => String(value).padStart(2, '0')
  const y = date.getFullYear()
  const m = pad(date.getMonth() + 1)
  const d = pad(date.getDate())
  const h = pad(date.getHours())
  const mi = pad(date.getMinutes())
  const s = pad(date.getSeconds())
  return `${y}-${m}-${d} ${h}:${mi}:${s}`
}

const buildLastHoursRange = (hours: number) => {
  const end = new Date()
  const start = new Date(end.getTime() - hours * 60 * 60 * 1000)
  return [formatDateTime(start), formatDateTime(end)]
}

const toGroupMap = (value: any): Record<string, any[]> => {
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
    return {}
  }
  const entries = Object.entries(value).filter(([, v]) => Array.isArray(v))
  if (!entries.length) {
    return {}
  }
  const map: Record<string, any[]> = {}
  for (const [k, v] of entries) {
    map[k] = v as any[]
  }
  return map
}

const formatCell = (value: string | number | null | undefined) => {
  if (value === null || value === undefined) {
    return ''
  }
  return value
}

const headerCellStyle = () => {
  return {
    fontWeight: 500,
    padding: '6px 4px',
    backgroundColor: 'var(--el-fill-color-light)',
    color: 'var(--el-text-color-primary)'
  }
}

const bodyCellStyle = () => {
  return {
    padding: '4px 4px'
  }
}

const buildSectionsFromGroups = (groups: Record<string, any[]>): Section[] => {
  const result: Section[] = []
  for (const [key, list] of Object.entries(groups)) {
    const columns: SectionColumn[] = []
    const row: SectionRow = {}
    if (Array.isArray(list) && list.length) {
      list.forEach((item: any, index: number) => {
        const prop = `col${index}`
        const label =
          item?.attributeName ?? `${t('DataCollection.HistoryData.defaultFieldLabelPrefix')}${index + 1}`
        columns.push({ prop, label })
        row[prop] = item?.addressValue ?? ''
      })
    }
    result.push({
      key,
      title: key,
      columns,
      rows: columns.length ? [row] : []
    })
  }
  return result
}

const fetchHistory = async () => {
  if (props.deviceId === undefined || props.deviceId === null || props.deviceId === '') {
    recordGroups.value = []
    total.value = 0
    return
  }
  loading.value = true
  try {
    const params: any = { 
      deviceId: props.deviceId,
      pageNo: queryParams.pageNo,
      pageSize: queryParams.pageSize
    }
    if (Array.isArray(collectionTimeRange.value) && collectionTimeRange.value.length === 2) {
      params.collectionStartTime = collectionTimeRange.value[0]
      params.collectionEndTime = collectionTimeRange.value[1]
    }
    const res: any = await DeviceApi.getHistoryRecord(params)
    const responseData = res?.data?.data ?? res?.data ?? res
    
    let list: any[] = []
    if (responseData && Array.isArray(responseData.list)) {
      list = responseData.list
      total.value = responseData.total || 0
    } else if (Array.isArray(responseData)) {
      list = responseData
      total.value = 0
    } else {
      list = []
      total.value = 0
    }
    
    recordGroups.value = list.map((item: any, index: number) => {
      const groups = toGroupMap(item)
      return {
        key: `${item?.collectTime ?? index}-${index}`,
        collectTime: item?.collectTime,
        sections: buildSectionsFromGroups(groups)
      }
    })
  } finally {
    loading.value = false
  }
}

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

const resetQuery = () => {
  collectionTimeRange.value = []
  queryParams.pageNo = 1
  queryParams.pageSize = 10
  fetchHistory()
}

watch(
  () => [props.modelValue, props.deviceId],
  ([visible]) => {
    if (!visible) {
      return
    }
    collectionTimeRange.value = buildLastHoursRange(4)
    queryParams.pageNo = 1
    queryParams.pageSize = 10
    fetchHistory()
  }
)
</script>

<style scoped>
.single-device-dialog {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.single-device-dialog__table-grid {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
  gap: 12px;
}

.single-device-dialog__record-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.single-device-dialog__record {
  padding: 12px;
  background: var(--el-bg-color-overlay);
  border: 1px solid var(--el-border-color);
  border-radius: 6px;
}

.single-device-dialog__section {
  padding: 10px;
  background: var(--el-fill-color-lighter);
  border: 1px solid var(--el-border-color);
  border-radius: 6px;
}

.single-device-dialog__section :deep(.el-table) {
  --el-table-row-hover-bg-color: transparent;
}

.single-device-dialog__record-title {
  margin-bottom: 6px;
  font-size: 13px;
  color: var(--el-text-color-secondary);
}

.single-device-dialog__section-title {
  margin-bottom: 4px;
  font-size: 13px;
  color: var(--el-text-color-primary);
}

.single-device-dialog__section :deep(.el-table__inner-wrapper) {
  border-radius: 0;
}

.single-device-dialog__section :deep(.el-table__header-wrapper th) {
  border-bottom-color: var(--el-border-color);
}
</style>
