<script setup lang="ts">
import dayjs from 'dayjs'
import { IotRyDailyReportApi } from '@/api/pms/iotrydailyreport'
import { useDebounceFn } from '@vueuse/core'
import CountTo from '@/components/count-to1.vue'
import * as echarts from 'echarts'
import UnfilledReportDialog from './UnfilledReportDialog.vue'

import { Motion, AnimatePresence } from 'motion-v'

import { rangeShortcuts } from '@/utils/formatTime'
import download from '@/utils/download'

import { useUserStore } from '@/store/modules/user'

const deptId = useUserStore().getUser.deptId

interface Query {
  pageNo: number
  pageSize: number
  deptId: number
  contractName?: string
  taskName?: string
  createTime: string[]
  projectClassification: 1 | 2
}

const id = deptId

const query = ref<Query>({
  pageNo: 1,
  pageSize: 10,
  deptId: deptId,
  createTime: [
    ...rangeShortcuts[2].value().map((item) => dayjs(item).format('YYYY-MM-DD HH:mm:ss'))
  ],
  projectClassification: 2
})

const totalWorkKeys: [string, string, string, string, number][] = [
  ['totalCount', '个', '总数', 'i-tabler:report-analytics text-sky', 0],
  [
    'alreadyReported',
    '个',
    '已填报',
    'i-material-symbols:check-circle-outline-rounded text-emerald',
    0
  ],
  ['notReported', '个', '未填报', 'i-material-symbols:cancel-outline-rounded text-rose', 0],
  [
    'totalFuelConsumption',
    '万升',
    '累计油耗',
    'i-material-symbols:directions-car-outline-rounded text-sky',
    4
  ],
  [
    'totalPowerConsumption',
    'MWh',
    '累计用电量',
    'i-material-symbols:electric-bolt-outline-rounded text-sky',
    4
  ],
  ['constructionWells', '个', '累计施工井数', 'i-mdi:progress-wrench text-sky', 0],
  ['completedWells', '个', '累计完工井数', 'i-mdi:wrench-check-outline text-emerald', 0]
]

const totalWork = ref({
  totalCount: 0,
  alreadyReported: 0,
  notReported: 0,
  totalFuelConsumption: 0,
  totalPowerConsumption: 0,
  constructionWells: 0,
  completedWells: 0
})

const totalLoading = ref(false)

const getTotal = useDebounceFn(async () => {
  totalLoading.value = true

  const { pageNo, pageSize, ...other } = query.value

  try {
    let res1: any[]
    if (query.value.createTime && query.value.createTime.length === 2) {
      res1 = await IotRyDailyReportApi.ryDailyReportStatistics({
        createTime: query.value.createTime,
        projectClassification: query.value.projectClassification
      })

      totalWork.value.totalCount = res1[0].count
      totalWork.value.alreadyReported = res1[1].count
      totalWork.value.notReported = res1[2].count
    }

    const res2 = await IotRyDailyReportApi.totalWorkload(other)

    totalWork.value = {
      ...totalWork.value,
      constructionWells: 0,
      completedWells: 0,
      ...res2,
      totalPowerConsumption: (res2.totalPowerConsumption || 0) / 1000,
      totalFuelConsumption: (res2.totalFuelConsumption || 0) / 10000
    }
  } finally {
    totalLoading.value = false
  }
}, 1000)

interface List {
  id: number | null
  name: string | null
  type: '1' | '2' | '3'
  cumulativeGasInjection: number | null
  cumulativeWaterInjection: number | null
  cumulativePowerConsumption: number | null
  cumulativeFuelConsumption: number | null
  transitTime: number | null
}

const list = ref<List[]>([])

const type = ref('2')

const columns = (type: string) => {
  return [
    {
      label: type === '2' ? '项目部' : '队伍',
      prop: 'name'
    },
    {
      label: '累计施工井数',
      prop: 'cumulativeConstructWells'
    },
    {
      label: '累计完工井数',
      prop: 'cumulativeCompletedWells'
    },
    {
      label: '累计用电量(MWh)',
      prop: 'cumulativePowerConsumption'
    },
    {
      label: '累计油耗(万升)',
      prop: 'cumulativeFuelConsumption'
    },
    {
      label: '平均时效(%)',
      prop: 'transitTime'
    }
  ]
}

const listLoading = ref(false)

const formatter = (row: List, column: any) => {
  if (column.property === 'transitTime') {
    return (Number(row.transitTime ?? 0) * 100).toFixed(2) + '%'
  } else return row[column.property] ?? 0
}

