<template>
  <div class="overview-page">
    <div class="overview-header">
      <div class="header-left"><img class="site-navbar__brand-logo" src="~@/assets/img/lc.png" alt="龙闯电梯"></div>
      <div class="header-center">
        <div class="header-title">龙闯电梯 MES - 工厂综合运营大屏</div>
      </div>
      <div class="right-tools">
        <div class="time-text">{{ currentTime }}</div>
      </div>
    </div>

    <div class="kpi-grid">
      <div class="kpi-card">
        <div class="kpi-label">近一月整梯排产</div>
        <div class="kpi-value">{{ kpi.monthWhole }}</div>
      </div>
      <div class="kpi-card">
        <div class="kpi-label">近一月VL2.5升级排产</div>
        <div class="kpi-value">{{ kpi.monthRenovation }}</div>
      </div>
      <div class="kpi-card">
        <div class="kpi-label">近一月线缆/COP任务</div>
        <div class="kpi-value">{{ kpi.monthTask }}</div>
      </div>
      <div class="kpi-card">
        <div class="kpi-label">近一月机加工任务</div>
        <div class="kpi-value">{{ kpi.monthMachining }}</div>
      </div>
      <div class="kpi-card">
        <div class="kpi-label">近一月完工达成率</div>
        <div class="kpi-value highlight">{{ kpi.finishRate }}%</div>
      </div>
      <div class="kpi-card">
        <div class="kpi-label">当前在制总量</div>
        <div class="kpi-value warning">{{ kpi.wipTotal }}</div>
      </div>
      <div class="kpi-card">
        <div class="kpi-label">订单准交率</div>
        <div class="kpi-value success">{{ kpi.onTimeRate }}%</div>
      </div>
    </div>

    <div class="chart-grid">
      <div class="panel">
        <div class="panel-title">近一月排产/完工对比</div>
        <div id="overviewBarChart" class="chart-box"></div>
      </div>
      <div class="panel">
        <div class="panel-title">生产结构分布</div>
        <div id="overviewPieChart" class="chart-box"></div>
      </div>
      <div class="panel wide">
        <div class="panel-title">最近 7 天完工趋势</div>
        <div id="overviewLineChart" class="chart-box line-box"></div>
      </div>
      <div class="panel">
        <div class="panel-title">关键环节达成率</div>
        <div class="node-rate-grid">
          <div v-for="item in nodeRates" :key="item.name" class="node-rate-card">
            <div class="node-rate-name">{{ item.name }}</div>
            <div class="node-rate-meta">
              <span class="node-rate-count">{{ item.done }}/{{ item.total }}</span>
              <span class="node-rate-badge" :class="getNodeRateClass(item.rate)">{{ item.rate }}%</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import echarts from 'echarts'
import { getFactoryOverviewBoardData } from '@/api/longchuang/productionPlan'

const STATUS_ALLOW_LIST = ['已排产', '进行中', '已完成']

