<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import dayjs from 'dayjs'
import CountTo from '@/components/count-to1.vue'
import { IotReportApi } from '@/api/pms/report'
import { useDebounceFn } from '@vueuse/core'
import download from '@/utils/download'
import { rangeShortcuts } from '@/utils/formatTime'
import { useTableComponents } from '@/components/ZmTable/useTableComponents'

// 定义时间类型
type TimeType = 'year' | 'month' | 'day'

interface Query {
  deptId?: number
  createTime?: [string, string]
  pageNo: number
  pageSize: number
  type?: string
}

// 选项配置数组
const timeOptions: { label: string; value: TimeType }[] = [
  { label: '年', value: 'year' },
  { label: '月', value: 'month' },
  { label: '日', value: 'day' }
]

const route = useRoute()

const getRouteCreateTime = (): [string, string] | undefined => {
  const createTime = route.query.createTime

  if (Array.isArray(createTime)) {
    const values = createTime.filter((item): item is string => typeof item === 'string')
    return values.length === 2 ? [values[0], values[1]] : undefined
  }

  if (typeof createTime === 'string') {
    const values = createTime.split(',').filter(Boolean)
    return values.length === 2 ? [values[0], values[1]] : undefined
  }

  return undefined
}

const routeCreateTime = getRouteCreateTime()
const activeTimeType = ref<TimeType | undefined>(routeCreateTime ? undefined : 'year')
const query = ref<Query>({
  pageNo: 1,
  pageSize: 10,
  createTime: routeCreateTime
})

const handleTimeChange = (type: TimeType, init = false) => {
  activeTimeType.value = type

  const formatStr = 'YYYY-MM-DD HH:mm:ss'
  const endTime = dayjs().endOf('day').format(formatStr)
  let startTime = ''

  switch (type) {
    case 'year':
      startTime = dayjs().startOf('year').format(formatStr)
      break
    case 'month':
      startTime = dayjs().startOf('month').format(formatStr)
      break
    case 'day':
      startTime = dayjs().startOf('day').format(formatStr)
      break
  }

  query.value.createTime = [startTime, endTime]

  console.log(`切换为[${type}]:`, query.value.createTime)

  if (!init) loadData()
}

interface StatItem {
  key: string
  title: string
  icon: string
  type: string
  class: { bg1: string; bg2: string; text: string }
  value: number
  tb: number
  hb: number
}

const defaultStats: StatItem[] = [
  {
    key: 'repair',
    title: '内部维修成本',
    type: '内部维修',
    icon: 'i-material-symbols:home-repair-service-outline',
    class: {
      bg1: 'bg-[var(--el-color-success-light-7)]',
      bg2: 'bg-[var(--el-color-success-light-5)]',
      text: 'text-[var(--el-color-success)]'
    },
    value: 0,
    tb: 0,
    hb: 0
  },
  {
    key: 'byFee',
    title: '保养成本',
    type: '保养',
    icon: 'i-material-symbols:construction-rounded',
    class: {
      bg1: 'bg-[var(--el-color-primary-light-7)]',
      bg2: 'bg-[var(--el-color-primary-light-5)]',
      text: 'text-[var(--el-color-primary)]'
    },
    value: 0,
    tb: 0,
    hb: 0
  },
  {
    key: 'out',
    title: '委外维修',
    type: '委外维修',
    icon: 'i-material-symbols:work-outline',
    class: {
      bg1: 'bg-[var(--el-color-warning-light-7)]',
      bg2: 'bg-[var(--el-color-warning-light-5)]',
      text: 'text-[var(--el-color-warning)]'
    },
    value: 0,
    tb: 0,
    hb: 0
  }
]

const statList = ref<StatItem[]>(defaultStats)
const dataLoading = ref(false)

