<script lang="ts" setup>
import { IotStatApi } from '@/api/pms/stat'
import dayjs from 'dayjs'
import type { Ref } from 'vue'

interface RyProductionBriefRow {
  id: number
  projectClassification: string
  projectName: string
  deptName: string
  taskName: string
  constructionStatusName: string
  dailyFootage: number | null
  completedWells: number | null
  dailyPowerUsage: number | null
  dailyFuel: number | null
  nonProductionTime: number | null
  nextPlan: string
  constructionBrief: string
  projectSort?: number | null
  teamSort?: number | null
}

interface SpanMethodProps {
  rowIndex: number
  columnIndex: number
}

const TABLE_HEIGHT = 220
const MERGE_COLUMN_INDEXES = [0, 1]
const COMPANY_ORDER = ['钻井', '修井']
const DEFAULT_DATE = dayjs().subtract(1, 'day').format('YYYY-MM-DD')

const props = withDefaults(
  defineProps<{
    pageMode?: 'compact' | 'full'
  }>(),
  {
    pageMode: 'compact'
  }
)

const selectedDate = ref(DEFAULT_DATE)
const loading = ref(false)
const list = ref<RyProductionBriefRow[]>([])
const kbScale = inject<Ref<number>>('ryKbScale', ref(1))
const tableHeight = computed<number | string>(() =>
  props.pageMode === 'full' ? '100%' : Math.round(TABLE_HEIGHT * kbScale.value)
)

const tableData = computed(() => {
  return [...list.value].sort((a, b) => {
    const companySort =
      getCompanyOrder(a.projectClassification) - getCompanyOrder(b.projectClassification)
    if (companySort !== 0) return companySort

    const projectSort = Number(a.projectSort ?? 9999) - Number(b.projectSort ?? 9999)
    if (projectSort !== 0) return projectSort

    const projectNameSort = (a.projectName || '').localeCompare(b.projectName || '', 'zh-Hans-CN')
    if (projectNameSort !== 0) return projectNameSort

    return Number(a.teamSort ?? 9999) - Number(b.teamSort ?? 9999)
  })
})

const spanMaps = computed(() => {
  return {
    company: createSpanMap(tableData.value, (row) => row.projectClassification || '-'),
    project: createSpanMap(
      tableData.value,
      (row) => `${row.projectClassification || '-'}__${row.projectName || '-'}`
    )
  }
})

function getCompanyOrder(value?: string) {
  const index = COMPANY_ORDER.indexOf(value || '')
  return index === -1 ? COMPANY_ORDER.length : index
}

function createSpanMap(
  rows: RyProductionBriefRow[],
  getKey: (row: RyProductionBriefRow) => string
) {
  const spanMap: number[] = []

  rows.forEach((row, index) => {
    const key = getKey(row)

    if (index > 0 && getKey(rows[index - 1]) === key) {
      spanMap[index] = 0
      return
    }

    let span = 1
    for (let nextIndex = index + 1; nextIndex < rows.length; nextIndex++) {
      if (getKey(rows[nextIndex]) !== key) break
      span += 1
    }
    spanMap[index] = span
  })

  return spanMap
}

function tableSpanMethod({ rowIndex, columnIndex }: SpanMethodProps) {
  if (!MERGE_COLUMN_INDEXES.includes(columnIndex)) {
    return {
      rowspan: 1,
      colspan: 1
    }
  }

  const rowspan =
    columnIndex === 0 ? spanMaps.value.company[rowIndex] : spanMaps.value.project[rowIndex]

  return {
    rowspan,
    colspan: rowspan > 0 ? 1 : 0
  }
}

function formatNumber(value?: number | null, fractionDigits = 1) {
  const numberValue = Number(value ?? 0)
  return Number.isInteger(numberValue) ? `${numberValue}` : numberValue.toFixed(fractionDigits)
}

function formatFootageOrWell(row: RyProductionBriefRow) {
  if (row.projectClassification === '钻井') {
    return `${formatNumber(row.dailyFootage)}m`
  }

  return formatNumber(row.completedWells, 0)
}

function normalizeList(res: any): RyProductionBriefRow[] {
  if (Array.isArray(res)) return res
  if (Array.isArray(res?.list)) return res.list
  if (Array.isArray(res?.records)) return res.records
  if (Array.isArray(res?.data)) return res.data
  return []
}

function handleDateChange() {
  getList()
}

function getCreateTimeRange() {
  const date = selectedDate.value || DEFAULT_DATE

  return [
    dayjs(date).startOf('day').format('YYYY-MM-DD HH:mm:ss'),
    dayjs(date).endOf('day').format('YYYY-MM-DD HH:mm:ss')
  ]
}

async function getList() {
  loading.value = true

  try {
    const res = await IotStatApi.getRyProductionBriefs({ createTime: getCreateTimeRange() })
    list.value = normalizeList(res).filter((row) =>
      COMPANY_ORDER.includes(row.projectClassification || '')
    )
  } catch (error) {
    console.error('获取瑞鹰生产简报失败:', error)
    list.value = []
  } finally {
    loading.value = false
  }
}

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