const getList = useDebounceFn(async () => {
  listLoading.value = true
  try {
    const res = await IotRyDailyReportApi.getIotRyDailyReportSummary(query.value)

    const { list: reslist } = res

    type.value = reslist[0]?.type || '2'

    list.value = reslist.map(
      ({ id, projectDeptId, projectDeptName, teamId, teamName, sort, taskId, type, ...other }) => ({
        id: type === '2' ? projectDeptId : teamId,
        name: type === '2' ? projectDeptName : teamName,
        ...other,
        cumulativePowerConsumption: ((other.cumulativePowerConsumption || 0) / 1000).toFixed(4),
        cumulativeFuelConsumption: ((other.cumulativeFuelConsumption || 0) / 10000).toFixed(4)
      })
    )
  } finally {
    listLoading.value = false
  }
}, 1000)

const tab = ref<'表格' | '看板'>('表格')

const currentTab = ref<'表格' | '看板'>('表格')

const deptName = ref('瑞鹰国际修井')

const direction = ref<'left' | 'right'>('right')

const handleSelectTab = (val: '表格' | '看板') => {
  tab.value = val
  direction.value = val === '看板' ? 'right' : 'left'
  nextTick(() => {
    currentTab.value = val
    setTimeout(() => {
      render()
    })
  })
}

const chartRef = ref<HTMLDivElement | null>(null)
let chart: echarts.ECharts | null = null

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

const legend = ref<string[][]>([
  ['累计施工井数 (个)', 'cumulativeConstructWells'],
  ['累计完工井数 (个)', 'cumulativeCompletedWells'],
  ['累计油耗 (万升)', 'cumulativeFuelConsumption'],
  ['累计用电量 (MWh)', 'cumulativePowerConsumption'],
  ['平均时效 (%)', 'transitTime']
])

const chartData = ref<Record<string, number[]>>({
  cumulativeFuelConsumption: [],
  cumulativeConstructWells: [],
  cumulativeCompletedWells: [],
  cumulativePowerConsumption: [],
  transitTime: []
})

let chartLoading = ref(false)

const getChart = useDebounceFn(async () => {
  chartLoading.value = true

  try {
    const res = await IotRyDailyReportApi.getIotRyDailyReportSummaryPolyline(query.value)

    chartData.value = {
      cumulativeFuelConsumption: res.map((item) => (item.cumulativeFuelConsumption || 0) / 10000),
      cumulativeConstructWells: res.map((item) => item.cumulativeConstructWells || 0),
      cumulativeCompletedWells: res.map((item) => item.cumulativeCompletedWells || 0),
      cumulativePowerConsumption: res.map((item) => (item.cumulativePowerConsumption || 0) / 1000),
      transitTime: res.map((item) => (item.transitTime || 0) * 100)
    }

    xAxisData.value = res.map((item) => item.reportDate || '')
  } finally {
    chartLoading.value = false
  }
}, 1000)

const resizer = () => {
  chart?.resize()
}

onUnmounted(() => {
  window.removeEventListener('resize', resizer)
})

const render = () => {
  if (!chartRef.value) return

  chart = echarts.init(chartRef.value, undefined, { renderer: 'canvas' })

  window.addEventListener('resize', resizer)

  const values: number[] = []

  for (const [_name, key] of legend.value) {
    values.push(...(chartData.value[key] || []))
  }

  const maxVal = values.length === 0 ? 10000 : Math.max(...values)
  const minVal = values.length === 0 ? 0 : Math.min(...values) > 0 ? 0 : Math.min(...values)

  const maxDigits = (Math.floor(maxVal) + '').length
  const minDigits = minVal === 0 ? 0 : (Math.floor(Math.abs(minVal)) + '').length
  const interval = Math.max(maxDigits, minDigits)

  const maxInterval = interval
  const minInterval = minDigits

  const intervalArr = [0]
  for (let i = 1; i <= interval; i++) {
    intervalArr.push(Math.pow(10, i))
  }

  chart.setOption({
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'line'
      },
      formatter: (params) => {
        let d = `${params[0].axisValueLabel}<br>`
        let item = params.map((el) => {
          return `<div class="flex items-center justify-between mt-1 gap-1">
            <span>${el.marker} ${el.seriesName}</span>
            <span>${chartData.value[legend.value[el.componentIndex][1]][el.dataIndex].toFixed(2)} ${el.seriesName.split(' ')[1]}</span>
          </div>`
        })

        return d + item.join('')
      }
    },
    legend: {
      data: legend.value.map(([name]) => name),
      show: true
    },
    xAxis: {
      type: 'category',
      data: xAxisData.value
    },
    yAxis: {
      type: 'value',
      min: -minInterval,
      max: maxInterval,
      interval: 1,
      axisLabel: {
        formatter: (v) => {
          const num = v === 0 ? 0 : v > 0 ? Math.pow(10, v) : -Math.pow(10, -v)

          return num.toLocaleString()
        }
      }
    },
    series: legend.value.map(([name, key]) => ({
      name,
      type: 'line',
      smooth: true,
      showSymbol: true,
      data: chartData.value[key].map((value) => {
        // return value
        if (value === 0) return 0

        const isPositive = value > 0
        const absItem = Math.abs(value)

        const min_value = Math.max(...intervalArr.filter((v) => v <= absItem))
        const min_index = intervalArr.findIndex((v) => v === min_value)

        const new_value =
          (absItem - min_value) / (intervalArr[min_index + 1] - intervalArr[min_index]) + min_index

        return isPositive ? new_value : -new_value
      })
    }))
  })
}