const loadData = useDebounceFn(async function () {
  dataLoading.value = true
  try {
    const { pageNo, pageSize, type, ...other } = query.value
    const res = await IotReportApi.getCostsFee({ ...other, timeType: activeTimeType.value })
    const repair = statList.value[0]!
    const out = statList.value[2]!
    const byFee = statList.value[1]!

    out.value = res[out.key].total || 0
    out.tb = Number(((res[out.key].tb || 0) * 100).toFixed(0))
    out.hb = Number(((res[out.key].hb || 0) * 100).toFixed(0))

    repair.value = res[repair.key].total || 0
    repair.tb = Number(((res[repair.key].tb || 0) * 100).toFixed(0))
    repair.hb = Number(((res[repair.key].hb || 0) * 100).toFixed(0))

    byFee.value = res[byFee.key].total || 0
    byFee.tb = Number(((res[byFee.key].tb || 0) * 100).toFixed(0))
    byFee.hb = Number(((res[byFee.key].hb || 0) * 100).toFixed(0))
  } catch (error) {
    console.log('error :>> ', error)
  } finally {
    dataLoading.value = false
  }
}, 500)

const list = ref<any[]>([])
const loading = ref(false)
const total = ref(0)

function handleSizeChange(val: number) {
  query.value.pageSize = val
  query.value.pageNo = 1
  loadList()
}

function handleCurrentChange(val: number) {
  query.value.pageNo = val
  loadList()
}

function handleQuery(setPage = true) {
  if (setPage) {
    query.value.pageNo = 1
  }
  loadList()
  loadData()
}

const loadList = useDebounceFn(async function () {
  loading.value = true
  try {
    const data = await IotReportApi.getCostsPage(query.value)
    list.value = data.list
    total.value = data.total

    // nextTick(() => {
    //   calculateColumnWidths(columns.value)
    // })
  } finally {
    loading.value = false
  }
}, 500)

onMounted(() => {
  if (!query.value.createTime) {
    handleTimeChange('year', true)
  }
})

watch(
  [() => query.value.createTime, () => query.value.deptId],
  () => {
    handleQuery()
  },
  { immediate: true }
)

watch(
  () => route.query.createTime,
  () => {
    const createTime = getRouteCreateTime()
    if (!createTime) return

    activeTimeType.value = undefined
    query.value.createTime = createTime
  }
)

function selectType(type: string | undefined) {
  query.value.type = type
  query.value.pageNo = 1
  loadList()
}

function handleReset() {
  handleTimeChange('year')
  selectType(undefined)
}

const exportLoading = ref(false)
const { ZmTable, ZmTableColumn } = useTableComponents<any>()

const handleExport = async () => {
  exportLoading.value = true
  try {
    const data = await IotReportApi.exportCosts(query.value)
    download.excel(data, '运维成本.xls')
  } finally {
    exportLoading.value = false
  }
}

const handleClear = () => {
  handleTimeChange('year')
}

const handleChange = () => {
  activeTimeType.value = undefined
}
</script>

