<template>
  <div class="factory-calendar-page app-container" v-loading="loading">
    <div class="toolbar-row">
      <el-form :inline="true" size="small" class="filter-row">
        <el-form-item label="年份">
          <el-date-picker
            v-model="query.year"
            type="year"
            value-format="yyyy"
            placeholder="选择年份"
            style="width: 120px"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" @click="handleRefresh">查询</el-button>
          <el-button icon="el-icon-refresh" @click="handleRefresh">刷新</el-button>
        </el-form-item>
      </el-form>

      <div class="month-strip">
        <el-button
          v-for="m in monthOptions"
          :key="`m-${m}`"
          size="mini"
          :type="query.monthNum === m ? 'primary' : 'default'"
          plain
          class="month-btn"
          @click="selectMonth(m)"
        >
          {{ m }}月
        </el-button>
      </div>
    </div>

    <div class="stats-row">
      <div class="stat-card">
        <div class="k"><i class="el-icon-s-operation" />任务总数</div>
        <div class="v">{{ overview.taskCount }}</div>
      </div>
      <div class="stat-card">
        <div class="k"><i class="el-icon-data-line" />活跃产线</div>
        <div class="v">{{ overview.activeLineCount }} / {{ overview.totalLineCount }}</div>
      </div>
      <div class="stat-card">
        <div class="k"><i class="el-icon-time" />排产总工时</div>
        <div class="v">{{ overview.totalHours }}</div>
      </div>
      <div class="stat-card">
        <div class="k"><i class="el-icon-date" />峰值日</div>
        <div class="v">{{ overview.peakDayText }}</div>
      </div>
      <div class="stat-card">
        <div class="k"><i class="el-icon-s-flag" />最忙产线</div>
        <div class="v">{{ overview.busiestLineText }}</div>
      </div>
      <div class="stat-card">
        <div class="k"><i class="el-icon-collection-tag" />最忙产线-班组</div>
        <div class="v">{{ overview.busiestLineShiftText }}</div>
      </div>
    </div>

    <div class="calendar-block">
      <div class="block-head">
        <div class="block-title">产线日历</div>
        <div class="legend">
          <span class="legend-item"><i class="dot work" />工作日</span>
          <span class="legend-item"><i class="dot rest" />休息日</span>
        </div>
      </div>
      <el-tabs v-model="activeLineTab" type="card" class="sub-tabs" v-if="lineRows.length">
        <el-tab-pane
          v-for="line in lineRows"
          :key="`line-tab-${line.lineId}`"
          :name="String(line.lineId)"
          :label="line.lineName"
        >
          <div class="calendar-full">
            <div class="week-head">
              <span v-for="w in weekLabels" :key="`line-week-${line.lineId}-${w}`">{{ w }}</span>
            </div>
            <div class="month-grid">
              <div
                v-for="cell in monthCells"
                :key="`line-${line.lineId}-${cell.key}`"
                class="day-cell"
                :class="[cell.isCurrentMonth ? 'cur' : 'other', lineDayClass(line.lineId, cell.date), dayExtraClass(cell)]"
              >
                <div class="day-no">{{ cell.day }}</div>
                <template v-if="cell.isCurrentMonth">
                  <div class="task-count">{{ getLineDay(line.lineId, cell.date).taskCount }} 单</div>
                  <div
                    v-for="(t, idx) in tasksByLineDate(line.lineId, cell.date).slice(0, 3)"
                    :key="`line-${line.lineId}-${cell.date}-${idx}`"
                    class="task-item"
                    :title="taskLabel(t)"
                  >
                    {{ shortTaskWithShift(t) }}
                  </div>
                  <div class="more" v-if="getLineDay(line.lineId, cell.date).taskCount > 3">+{{ getLineDay(line.lineId, cell.date).taskCount - 3 }}</div>
                </template>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
      <el-empty v-else description="暂无产线数据" />
    </div>

    <div class="calendar-block">
      <div class="block-head">
        <div class="block-title">产线-班组日历</div>
        <div class="legend">
          <span class="legend-item"><i class="dot work" />工作日</span>
          <span class="legend-item"><i class="dot rest" />休息日</span>
        </div>
      </div>
      <el-tabs v-model="activeLineShiftTab" type="card" class="sub-tabs" v-if="lineShiftRows.length">
        <el-tab-pane
          v-for="item in lineShiftRows"
          :key="`ls-tab-${item.lineId}-${item.shiftId}`"
          :name="`${item.lineId}-${item.shiftId}`"
          :label="`${item.lineName} · ${item.shiftName}`"
        >
          <div class="calendar-full">
            <div class="week-head">
              <span v-for="w in weekLabels" :key="`ls-week-${item.lineId}-${item.shiftId}-${w}`">{{ w }}</span>
            </div>
            <div class="month-grid">
              <div
                v-for="cell in monthCells"
                :key="`ls-${item.lineId}-${item.shiftId}-${cell.key}`"
                class="day-cell"
                :class="[cell.isCurrentMonth ? 'cur' : 'other', lineShiftDayClass(item.lineId, item.shiftId, cell.date), dayExtraClass(cell)]"
              >
                <div class="day-no">{{ cell.day }}</div>
                <template v-if="cell.isCurrentMonth">
                  <div class="task-count">{{ getLineShiftDay(item.lineId, item.shiftId, cell.date).taskCount }} 单</div>
                  <div
                    v-for="(t, idx) in tasksByLineShiftDate(item.lineId, item.shiftId, cell.date).slice(0, 3)"
                    :key="`ls-${item.lineId}-${item.shiftId}-${cell.date}-${idx}`"
                    class="task-item"
                    :title="taskLabel(t)"
                  >
                    {{ shortTask(t) }}
                  </div>
                  <div class="more" v-if="getLineShiftDay(item.lineId, item.shiftId, cell.date).taskCount > 3">+{{ getLineShiftDay(item.lineId, item.shiftId, cell.date).taskCount - 3 }}</div>
                </template>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
      <el-empty v-else description="暂无产线-班组数据" />
    </div>
  </div>