export default {
  name: 'ScreenFactoryOverview',
  data() {
    return {
      currentTime: '',
      timerId: null,
      boardTimerId: null,
      loading: false,
      chartBar: null,
      chartPie: null,
      chartLine: null,
      wholeList: [],
      taskList: [],
      renovationList: [],
      machiningList: [],
      kpi: {
        monthWhole: 0,
        monthRenovation: 0,
        monthTask: 0,
        monthMachining: 0,
        finishRate: 0,
        wipTotal: 0,
        onTimeRate: 0
      },
      nodeRates: []
    }
  },
  mounted() {
    this.loadBoardData()
    this.updateTime()
    this.timerId = setInterval(this.updateTime, 1000)
    this.boardTimerId = setInterval(() => {
      this.loadBoardData()
    }, 60000)
    window.addEventListener('resize', this.resizeCharts)
  },
  beforeDestroy() {
    if (this.timerId) clearInterval(this.timerId)
    if (this.boardTimerId) clearInterval(this.boardTimerId)
    window.removeEventListener('resize', this.resizeCharts)
    this.disposeCharts()
  },
  methods: {
    loadBoardData() {
      if (this.loading) return
      this.loading = true
      getFactoryOverviewBoardData({ page: 1, limit: 500, statusList: STATUS_ALLOW_LIST }).then(({ data }) => {
        this.loading = false
        const boardData = data && data.code === 0 && data.boardData ? data.boardData : {}
        this.wholeList = this.normalizeBoardList(boardData.homeLiftList)
        this.taskList = this.normalizeBoardList(boardData.cableCopTaskList)
        this.renovationList = this.normalizeBoardList(boardData.renovationOrderList)
        this.machiningList = this.normalizeBoardList(boardData.machiningTaskList)
        this.buildDashboard()
        this.$nextTick(() => {
          setTimeout(() => {
            this.resizeCharts()
          }, 120)
        })
      }).catch(() => {
        this.loading = false
        this.wholeList = []
        this.taskList = []
        this.renovationList = []
        this.machiningList = []
        this.buildDashboard()
      })
    },
    normalizeBoardList(sourceList) {
      return (sourceList || [])
        .filter(item => STATUS_ALLOW_LIST.includes(item.status))
        .map(item => ({
          ...item,
          nodeList: item.nodeList || []
        }))
    },
    buildDashboard() {
      const periodStart = this.dayjs().subtract(1, 'month').startOf('day')
      const allOrderList = this.wholeList
        .concat(this.renovationList)
        .concat(this.taskList)
        .concat(this.machiningList)
      const recentOrderList = this.filterByDateRange(allOrderList, periodStart)
      const finishedAll = recentOrderList.filter(item => item.status === '已完成').length
      const inScheduleAll = recentOrderList.filter(item => STATUS_ALLOW_LIST.includes(item.status)).length
      const wipTotal = this.wholeList.filter(item => item.status === '进行中').length +
        this.taskList.filter(item => item.status === '进行中').length +
        this.renovationList.filter(item => item.status === '进行中').length +
        this.machiningList.filter(item => item.status === '进行中').length

      const monthWhole = this.countByMonth(this.wholeList, periodStart)
      const monthRenovation = this.countByMonth(this.renovationList, periodStart)
      const monthTask = this.countByMonth(this.taskList, periodStart)
      const monthMachining = this.countByMonth(this.machiningList, periodStart)

      const onTimeTotal = allOrderList.filter(item => item.status === '已完成').length
      const onTimeCount = allOrderList.filter(item => item.status === '已完成' && this.isOnTime(item)).length

      this.kpi.monthWhole = monthWhole
      this.kpi.monthRenovation = monthRenovation
      this.kpi.monthTask = monthTask
      this.kpi.monthMachining = monthMachining
      this.kpi.finishRate = inScheduleAll ? Math.round((finishedAll / inScheduleAll) * 100) : 0
      this.kpi.wipTotal = wipTotal
      this.kpi.onTimeRate = onTimeTotal ? Math.round((onTimeCount / onTimeTotal) * 100) : 0

      this.nodeRates = this.buildNodeRates()
      this.$nextTick(() => {
        this.renderBarChart()
        this.renderPieChart()
        this.renderLineChart()
      })
    },
    countByMonth(list, monthStart) {
      const startValue = monthStart.valueOf()
      return list.filter(item => {
        const dateVal = item.planDeliveryDate || item.planFinishDate || item.createTime
        const dateObj = this.toDayjs(dateVal)
        return dateObj && dateObj.valueOf() >= startValue
      }).length
    },
    filterByDateRange(list, startDate) {
      return (list || []).filter(item => {
        const dateVal = item.planDeliveryDate || item.planFinishDate || item.createTime
        const dateObj = this.toDayjs(dateVal)
        return dateObj && dateObj.valueOf() >= startDate.valueOf()
      })
    },
    countFinishedInRange(list, startDate) {
      return (list || []).filter(item => {
        if (item.status !== '已完成') return false
        const dateVal = item.finishDate || item.planDeliveryDate || item.planFinishDate || item.createTime
        const dateObj = this.toDayjs(dateVal)
        return dateObj && dateObj.valueOf() >= startDate.valueOf()
      }).length
    },
    isOnTime(item) {
      const finishDate = this.toDayjs(item.finishDate)
      const planDate = this.toDayjs(item.planDeliveryDate || item.planFinishDate)
      if (!finishDate || !planDate) return false
      return finishDate.valueOf() <= planDate.valueOf()
    },
    toDayjs(dateVal) {
      if (!dateVal) return null
      const d = this.dayjs(dateVal)
      return d && d.isValid() ? d : null
    },
    buildNodeRates() {
      const nodeMap = {}
      const all = this.wholeList.concat(this.taskList).concat(this.renovationList).concat(this.machiningList)
      all.forEach(item => {
        const list = item.nodeList || []
        list.forEach(node => {
          if (!nodeMap[node.nodeName]) nodeMap[node.nodeName] = { total: 0, done: 0 }
          nodeMap[node.nodeName].total += 1
          if (node.status === '已完成') nodeMap[node.nodeName].done += 1
        })
      })
      return Object.keys(nodeMap).map((name) => {
        const total = nodeMap[name].total
        const done = nodeMap[name].done
        return {
          name,
          total,
          done,
          rate: total ? Math.round((done / total) * 100) : 0,
        }
      }).sort((a, b) => b.rate - a.rate)
    },
    getNodeRateClass(rate) {
      if (rate >= 85) return 'is-high'
      if (rate >= 60) return 'is-mid'
      return 'is-low'
    },
    renderBarChart() {
      const el = document.getElementById('overviewBarChart')
      if (!el) return
      if (!this.chartBar) this.chartBar = echarts.init(el)
      const periodStart = this.dayjs().subtract(1, 'month').startOf('day')
      const scheduledWhole = this.countByMonth(this.wholeList.filter(item => STATUS_ALLOW_LIST.includes(item.status)), periodStart)
      const scheduledRenovation = this.countByMonth(this.renovationList.filter(item => STATUS_ALLOW_LIST.includes(item.status)), periodStart)
      const scheduledTask = this.countByMonth(this.taskList.filter(item => STATUS_ALLOW_LIST.includes(item.status)), periodStart)
      const scheduledMachining = this.countByMonth(this.machiningList.filter(item => STATUS_ALLOW_LIST.includes(item.status)), periodStart)
      const finishedWhole = this.countFinishedInRange(this.wholeList, periodStart)
      const finishedRenovation = this.countFinishedInRange(this.renovationList, periodStart)
      const finishedTask = this.countFinishedInRange(this.taskList, periodStart)
      const finishedMachining = this.countFinishedInRange(this.machiningList, periodStart)
      this.chartBar.setOption({
        color: ['#4fa8ff', '#6ed3a6'],
        grid: { left: 30, right: 20, top: 40, bottom: 20, containLabel: true },
        tooltip: { trigger: 'axis' },
        legend: { textStyle: { color: '#cbe7ff' }, data: ['排产量', '完工量'] },
        xAxis: { type: 'category', axisLabel: { color: '#cbe7ff' }, data: ['整梯', 'VL2.5升级', '线缆/COP', '机加工'] },
        yAxis: { type: 'value', axisLabel: { color: '#cbe7ff' }, splitLine: { lineStyle: { color: 'rgba(160,200,240,0.15)' } } },
        series: [
          {
            name: '排产量',
            type: 'bar',
            barWidth: 24,
            data: [scheduledWhole, scheduledRenovation, scheduledTask, scheduledMachining],
            itemStyle: { color: '#4fa8ff' },
            label: {
              normal: {
                show: true,
                position: 'top',
                color: '#d4ebff',
                fontSize: 12,
                formatter: '{c}'
              }
            }
          },
          {
            name: '完工量',
            type: 'bar',
            barWidth: 24,
            data: [finishedWhole, finishedRenovation, finishedTask, finishedMachining],
            itemStyle: { color: '#6ed3a6' },
            label: {
              normal: {
                show: true,
                position: 'top',
                color: '#d4ebff',
                fontSize: 12,
                formatter: '{c}'
              }
            }
          }
        ]
      }, true)
    },
    renderPieChart() {
      const el = document.getElementById('overviewPieChart')
      if (!el) return
      if (!this.chartPie) this.chartPie = echarts.init(el)
      const wholeCount = this.wholeList.length
      const renovationCount = this.renovationList.length
      const taskCount = this.taskList.length
      const machiningCount = this.machiningList.length
      const pieData = [
        { value: wholeCount, name: '整梯订单' },
        { value: renovationCount, name: 'VL2.5升级订单' },
        { value: taskCount, name: '线缆/COP任务' },
        { value: machiningCount, name: '机加工任务' }
      ]
      this.chartPie.setOption({
        color: ['#57b8ff', '#5dd4b0', '#7fa6d9', '#f5c15e'],
        tooltip: {
          trigger: 'item',
          formatter: (params) => `${params.name}<br/>数量：${params.value}<br/>占比：${params.percent || 0}%`
        },
        legend: { bottom: 2, textStyle: { color: '#cbe7ff' } },
        series: [{
          type: 'pie',
          radius: ['42%', '72%'],
          center: ['50%', '45%'],
          avoidLabelOverlap: false,
          minShowLabelAngle: 0,
          label: {
            normal: {
              show: true,
              position: 'outside',
              color: '#d4ebff',
              fontSize: 14,
              formatter: '{b} {d}%'
            },
            emphasis: {
              show: true,
              formatter: '{b} {d}%'
            }
          },
          labelLine: {
            normal: {
              show: true,
              length: 14,
              length2: 10,
              lineStyle: {
                color: '#7fb4de'
              }
            }
          },
          data: pieData
        }]
      }, true)
    },
    renderLineChart() {
      const el = document.getElementById('overviewLineChart')
      if (!el) return
      if (!this.chartLine) this.chartLine = echarts.init(el)
      const xAxis = []
      const wholeSeries = []
      const renovationSeries = []
      const taskSeries = []
      const machiningSeries = []
      for (let i = 6; i >= 0; i--) {
        const day = this.dayjs().subtract(i, 'day')
        xAxis.push(day.format('MM-DD'))
        wholeSeries.push(this.countFinishByDay(this.wholeList, day))
        renovationSeries.push(this.countFinishByDay(this.renovationList, day))
        taskSeries.push(this.countFinishByDay(this.taskList, day))
        machiningSeries.push(this.countFinishByDay(this.machiningList, day))
      }
      this.chartLine.setOption({
        color: ['#6cc7ff', '#74e0b3', '#7fa6d9', '#f5c15e'],
        grid: { left: 35, right: 20, top: 34, bottom: 20, containLabel: true },
        tooltip: { trigger: 'axis' },
        legend: { textStyle: { color: '#cbe7ff' }, data: ['整梯完工', 'VL2.5升级完工', '线缆/COP完工', '机加工完工'] },
        xAxis: { type: 'category', axisLabel: { color: '#cbe7ff' }, data: xAxis },
        yAxis: { type: 'value', axisLabel: { color: '#cbe7ff' }, splitLine: { lineStyle: { color: 'rgba(160,200,240,0.15)' } } },
        series: [
          { name: '整梯完工', type: 'line', smooth: true, symbol: 'circle', symbolSize: 7, data: wholeSeries, itemStyle: { color: '#6cc7ff' }, lineStyle: { color: '#6cc7ff' }, areaStyle: { color: 'rgba(108,199,255,0.18)' } },
          { name: 'VL2.5升级完工', type: 'line', smooth: true, symbol: 'circle', symbolSize: 7, data: renovationSeries, itemStyle: { color: '#74e0b3' }, lineStyle: { color: '#74e0b3' }, areaStyle: { color: 'rgba(116,224,179,0.18)' } },
          { name: '线缆/COP完工', type: 'line', smooth: true, symbol: 'circle', symbolSize: 7, data: taskSeries, itemStyle: { color: '#7fa6d9' }, lineStyle: { color: '#7fa6d9' }, areaStyle: { color: 'rgba(127,166,217,0.16)' } },
          { name: '机加工完工', type: 'line', smooth: true, symbol: 'circle', symbolSize: 7, data: machiningSeries, itemStyle: { color: '#f5c15e' }, lineStyle: { color: '#f5c15e' }, areaStyle: { color: 'rgba(245,193,94,0.15)' } }
        ]
      }, true)
    },
    countFinishByDay(list, day) {
      return list.filter(item => {
        const finishDate = this.toDayjs(item.finishDate)
        return finishDate && finishDate.format('YYYY-MM-DD') === day.format('YYYY-MM-DD')
      }).length
    },
    updateTime() {
      const now = new Date()
      const weekList = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
      const d = this.dayjs(now)
      this.currentTime = `${d.format('YYYY/MM/DD')}  ${weekList[now.getDay()]}  ${d.format('HH:mm:ss')}`
    },
    resizeCharts() {
      if (this.chartBar) this.chartBar.resize()
      if (this.chartPie) this.chartPie.resize()
      if (this.chartLine) this.chartLine.resize()
    },
    disposeCharts() {
      if (this.chartBar) { this.chartBar.dispose(); this.chartBar = null }
      if (this.chartPie) { this.chartPie.dispose(); this.chartPie = null }
      if (this.chartLine) { this.chartLine.dispose(); this.chartLine = null }
    }
  }
}
</script>