<template>
  <div
    class="grid grid-cols-[auto_1fr] grid-rows-[196px_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]">
    <DeptTreeSelect
      :top-id="156"
      :deptId="156"
      v-model="query.deptId"
      :init-select="false"
      :show-title="false"
      class="row-span-2" />
    <!-- <div class="p-4 bg-white dark:bg-[#1d1e1f] shadow rounded-lg row-span-2"> </div> -->
    <div class="grid grid-rows-[1fr_32px] gap-4">
      <div class="grid grid-cols-3 gap-4" v-loading="dataLoading">
        <!-- 使用 v-for 循环渲染 -->
        <section
          v-for="item in statList"
          :key="item.key"
          class="flex flex-col items-center gap-y-4 rounded-lg shadow p-4 transition-transform hover:scale-105 duration-500"
          :class="{ [item.class.bg1]: true, 'scale-105': item.type === query.type }"
          @click="selectType(item.type)">
          <!-- 头部：图标 + 标题 -->
          <div class="flex items-center gap-x-3">
            <div class="rounded-2 p-2" :class="[item.class.text, item.class.bg2]">
              <div :class="item.icon"></div>
            </div>
            <div class="text-[var(--el-text-color-primary)] text-sm font-medium">
              {{ item.title }}
            </div>
          </div>

          <!-- 数值区域：CountTo -->
          <count-to
            class="text-3xl font-semibold"
            :start-val="0"
            :end-val="item.value"
            :decimals="2"
            suffix="元"
            :duration="1000">
            <!-- 插槽内容：当数据为空或0时的显示 (根据 count-to 组件的具体实现决定是否显示) -->
            <span class="text-xs leading-8 text-[var(--el-text-color-regular)]">暂无数据</span>
          </count-to>

          <!-- 底部：环比数据 -->
          <!-- 根据 trend 正负动态改变图标和颜色 -->
          <div class="mt-2 flex items-center gap-x-4">
            <div
              v-show="item.hb"
              class="flex items-center gap-x-1 text-xs font-medium"
              :class="item.class.text">
              <!-- 动态图标：大于等于0向上，小于0向下 -->
              <div
                :class="
                  item.hb >= 0
                    ? 'i-material-symbols:arrow-warm-up-rounded'
                    : 'i-material-symbols:arrow-cool-down-rounded'
                "></div>

              <span class="vertical-middle"> {{ item.hb > 0 ? '+' + item.hb : item.hb }}% </span>
              <span>环比</span>
            </div>
            <div
              v-show="item.tb"
              class="flex items-center gap-x-1 text-xs font-medium"
              :class="item.class.text">
              <!-- 动态图标：大于等于0向上，小于0向下 -->
              <div
                :class="
                  item.tb >= 0
                    ? 'i-material-symbols:arrow-warm-up-rounded'
                    : 'i-material-symbols:arrow-cool-down-rounded'
                "></div>

              <span class="vertical-middle"> {{ item.tb > 0 ? '+' + item.tb : item.tb }}% </span>
              <span>同比</span>
            </div>
          </div>
        </section>
      </div>
      <div class="flex justify-between gap-4">
        <div class="flex items-center gap-4">
          <el-date-picker
            size="default"
            v-model="query.createTime"
            value-format="YYYY-MM-DD HH:mm:ss"
            type="daterange"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :shortcuts="rangeShortcuts"
            class="!w-220px"
            @clear="handleClear"
            @change="handleChange"
            :clearable="false"
            :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" />
          <el-button-group size="default">
            <el-button
              v-for="item in timeOptions"
              :key="item.value"
              :type="activeTimeType === item.value ? 'primary' : ''"
              @click="handleTimeChange(item.value)">
              {{ item.label }}
            </el-button>
          </el-button-group>
        </div>
        <div class="flex items-center gap-2">
          <el-button size="default" @click="handleReset">重置</el-button>
          <el-button
            size="default"
            plain
            type="success"
            @click="handleExport"
            :loading="exportLoading">
            <Icon icon="ep:download" class="mr-5px" /> 导出
          </el-button>
        </div>
      </div>
    </div>
    <div class="bg-white dark:bg-[#1d1e1f] shadow rounded-lg p-4 flex flex-col mt-4">
      <div class="flex-1 relative">
        <el-auto-resizer class="absolute">
          <template #default="{ width, height }">
            <ZmTable
              :data="list"
              :loading="loading"
              :width="width"
              :height="height"
              :max-height="height"
              show-border>
              <ZmTableColumn
                label="序号"
                type="index"
                :width="70"
                fixed="left"
                hide-in-column-settings />
              <ZmTableColumn label="日期" prop="date" min-width="140" />
              <ZmTableColumn label="类别" prop="type" min-width="120" />
              <ZmTableColumn label="设备编号" prop="deviceCode" min-width="150" />
              <ZmTableColumn label="设备名称" prop="deviceName" min-width="180" />
              <ZmTableColumn label="成本" prop="cost" min-width="120" action>
                <template #default="{ row }"> {{ row.cost ?? 0 }}元 </template>
              </ZmTableColumn>
            </ZmTable>
          </template>
        </el-auto-resizer>
      </div>
      <div class="h-10 mt-4 flex items-center justify-end">
        <el-pagination
          size="default"
          v-show="total > 0"
          v-model:current-page="query.pageNo"
          v-model:page-size="query.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>
</template>

<style scoped></style>