</template>

<script>
import { fetchFactoryCalendar } from '@/api/aps/aps'

export default {
  name: 'ApsFactoryCalendarPage',
  data() {
    return {
      loading: false,
      query: { year: String(new Date().getFullYear()), monthNum: new Date().getMonth() + 1 },
      monthOptions: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
      weekLabels: ['日', '一', '二', '三', '四', '五', '六'],
      activeLineTab: '',
      activeLineShiftTab: '',
      payload: {
        overview: {},
        dateList: [],
        lineNameMap: {},
        shiftNameMap: {},
        lineDayMap: {},
        lineShiftDayMap: {}
      },
      legendVisible: true
    }
  },
  computed: {
    monthText() {
      return `${this.query.year}-${`${this.query.monthNum}`.padStart(2, '0')}`
    },
    lineRows() {
      return Object.keys(this.payload.lineNameMap || {}).map(id => ({ lineId: String(id), lineName: this.payload.lineNameMap[id] }))
    },
    lineShiftRows() {
      const rows = []
      Object.keys(this.payload.lineNameMap || {}).forEach(lineId => {
        Object.keys(this.payload.shiftNameMap || {}).forEach(shiftId => {
          rows.push({
            lineId: String(lineId),
            lineName: this.payload.lineNameMap[lineId],
            shiftId: String(shiftId),
            shiftName: this.payload.shiftNameMap[shiftId]
          })
        })
      })
      return rows
    },
    monthRange() {
      const y = Number((this.query.year || '').toString())
      const m = Number(this.query.monthNum || 0)
      if (!y || !m) return { start: '', end: '' }
      const start = new Date(y, m - 1, 1)
      const end = new Date(y, m, 0)
      return { start: this.formatDate(start), end: this.formatDate(end) }
    },
    monthCells() {
      const { start, end } = this.monthRange
      if (!start || !end) return []
      const startDate = new Date(`${start} 00:00:00`)
      const endDate = new Date(`${end} 00:00:00`)
      const firstWeekDay = startDate.getDay()
      const cells = []
      const prefixStart = new Date(startDate.getTime())
      prefixStart.setDate(prefixStart.getDate() - firstWeekDay)
      const totalDays = Math.ceil((endDate.getTime() - prefixStart.getTime()) / 86400000) + 1
      const totalCells = Math.ceil(totalDays / 7) * 7
      for (let i = 0; i < totalCells; i++) {
        const d = new Date(prefixStart.getTime())
        d.setDate(prefixStart.getDate() + i)
        const date = this.formatDate(d)
        cells.push({ key: `${date}-${i}`, date, day: d.getDate(), isCurrentMonth: date >= start && date <= end })
      }
      return cells
    },
    overview() {
      return this.payload.overview || {
        taskCount: 0,
        activeLineCount: 0,
        totalLineCount: 0,
        totalHours: '0.0',
        peakDayText: '-',
        busiestLineText: '-',
        busiestLineShiftText: '-'
      }
    }
  },
  created() {
    this.handleRefresh()
  },
  methods: {
    selectMonth(m) {
      this.query.monthNum = m
      this.handleRefresh()
    },
    formatDate(d) {
      const y = d.getFullYear()
      const m = `${d.getMonth() + 1}`.padStart(2, '0')
      const day = `${d.getDate()}`.padStart(2, '0')
      return `${y}-${m}-${day}`
    },
    async handleRefresh() {
      const { start, end } = this.monthRange
      if (!start || !end) {
        this.$message.warning('请先选择月份')
        return
      }
      this.loading = true
      try {
        const res = await fetchFactoryCalendar({ queryStart: `${start} 00:00:00`, queryEnd: `${end} 23:59:59` })
        this.payload = res.data || {
          overview: {}, dateList: [], lineNameMap: {}, shiftNameMap: {}, lineDayMap: {}, lineShiftDayMap: {}
        }
        if (this.lineRows.length && !this.lineRows.find(i => String(i.lineId) === this.activeLineTab)) {
          this.activeLineTab = String(this.lineRows[0].lineId)
        }
        if (this.lineShiftRows.length && !this.lineShiftRows.find(i => `${i.lineId}-${i.shiftId}` === this.activeLineShiftTab)) {
          this.activeLineShiftTab = `${this.lineShiftRows[0].lineId}-${this.lineShiftRows[0].shiftId}`
        }
      } finally {
        this.loading = false
      }
    },
    getLineDay(lineId, date) {
      const key = `${String(lineId)}|${date}`
      const m = this.payload.lineDayMap || {}
      const found = m[key]
      return found || { taskCount: 0, shiftCount: 0, tasks: [] }
    },
    getLineShiftDay(lineId, shiftId, date) {
      const key = `${String(lineId)}|${String(shiftId)}|${date}`
      const m = this.payload.lineShiftDayMap || {}
      const found = m[key]
      return found || { taskCount: 0, lineCount: 0, tasks: [] }
    },
    tasksByLineDate(lineId, date) {
      return this.getLineDay(lineId, date).tasks || []
    },
    tasksByLineShiftDate(lineId, shiftId, date) {
      return this.getLineShiftDay(lineId, shiftId, date).tasks || []
    },
    taskLabel(task) {
      return task && task.title ? task.title : '-'
    },
    shortTask(task) {
      return task && task.label ? task.label : '-'
    },
    shortTaskWithShift(task) {
      return this.shortTask(task)
    },
    lineDayClass(lineId, date) {
      const day = this.getLineDay(lineId, date)
      if (day.dayStatus === 1) return 'workday'
      if (day.dayStatus === 0) return 'restday'
      return day.taskCount > 0 ? 'workday' : 'neutral'
    },
    lineShiftDayClass(lineId, shiftId, date) {
      const day = this.getLineShiftDay(lineId, shiftId, date)
      if (day.dayStatus === 1) return 'workday'
      if (day.dayStatus === 0) return 'restday'
      return day.taskCount > 0 ? 'workday' : 'neutral'
    },
    dayExtraClass(cell) {
      const classes = []
      const d = new Date(`${cell.date} 00:00:00`)
      const week = d.getDay()
      if (week === 0 || week === 6) classes.push('is-weekend')
      const today = this.formatDate(new Date())
      if (cell.date === today) classes.push('is-today')
      return classes.join(' ')
    }
  }
}
</script>