const handleDeptNodeClick = (node: any) => {
  deptName.value = node.name
  // query.value.deptId = node.id
  handleQuery()
}

const handleQuery = (setPage = true) => {
  if (setPage) {
    query.value.pageNo = 1
  }
  getChart().then(() => {
    render()
  })
  getList()
  getTotal()
}

const resetQuery = () => {
  query.value = {
    pageNo: 1,
    pageSize: 10,
    deptId: deptId,
    createTime: [],
    projectClassification: 1
  }
  handleQuery()
}

watch(
  () => query.value.createTime,
  (val) => {
    if (!val) {
      totalWork.value.totalCount = 0
      totalWork.value.notReported = 0
      totalWork.value.alreadyReported = 0
    }
    handleQuery(false)
  }
)

onMounted(() => {
  handleQuery()
})

const exportChart = () => {
  if (!chart) return
  let img = new Image()
  img.src = chart.getDataURL({
    type: 'png',
    pixelRatio: 1,
    backgroundColor: '#fff'
  })

  img.onload = function () {
    let canvas = document.createElement('canvas')
    canvas.width = img.width
    canvas.height = img.height
    let ctx = canvas.getContext('2d')
    ctx?.drawImage(img, 0, 0)
    let dataURL = canvas.toDataURL('image/png')

    let a = document.createElement('a')

    let event = new MouseEvent('click')

    a.href = dataURL
    a.download = `瑞鹰修井日报统计数据.png`
    a.dispatchEvent(event)
  }
}

const exportData = async () => {
  const res = await IotRyDailyReportApi.exportRyDailyReportStatistics(query.value)

  download.excel(res, '瑞鹰修井日报统计数据.xlsx')
}

const exportAll = async () => {
  if (tab.value === '看板') exportChart()
  else exportData()
}

const message = useMessage()

const unfilledDialogRef = ref()

const openUnfilledDialog = () => {
  // 检查是否选择了创建时间
  if (!query.value.createTime || query.value.createTime.length === 0) {
    message.warning('请先选择创建时间范围')
    return
  }

  // 打开弹窗
  unfilledDialogRef.value?.open()
}

const router = useRouter()

const tolist = (id: number) => {
  const { pageNo, pageSize, ...rest } = query.value

  router.push({
    path: '/iotdayilyreport/IotRyXjDailyReport',
    query: {
      ...rest,
      deptId: id
    }
  })
}
</script>