<style scoped>
.overview-page {
  height: 100vh;
  padding: 16px;
  background: radial-gradient(circle at 20% 20%, #1b3352 0%, #102338 45%, #0a1523 100%);
  color: #e7f3ff;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}

.overview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
  padding: 12px 16px;
  border-radius: 10px;
  border: 1px solid rgba(100, 187, 255, 0.28);
  background: rgba(12, 36, 58, 0.78);
  position: relative;
}

.left-logo {
  display: flex;
  align-items: center;
  min-width: 110px;
  z-index: 2;
}

.logo-box {
  width: 86px;
  height: 30px;
  border-radius: 6px;
  border: 1px solid rgba(128, 198, 255, 0.45);
  color: #d8edff;
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(36, 82, 122, 0.35);
}

.overview-header .header-center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  pointer-events: none;
  max-width: 70%;
  width: auto;
  padding: 6px 24px 8px;
  border-radius: 8px;
  border: 1px solid rgba(96, 170, 232, 0.34);
  background: linear-gradient(180deg, rgba(33, 73, 116, 0.52), rgba(16, 44, 77, 0.42));
}

.overview-header .header-center::before {
  content: '';
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: -8px;
  width: 70%;
  height: 1px;
  background: linear-gradient(90deg, rgba(87,164,230,0), rgba(87,164,230,.9), rgba(87,164,230,0));
}