<style scoped lang="scss">
.factory-calendar-page {
  padding: 12px;
}

.toolbar-row {
  background: #fff;
  border: 1px solid #e9edf3;
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
}

.filter-row {
  margin: 0 0 10px;
}

::v-deep .filter-row .el-date-editor.el-input,
::v-deep .filter-row .el-date-editor.el-input__inner {
  width: 120px !important;
}

::v-deep .filter-row .el-input__inner {
  border-radius: 8px;
  border-color: #d7deea;
}

::v-deep .filter-row .el-input__inner:focus {
  border-color: #7aa9ff;
}

.month-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.month-btn {
  min-width: 56px;
}

.stats-row {
  display: grid;
  grid-template-columns: repeat(6, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}

.stat-card {
  padding: 10px 12px;
  border: 1px solid #e9edf3;
  border-radius: 10px;
  background: #fff;
}

.stat-card .k {
  font-size: 12px;
  color: #8b95a7;
}

.stat-card .v {
  margin-top: 6px;
  font-size: 18px;
  line-height: 1.2;
  font-weight: 700;
  color: #1f2d3d;
}

.calendar-block {
  margin-bottom: 14px;
  background: #fff;
  border: 1px solid #e9edf3;
  border-radius: 10px;
  padding: 10px;
}

.block-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.block-title {
  font-size: 14px;
  color: #1f2d3d;
  font-weight: 700;
}

.legend {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  color: #6b7280;
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.dot {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  display: inline-block;
  border: 1px solid #e5e7eb;
}

.dot.work {
  background: #edf8ee;
}

.dot.rest {
  background: #fff2e6;
}

::v-deep .sub-tabs .el-tabs__header {
  margin-bottom: 10px;
  border: none;
}

::v-deep .sub-tabs .el-tabs__nav-wrap,
::v-deep .sub-tabs .el-tabs__nav-scroll,
::v-deep .sub-tabs .el-tabs__nav {
  border: none !important;
  background: transparent;
}

::v-deep .sub-tabs .el-tabs__item {
  border-radius: 16px;
  margin-right: 8px;
  border: 1px solid #dbe3ef !important;
  background: #fff;
  height: 30px;
  line-height: 30px;
  padding: 0 12px;
  color: #4a5668;
  transition: all .2s;
}

::v-deep .sub-tabs .el-tabs__item:hover {
  color: #2f7df6;
  border-color: #b8d3ff !important;
}

::v-deep .sub-tabs .el-tabs__item.is-active {
  color: #2f7df6;
  background: #eef5ff;
  border-color: #bfd8ff !important;
  font-weight: 600;
}

::v-deep .sub-tabs .el-tabs__item:last-child {
  margin-right: 0;
}

::v-deep .sub-tabs .el-tabs__nav-wrap::after,
::v-deep .sub-tabs .el-tabs__active-bar {
  display: none !important;
}

.calendar-full {
  width: 100%;
}

.week-head {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  border: 1px solid #edf1f6;
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  overflow: hidden;
}

.week-head span {
  text-align: center;
  padding: 8px 0;
  font-size: 12px;
  color: #7d8797;
  background: #fafcff;
  border-right: 1px solid #edf1f6;
}

.week-head span:last-child {
  border-right: none;
}

.month-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  border-left: 1px solid #edf1f6;
  border-top: 1px solid #edf1f6;
}

.day-cell {
  height: 120px;
  padding: 8px;
  border-right: 1px solid #edf1f6;
  border-bottom: 1px solid #edf1f6;
  box-sizing: border-box;
  background: #fff;
}

.day-cell.other {
  background: #fafbfd;
  color: #c4cad4;
}

.day-cell.cur.workday {
  background: #edf8ee;
}

.day-cell.cur.restday {
  background: #fff2e6;
}

.day-cell.is-today {
  box-shadow: inset 0 0 0 2px #7aa9ff;
}

.day-cell.is-weekend .day-no {
  color: #5f84c9;
}

.day-no {
  font-size: 11px;
  color: #8f99aa;
  margin-bottom: 6px;
}

.task-count {
  font-size: 12px;
  color: #1f2d3d;
  font-weight: 700;
  margin-bottom: 4px;
}

.task-item {
  font-size: 11px;
  color: #4c596d;
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.more {
  font-size: 10px;
  color: #9aa5b5;
  margin-top: 3px;
}</style>