<template>
  <div
    class="panel device-list-panel production-brief-panel w-full min-h-0 flex flex-col"
    :class="{ 'production-brief-panel--full': props.pageMode === 'full' }">
    <div class="panel-title device-list-panel__title flex items-center justify-between">
      <div class="kb-panel-title-text flex items-center">
        <div class="icon-decorator">
          <span></span>
          <span></span>
        </div>
        生产简报
      </div>
      <div class="device-list-panel__picker">
        <el-date-picker
          v-model="selectedDate"
          value-format="YYYY-MM-DD"
          type="date"
          placeholder="选择日期"
          :clearable="false"
          class="device-list-panel__picker-input"
          @change="handleDateChange" />
      </div>
    </div>
    <div class="device-list-panel__body flex flex-col flex-1 min-h-0">
      <el-table
        v-loading="loading"
        :data="tableData"
        :height="tableHeight"
        :span-method="tableSpanMethod"
        element-loading-text="加载中..."
        element-loading-background="rgb(222 236 252 / 72%)"
        border
        class="device-list-table production-brief-table"
        :class="{ 'device-list-table--full': props.pageMode === 'full' }">
        <el-table-column prop="projectClassification" label="公司" min-width="72" align="center" />
        <el-table-column prop="projectName" label="项目" min-width="150" align="center" />
        <el-table-column prop="deptName" label="队伍" min-width="94" align="center" />
        <el-table-column prop="taskName" label="生产任务" min-width="130" align="center" />
        <el-table-column
          prop="constructionStatusName"
          label="运行状态"
          min-width="88"
          align="center" />

        <el-table-column prop="nextPlan" label="下步任务" min-width="130" align="center" />
        <el-table-column
          prop="constructionBrief"
          label="当日生产简况"
          min-width="160"
          align="center">
          <template #default="{ row }">
            <div class="production-brief-table__summary">{{ row.constructionBrief || '--' }}</div>
          </template>
        </el-table-column>

        <el-table-column label="当日进尺(m)/当日井次" min-width="150" align="center">
          <template #default="{ row }">
            {{ formatFootageOrWell(row) }}
          </template>
        </el-table-column>
        <el-table-column label="当日电耗(kwh)" min-width="120" align="center">
          <template #default="{ row }">
            {{ formatNumber(row.dailyPowerUsage) }}
          </template>
        </el-table-column>
        <el-table-column label="当日油耗(升)" min-width="112" align="center">
          <template #default="{ row }">
            {{ formatNumber(row.dailyFuel) }}
          </template>
        </el-table-column>
        <el-table-column label="当日非生产时间" min-width="126" align="center">
          <template #default="{ row }">
            {{ formatNumber(row.nonProductionTime) }}
          </template>
        </el-table-column>

        <template #empty>
          <div class="h-full min-h-[220px] flex items-center justify-center">
            <el-empty description="暂无数据" :image-size="72" />
          </div>
        </template>
      </el-table>
    </div>
  </div>
</template>

<style lang="scss" scoped>
@import url('@/styles/kb.scss');

.device-list-panel.production-brief-panel--full {
  height: 100%;
  min-height: 0;
  margin-top: 0;
}

.device-list-panel__picker,
.device-list-panel__picker-input {
  width: calc(160px * var(--kb-scale, 1)) !important;

  :deep(.el-input__wrapper) {
    min-height: calc(28px * var(--kb-scale, 1));
    padding: 0 calc(10px * var(--kb-scale, 1));
  }

  :deep(.el-input__inner) {
    font-size: calc(12px * var(--kb-scale, 1));
  }

  :deep(.el-input__prefix-inner),
  :deep(.el-input__suffix-inner) {
    font-size: calc(14px * var(--kb-scale, 1));
  }
}

.production-brief-table {
  width: 100%;

  :deep(.el-table__header-wrapper th.el-table__cell) {
    font-size: calc(16px * var(--kb-scale, 1));
    line-height: 1.2;
    color: #10233c !important;
    background: #b5cde7 !important;
    border-color: #fff !important;
  }

  :deep(.el-table__body td.el-table__cell) {
    height: calc(58px * var(--kb-scale, 1));
    padding: calc(7px * var(--kb-scale, 1)) 0;
    font-size: calc(14px * var(--kb-scale, 1));
    color: #07192c !important;
    background: #89b3de !important;
    border-color: #fff !important;
  }

  :deep(.el-table__body tr:nth-child(2n) td.el-table__cell) {
    background: #b8cee5 !important;
  }

  :deep(.el-table__row:hover > td.el-table__cell) {
    background: #75a5d6 !important;
  }
}

.production-brief-table__summary {
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.device-list-table--full {
  :deep(.el-scrollbar__view) {
    display: block;
    height: 100%;
  }

  :deep(.el-table__body) {
    height: auto;
  }

  :deep(.el-table__body tbody) {
    height: auto;
  }
}
</style>