<template>
  <div class="grid grid-cols-[16%_1fr] gap-5">
    <div class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-4">
      <!-- <DeptTree2 :deptId="id" @node-click="handleDeptNodeClick" /> -->
      <DeptTreeSelect
        :deptId="id"
        :top-id="158"
        v-model="query.deptId"
        @node-click="handleDeptNodeClick"
      />
    </div>
    <div class="grid grid-rows-[62px_164px_1fr] h-full gap-5">
      <el-form
        size="default"
        class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between"
      >
        <div class="flex items-center gap-8">
          <el-form-item label="项目">
            <el-input
              v-model="query.contractName"
              placeholder="请输入项目"
              clearable
              @keyup.enter="handleQuery()"
              class="!w-240px"
            />
          </el-form-item>
          <el-form-item label="任务">
            <el-input
              v-model="query.taskName"
              placeholder="请输入任务"
              clearable
              @keyup.enter="handleQuery()"
              class="!w-240px"
            />
          </el-form-item>
          <el-form-item label="创建时间">
            <el-date-picker
              v-model="query.createTime"
              value-format="YYYY-MM-DD HH:mm:ss"
              type="daterange"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              :shortcuts="rangeShortcuts"
              class="!w-220px"
              :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
            />
          </el-form-item>
        </div>
        <el-form-item>
          <el-button type="primary" @click="handleQuery()">
            <Icon icon="ep:search" class="mr-5px" /> 搜索
          </el-button>
          <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
        </el-form-item>
      </el-form>
      <div class="grid grid-cols-7 gap-8">
        <div
          v-for="info in totalWorkKeys"
          :key="info[0]"
          class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow p-4 flex flex-col items-center justify-center gap-2"
        >
          <div class="size-7.5" :class="info[3]"></div>
          <count-to
            class="text-2xl font-medium"
            :start-val="0"
            :end-val="totalWork[info[0]]"
            :decimals="info[4]"
            @click="info[2] === '未填报' ? openUnfilledDialog() : ''"
          >
            <span class="text-xs leading-8 text-[var(--el-text-color-regular)]">暂无数据</span>
          </count-to>
          <div class="text-xs font-medium text-[var(--el-text-color-regular)]">{{ info[1] }}</div>
          <div class="text-sm font-medium text-[var(--el-text-color-regular)]">{{ info[2] }}</div>
        </div>
      </div>
      <div
        class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 py-4 grid grid-rows-[48px_1fr] gap-2"
      >
        <div class="flex items-center justify-between">
          <el-button-group>
            <el-button
              size="default"
              :type="tab === '表格' ? 'primary' : 'default'"
              @click="handleSelectTab('表格')"
              >表格
            </el-button>
            <el-button
              size="default"
              :type="tab === '看板' ? 'primary' : 'default'"
              @click="handleSelectTab('看板')"
              >看板
            </el-button>
          </el-button-group>
          <h3 class="text-xl font-medium">{{ `${deptName}-${tab}` }}</h3>
          <el-button size="default" type="primary" @click="exportAll">导出</el-button>
        </div>
        <!-- <el-auto-resizer>
          <template #default="{ height, width }"> -->
        <Motion
          as="div"
          :style="{ position: 'relative', overflow: 'hidden' }"
          :animate="{ height: `${500}px`, width: `100%` }"
          :transition="{ type: 'spring', stiffness: 200, damping: 25, duration: 0.3 }"
        >
          <AnimatePresence :initial="false" mode="sync">
            <Motion
              :key="currentTab"
              as="div"
              :initial="{ x: direction === 'left' ? '-100%' : '100%', opacity: 0 }"
              :animate="{ x: '0%', opacity: 1 }"
              :exit="{ x: direction === 'left' ? '50%' : '-50%', opacity: 0 }"
              :transition="{ type: 'tween', stiffness: 300, damping: 30, duration: 0.3 }"
              :style="{ position: 'absolute', left: 0, right: 0, top: 0 }"
            >
              <div :style="{ width: `100%`, height: `${500}px` }">
                <el-table
                  v-if="currentTab === '表格'"
                  v-loading="listLoading"
                  :data="list"
                  :stripe="true"
                  :max-height="500"
                  show-overflow-tooltip
                >
                  <template v-for="item in columns(type)" :key="item.prop">
                    <el-table-column
                      v-if="item.prop !== 'name'"
                      :label="item.label"
                      :prop="item.prop"
                      align="center"
                      :formatter="formatter"
                    />
                    <el-table-column v-else :label="item.label" :prop="item.prop" align="center">
                      <template #default="{ row }">
                        <el-button text type="primary" @click.prevent="tolist(row.id)">{{
                          row.name
                        }}</el-button>
                      </template>
                    </el-table-column>
                  </template>
                </el-table>
                <div
                  ref="chartRef"
                  v-loading="chartLoading"
                  :key="dayjs().valueOf()"
                  v-else
                  :style="{ width: `100%`, height: `${500}px` }"
                >
                </div>
              </div>
            </Motion>
          </AnimatePresence>
        </Motion>
        <!-- </template>
        </el-auto-resizer> -->
      </div>
    </div>
  </div>
  <UnfilledReportDialog ref="unfilledDialogRef" :query-params="query" />
</template>

<style scoped>
:deep(.el-form-item) {
  margin-bottom: 0;
}

:deep(.el-table) {
  border-top-right-radius: 8px;
  border-top-left-radius: 8px;

  .el-table__cell {
    height: 52px;
  }

  .el-table__header-wrapper {
    .el-table__cell {
      background: var(--el-fill-color-light);
    }
  }
}
</style>