.header-title {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: 3px;
  line-height: 1.05;
  color: #8fe7ff;
  text-shadow: 0 0 14px rgba(79, 179, 255, 0.36);
}

.header-subtitle {
  margin-top: 4px;
  font-size: 12px;
  color: #c7e8ff;
  letter-spacing: 1px;
}

.right-tools {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto;
  z-index: 2;
}

.time-text {
  font-size: 18px;
  font-weight: 600;
  color: #7bd9ff;
}

.refresh-btn {
  background: #ecf5ff;
  border-color: #b3d8ff;
  color: #409eff;
}

.refresh-btn:hover {
  background: #409eff;
  border-color: #409eff;
  color: #fff;
}

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.kpi-card {
  border-radius: 10px;
  padding: 12px 14px;
  background: linear-gradient(135deg, rgba(29, 66, 106, 0.95), rgba(17, 43, 69, 0.92));
  border: 1px solid rgba(95, 180, 255, 0.24);
}

.kpi-label {
  font-size: 12px;
  color: #b9d8f8;
}

.kpi-value {
  margin-top: 6px;
  font-size: 28px;
  font-weight: 700;
  color: #dff0ff;
}

.kpi-value.highlight {
  color: #67d2ff;
}

.kpi-value.warning {
  color: #f5c15e;
}

.kpi-value.success {
  color: #4ade80;
}

.chart-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
  gap: 12px;
  flex: 1;
  min-height: 0;
}

.panel {
  border-radius: 10px;
  background: rgba(13, 34, 54, 0.86);
  border: 1px solid rgba(95, 180, 255, 0.24);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.panel.wide {
  grid-column: span 1;
}

.panel-title {
  font-size: 14px;
  font-weight: 600;
  color: #d9ebff;
  margin-bottom: 8px;
}

.chart-box {
  flex: 1;
  min-height: 160px;
  height: auto;
}

.line-box {
  min-height: 160px;
}

.node-rate-grid {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.node-rate-card {
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid rgba(103, 168, 227, 0.25);
  background: rgba(29, 58, 86, 0.5);
}

.node-rate-name {
  color: #d1e7ff;
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.node-rate-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 6px;
}

.node-rate-count {
  color: #9cc5ea;
  font-size: 12px;
}

.node-rate-badge {
  min-width: 50px;
  text-align: center;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 12px;
  font-weight: 700;
}

.node-rate-badge.is-high {
  color: #81f3bd;
  background: rgba(23, 108, 80, 0.35);
}

.node-rate-badge.is-mid {
  color: #ffd978;
  background: rgba(122, 92, 25, 0.35);
}

.node-rate-badge.is-low {
  color: #ff9fa3;
  background: rgba(126, 49, 53, 0.35);
}
</style>
