<template>
  <div class="app-container comparison-report" v-loading="loading">
    <!-- 查询条件 -->
    <el-card shadow="never" class="filter-card">
      <el-form label-width="70px" inline class="filter-form">
        <el-form-item label="产线">
          <el-select style="width: 150px;" v-model="actionTypes" placeholder="产线" clearable @change="handleQuery" size="small">
            <el-option label="全部" value="" />
            <el-option v-for="line in lineOptions" :key="line.value" :label="line.label" :value="line.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="品质">
          <muti-select v-model="queryParams.qualityStatusCsv" :options="dict.type.coil_quality_status"
            placeholder="品质" clearable style="width: 150px;" size="small" />
        </el-form-item>
        <el-form-item label="规格">
          <memo-input style="width: 130px;" v-model="queryParams.itemSpecification" storageKey="coilSpec"
            placeholder="规格" clearable size="small" @keyup.enter.native="handleQuery" />
        </el-form-item>
        <el-form-item label="材质">
          <muti-select style="width: 150px;" v-model="queryParams.itemMaterial" :options="dict.type.coil_material"
            placeholder="材质" clearable size="small" />
        </el-form-item>
        <el-form-item label="厂家">
          <muti-select style="width: 150px;" v-model="queryParams.itemManufacturer"
            :options="dict.type.coil_manufacturer" placeholder="厂家" clearable size="small" />
        </el-form-item>
        <el-form-item label="入场号">
          <el-input style="width: 150px;" v-model="queryParams.enterCoilNo" placeholder="入场钢卷号" clearable size="small"
            @keyup.enter.native="handleQuery" />
        </el-form-item>
      </el-form>
      <div class="time-row">
        <span class="time-label">基期</span>
        <el-date-picker style="width: 170px;" v-model="baseStartTime" type="datetime"
          value-format="yyyy-MM-dd HH:mm:ss" placeholder="开始" size="small" />
        <span class="time-sep">—</span>
        <el-date-picker style="width: 170px;" v-model="baseEndTime" type="datetime"
          value-format="yyyy-MM-dd HH:mm:ss" placeholder="结束" size="small" />
        <span class="time-label current-label">当期</span>
        <el-date-picker style="width: 170px;" v-model="currentStartTime" type="datetime"
          value-format="yyyy-MM-dd HH:mm:ss" placeholder="开始" size="small" />
        <span class="time-sep">—</span>
        <el-date-picker style="width: 170px;" v-model="currentEndTime" type="datetime"
          value-format="yyyy-MM-dd HH:mm:ss" placeholder="结束" size="small" />
        <el-button-group size="small" class="quick-btns">
          <el-button @click="setQuickCompare('prevDay')">日环比</el-button>
          <el-button @click="setQuickCompare('prevWeek')">周环比</el-button>
          <el-button @click="setQuickCompare('prevMonth')">月环比</el-button>
          <el-button @click="setQuickCompare('prevYear')">年环比</el-button>
        </el-button-group>
        <el-button type="primary" size="small" icon="el-icon-search" @click="handleQuery">查询</el-button>
        <el-button size="small" icon="el-icon-setting" @click="settingVisible = true">列配置</el-button>
      </div>
    </el-card>

    <!-- 口径说明 -->
    <el-alert type="info" :closable="false" class="explain-alert">
      <span slot="title">
        <strong>口径：</strong>数值环比 = (当期−基期)/|基期|×100%（<span class="color-up">红增</span>/<span class="color-down">绿降</span>）；百分比环比 = 当期百分点−基期百分点。 M卷（currentCoilNo含M且不在前五位）不计入产出。
      </span>
    </el-alert>

    <!-- 指标卡片 -->
    <div class="card-group">
      <div class="group-title">环比对比统计</div>
      <el-row :gutter="8">
        <el-col :span="6" v-for="item in comparisonItems" :key="item.key">
          <div class="kpi-card">
            <div class="kpi-label">{{ item.label }}</div>
            <div class="kpi-body">
              <span class="kpi-base">{{ item.base }}</span>
              <span class="kpi-arrow">→</span>
              <span class="kpi-current">{{ item.current }}</span>
            </div>
            <div class="kpi-rate" :style="{ color: item.rateColor }">{{ item.rate }}</div>
          </div>
        </el-col>
      </el-row>
    </div>

    <div class="card-group">
      <div class="group-title">已处理M统计信息对比</div>
      <el-row :gutter="8">
        <el-col :span="6" v-for="item in mComparisonItems" :key="item.key">
          <div class="kpi-card">
            <div class="kpi-label">{{ item.label }}</div>
            <div class="kpi-body">
              <span class="kpi-base">{{ item.base }}</span>
              <span class="kpi-arrow">→</span>
              <span class="kpi-current">{{ item.current }}</span>
            </div>
            <div class="kpi-rate" :style="{ color: item.rateColor }">{{ item.rate }}</div>
          </div>
        </el-col>
      </el-row>
    </div>

    <div class="card-group">
      <div class="group-title">异常库位统计对比</div>
      <el-row :gutter="8">
        <el-col :span="6" v-for="item in abComparisonItems" :key="item.key">
          <div class="kpi-card">
            <div class="kpi-label">{{ item.label }}</div>
            <div class="kpi-body">
              <span class="kpi-base">{{ item.base }}</span>
              <span class="kpi-arrow">→</span>
              <span class="kpi-current">{{ item.current }}</span>
            </div>
            <div class="kpi-rate" :style="{ color: item.rateColor }">{{ item.rate }}</div>
          </div>
        </el-col>
      </el-row>
    </div>

    <!-- 明细信息 -->
    <div class="detail-section">
      <div class="group-title">明细信息</div>
      <el-tabs v-model="activeTab" type="card">
        <el-tab-pane label="产出（当期）" name="currentOutput" />
        <el-tab-pane label="投入（当期）" name="currentLoss" />
        <el-tab-pane label="产出（基期）" name="baseOutput" />
        <el-tab-pane label="投入（基期）" name="baseLoss" />
      </el-tabs>
      <coil-table :data="activeDetailList" :total="activeDetailTotal" :page-num="activeDetailPageNum"
        :page-size="detailPageSize" :columns="activeDetailColumns" :loading="detailLoading"
        @size-change="handleDetailSizeChange"
        @current-change="handleDetailPageChange"
        height="calc(100vh - 500px)" />
    </div>

    <el-dialog title="列设置" :visible.sync="settingVisible" width="50%">
      <el-radio-group v-model="activeColumnConfig">
        <el-radio-button label="coil-report-loss">投入明细</el-radio-button>
        <el-radio-button label="coil-report-output">产出明细</el-radio-button>
      </el-radio-group>
      <columns-setting :reportType="activeColumnConfig" />
    </el-dialog>
  </div>
</template>

<script>
import { listLightCoil, listCoilWithIds } from "@/api/wms/coil";
import { listLightPendingAction } from '@/api/wms/pendingAction';
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import { calcSummary, calcMSummary, calcAbSummary } from "@/views/wms/report/js/calc";
import CoilTable from "@/views/wms/report/components/coilTable";
import ColumnsSetting from "@/views/wms/report/components/setting/columns";

export default {
  name: 'ComparisonReport',
  components: { MemoInput, MutiSelect, CoilTable, ColumnsSetting },
  dicts: ['product_coil_status', 'coil_material', 'coil_itemname', 'coil_manufacturer', 'coil_quality_status'],
  data() {
    const addZero = (num) => num.toString().padStart(2, '0')
    const now = new Date()
    const currentMonthStart = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}-01 00:00:00`
    const currentMonthEnd = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}-${addZero(now.getDate())} 23:59:59`
    const prevMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1)
    const prevMonthLastDay = new Date(now.getFullYear(), now.getMonth(), 0)
    const baseMonthStart = `${prevMonth.getFullYear()}-${addZero(prevMonth.getMonth() + 1)}-01 00:00:00`
    const baseMonthEnd = `${prevMonth.getFullYear()}-${addZero(prevMonth.getMonth() + 1)}-${addZero(Math.min(now.getDate(), prevMonthLastDay.getDate()))} 23:59:59`

    return {
      currentOutList: [], currentLossList: [], baseOutList: [], baseLossList: [],
      currentOutDetailList: [], currentOutDetailTotal: 0, currentOutPageNum: 1,
      currentLossDetailList: [], currentLossDetailTotal: 0, currentLossPageNum: 1,
      baseOutDetailList: [], baseOutDetailTotal: 0, baseOutPageNum: 1,
      baseLossDetailList: [], baseLossDetailTotal: 0, baseLossPageNum: 1,
      detailPageSize: 20,
      currentOutIds: '', currentLossActionIds: '', baseOutIds: '', baseLossActionIds: '',
      activeTab: 'currentOutput', activeColumnConfig: 'coil-report-output',
      settingVisible: false, loading: false, detailLoading: false,
      currentStartTime: currentMonthStart, currentEndTime: currentMonthEnd,
      baseStartTime: baseMonthStart, baseEndTime: baseMonthEnd,
      queryParams: { enterCoilNo: '', currentCoilNo: '', itemName: '', itemSpecification: '', itemMaterial: '', itemManufacturer: '', qualityStatusCsv: '' },
      lossColumns: [], outputColumns: [],
      actionTypes: '',
      lineOptions: [
        { label: '酸轧线', value: '11,120,201,520' }, { label: '镀锌线', value: '202,501,521' },
        { label: '双机架', value: '205,504,524' }, { label: '镀铬线', value: '206,505,525' },
        { label: '拉矫线', value: '204,503,523' }, { label: '脱脂线', value: '203,502,522' },
      ]
    }
  },
  computed: {
    summary() { return calcSummary(this.currentOutList, this.currentLossList) },
    baseSummary() { return calcSummary(this.baseOutList, this.baseLossList) },
    currentMSummary() { return calcMSummary(this.currentOutList, this.currentLossList) },
    baseMSummary() { return calcMSummary(this.baseOutList, this.baseLossList) },
    currentAbSummary() { return calcAbSummary(this.currentOutList) },
    baseAbSummary() { return calcAbSummary(this.baseOutList) },
    comparisonItems() {
      return this.buildComparisonItems(this.summary, this.baseSummary, [
        { key: 'outCount', label: '产出数量' }, { key: 'outTotalWeight', label: '产出总重(t)' }, { key: 'outAvgWeight', label: '产出均重(t)' },
        { key: 'lossCount', label: '消耗数量' }, { key: 'lossTotalWeight', label: '消耗总重(t)' }, { key: 'lossAvgWeight', label: '消耗均重(t)' },
        { key: 'totalCount', label: '合计数量' }, { key: 'totalWeight', label: '合计总重(t)' }, { key: 'totalAvgWeight', label: '合计均重(t)' },
        { key: 'countDiff', label: '数量差值' }, { key: 'weightDiff', label: '总重差值' }, { key: 'avgWeightDiff', label: '均重差值(t)' },
        { key: 'passRate', label: '成品率', isPercent: true }, { key: 'lossRate', label: '损耗率', isPercent: true },
        { key: 'abRate', label: '异常率', isPercent: true }, { key: 'passRate2', label: '正品率', isPercent: true },
      ])
    },
    mComparisonItems() {
      return this.buildComparisonItems(this.currentMSummary, this.baseMSummary, [
        { key: 'outCount', label: 'M-产出数量' }, { key: 'outTotalWeight', label: 'M-产出总重(t)' }, { key: 'outAvgWeight', label: 'M-产出均重(t)' },
        { key: 'lossCount', label: 'M-消耗数量' }, { key: 'lossTotalWeight', label: 'M-消耗总重(t)' }, { key: 'lossAvgWeight', label: 'M-消耗均重(t)' },
        { key: 'countDiff', label: 'M-数量差值' }, { key: 'weightDiff', label: 'M-总重差值' },
        { key: 'passRate', label: 'M-成品率', isPercent: true }, { key: 'lossRate', label: 'M-损耗率', isPercent: true },
        { key: 'abRate', label: 'M-异常率', isPercent: true }, { key: 'passRate2', label: 'M-正品率', isPercent: true },
      ])
    },
    abComparisonItems() {
      const cur = this.currentAbSummary, base = this.baseAbSummary
      const cm = {}, bm = {}
      cur.forEach(i => { cm[i.label] = i.value })
      base.forEach(i => { bm[i.label] = i.value })
      return ['技术部钢卷数','小钢卷库钢卷数','废品库钢卷数','退货库钢卷数',
        '技术部钢卷重量','小钢卷库钢卷重量','废品库钢卷重量','退货库钢卷重量',
        '技术部占比','小钢卷库占比','废品库占比','退货库占比'].map(label => {
        const { rate, rateColor } = this.calcSingleRate(cm[label] || 0, bm[label] || 0, label.includes('占比'))
        return { key: label, label, base: bm[label] || 0, current: cm[label] || 0, rate, rateColor }
      })
    },
    activeDetailList() {
      const m = { currentOutput: 'currentOutDetailList', currentLoss: 'currentLossDetailList', baseOutput: 'baseOutDetailList', baseLoss: 'baseLossDetailList' }
      return this[m[this.activeTab]] || []
    },
    activeDetailTotal() {
      const m = { currentOutput: 'currentOutDetailTotal', currentLoss: 'currentLossDetailTotal', baseOutput: 'baseOutDetailTotal', baseLoss: 'baseLossDetailTotal' }
      return this[m[this.activeTab]] || 0
    },
    activeDetailPageNum() {
      const m = { currentOutput: 'currentOutPageNum', currentLoss: 'currentLossPageNum', baseOutput: 'baseOutPageNum', baseLoss: 'baseLossPageNum' }
      return this[m[this.activeTab]] || 1
    },
    activeDetailColumns() {
      return this.activeTab.endsWith('Output') ? this.outputColumns : this.lossColumns
    },
  },
  created() { this.handleQuery(); this.loadColumns() },
  watch: {
    activeTab() { this.loadDetailData() }
  },
  methods: {
    calcSingleRate(curVal, baseVal, isPercent) {
      if (isPercent) {
        const cp = parseFloat(curVal) || 0, bp = parseFloat(baseVal) || 0, diff = (cp - bp).toFixed(2)
        return { rate: (diff >= 0 ? '+' : '') + diff + '%', rateColor: diff > 0 ? '#f56c6c' : diff < 0 ? '#67c23a' : '' }
      }
      const cv = parseFloat(curVal) || 0, bv = parseFloat(baseVal) || 0, diff = cv - bv
      let label = '0.00%'
      if (bv !== 0) { const r = ((cv - bv) / Math.abs(bv) * 100).toFixed(2); label = (r >= 0 ? '+' : '') + r + '%' }
      else if (cv !== 0) label = '+∞'
      return { rate: label, rateColor: diff > 0 ? '#f56c6c' : diff < 0 ? '#67c23a' : '' }
    },
    buildComparisonItems(current, base, itemDefs) {
      return itemDefs.map(item => {
        const { rate, rateColor } = this.calcSingleRate(current[item.key], base[item.key], item.isPercent)
        return { key: item.key, label: item.label, base: base[item.key], current: current[item.key], rate, rateColor }
      })
    },
    setQuickCompare(type) {
      const now = new Date(), addZero = n => n.toString().padStart(2, '0'), fd = d => `${d.getFullYear()}-${addZero(d.getMonth()+1)}-${addZero(d.getDate())}`
      switch (type) {
        case 'prevDay': {
          const y = new Date(now); y.setDate(y.getDate()-1)
          this.currentStartTime = `${fd(y)} 00:00:00`; this.currentEndTime = `${fd(y)} 23:59:59`
          const by = new Date(y); by.setDate(by.getDate()-1)
          this.baseStartTime = `${fd(by)} 00:00:00`; this.baseEndTime = `${fd(by)} 23:59:59`; break
        }
        case 'prevWeek': {
          const wa = new Date(now); wa.setDate(wa.getDate()-7)
          this.currentStartTime = `${fd(wa)} 00:00:00`; this.currentEndTime = `${fd(now)} 23:59:59`
          const twa = new Date(wa); twa.setDate(twa.getDate()-7)
          this.baseStartTime = `${fd(twa)} 00:00:00`; this.baseEndTime = `${fd(wa)} 23:59:59`; break
        }
        case 'prevMonth': {
          this.currentStartTime = `${fd(new Date(now.getFullYear(),now.getMonth(),1))} 00:00:00`; this.currentEndTime = `${fd(now)} 23:59:59`
          this.baseStartTime = `${fd(new Date(now.getFullYear(),now.getMonth()-1,1))} 00:00:00`; this.baseEndTime = `${fd(new Date(now.getFullYear(),now.getMonth(),0))} 23:59:59`; break
        }
        case 'prevYear': {
          this.currentStartTime = `${fd(new Date(now.getFullYear(),0,1))} 00:00:00`; this.currentEndTime = `${fd(now)} 23:59:59`
          this.baseStartTime = `${fd(new Date(now.getFullYear()-1,0,1))} 00:00:00`; this.baseEndTime = `${fd(new Date(now.getFullYear()-1,now.getMonth(),now.getDate()))} 23:59:59`; break
        }
      }
      this.handleQuery()
    },
    handleQuery() { this.currentOutPageNum = this.currentLossPageNum = this.baseOutPageNum = this.baseLossPageNum = 1; this.fetchData() },
    async fetchData() {
      this.loading = true
      const baseQuery = { enterCoilNo: this.queryParams.enterCoilNo, currentCoilNo: this.queryParams.currentCoilNo,
        itemName: this.queryParams.itemName, itemSpecification: this.queryParams.itemSpecification,
        itemMaterial: this.queryParams.itemMaterial, itemManufacturer: this.queryParams.itemManufacturer,
        qualityStatusCsv: this.queryParams.qualityStatusCsv }
      const mapItems = list => (list || []).map(item => {
        const [th, w] = item.specification?.split('*') || []
        return { ...item, computedThickness: parseFloat(th), computedWidth: parseFloat(w) }
      })
      const fetchPeriod = async (st, et) => {
        const p = { ...baseQuery, startTime: st, endTime: et, actionTypes: this.actionTypes, actionStatus: 2 }
        const acts = await listLightPendingAction(p)
        const oIds = acts.data.map(i => i.processedCoilIds).filter(Boolean).join(',')
        const lIds = acts.data.filter(i => i.coilId).map(i => i.coilId).join(',')
        if (!oIds || !lIds) return { outList: [], lossList: [], outIds: '', lossActionIds: '' }
        const [oRes, lRes] = await Promise.all([
          listLightCoil({ ...p, coilIds: oIds, startTime: '', endTime: '', byCreateTimeStart: st, byCreateTimeEnd: et, selectType: 'product', pageSize: 99999, pageNum: 1 }),
          listLightCoil({ ...p, coilIds: lIds, startTime: '', endTime: '', selectType: 'raw_material', pageSize: 99999, pageNum: 1 }),
        ])
        return { outList: mapItems(oRes), lossList: mapItems(lRes), outIds: oIds, lossActionIds: lIds }
      }
      const [cr, br] = await Promise.all([
        fetchPeriod(this.currentStartTime, this.currentEndTime),
        fetchPeriod(this.baseStartTime, this.baseEndTime),
      ])
      this.currentOutList = cr.outList; this.currentLossList = cr.lossList; this.baseOutList = br.outList; this.baseLossList = br.lossList
      this.currentOutIds = cr.outIds; this.currentLossActionIds = cr.lossActionIds; this.baseOutIds = br.outIds; this.baseLossActionIds = br.lossActionIds
      this.loading = false
      this.loadDetailData()
    },
    async loadDetailData() {
      const cfgMap = {
        currentOutput: { ids: 'currentOutIds', list: 'currentOutDetailList', total: 'currentOutDetailTotal', pn: 'currentOutPageNum', type: 'product' },
        currentLoss: { ids: 'currentLossActionIds', list: 'currentLossDetailList', total: 'currentLossDetailTotal', pn: 'currentLossPageNum', type: 'raw_material' },
        baseOutput: { ids: 'baseOutIds', list: 'baseOutDetailList', total: 'baseOutDetailTotal', pn: 'baseOutPageNum', type: 'product' },
        baseLoss: { ids: 'baseLossActionIds', list: 'baseLossDetailList', total: 'baseLossDetailTotal', pn: 'baseLossPageNum', type: 'raw_material' },
      }
      const c = cfgMap[this.activeTab]
      if (!c) return
      this.detailLoading = true
      if (!this[c.ids]) {
        this[c.list] = []; this[c.total] = 0; this.detailLoading = false; return
      }
      const isOut = c.type === 'product'
      const res = await listCoilWithIds(isOut
        ? { ...this.queryParams, coilIds: this[c.ids], selectType: 'product', pageSize: this.detailPageSize, pageNum: this[c.pn] }
        : { ...this.queryParams, actionIds: this[c.ids], selectType: 'raw_material', pageSize: this.detailPageSize, pageNum: this[c.pn] })
      this[c.list] = (res.rows || []).map(item => {
        const [th, w] = item.specification?.split('*') || []
        return { ...item, computedThickness: parseFloat(th), computedWidth: parseFloat(w) }
      })
      this[c.total] = res.total || 0; this.detailLoading = false
    },
    handleDetailPageChange(page) { this[this.activeTab + 'PageNum'] = page; this.loadDetailData() },
    handleDetailSizeChange(size) { this.detailPageSize = size; this[this.activeTab + 'PageNum'] = 1; this.loadDetailData() },
    loadColumns() {
      this.lossColumns = JSON.parse(localStorage.getItem('preference-tableColumns-coil-report-loss') || '[]') || []
      this.outputColumns = JSON.parse(localStorage.getItem('preference-tableColumns-coil-report-output') || '[]') || []
    }
  }
}
</script>

<style scoped>
.comparison-report { min-width: 900px; }
.filter-card { margin-bottom: 8px; }
.filter-card >>> .el-card__body { padding: 8px 12px 8px; }
.filter-form { margin-bottom: 0; }
.filter-form .el-form-item { margin-bottom: 6px; margin-right: 4px; }
.filter-form >>> .el-form-item__label { font-size: 12px; }
.time-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding-top: 6px; border-top: 1px solid #eee; }
.time-label { font-size: 12px; color: #909399; font-weight: 600; }
.current-label { color: #409eff; }
.time-sep { color: #c0c4cc; font-size: 12px; }
.quick-btns { margin-left: auto; }
.explain-alert { margin-bottom: 8px; }
.explain-alert >>> .el-alert__title { font-size: 12px; line-height: 1.5; }
.color-up { color: #f56c6c; }
.color-down { color: #67c23a; }

.card-group { margin-bottom: 10px; }
.group-title { font-size: 13px; font-weight: 600; color: #303133; padding: 5px 0; margin-bottom: 6px; border-bottom: 2px solid #409eff; }
.kpi-card { background: #fafbfc; border: 1px solid #e8eaed; border-radius: 4px; padding: 10px 12px; text-align: center; transition: box-shadow .15s; }
.kpi-card:hover { box-shadow: 0 2px 6px rgba(0,0,0,.06); }
.kpi-label { font-size: 12px; color: #909399; margin-bottom: 4px; }
.kpi-body { font-size: 15px; font-weight: 600; margin-bottom: 2px; display: flex; align-items: center; justify-content: center; gap: 6px; }
.kpi-arrow { color: #c0c4cc; font-size: 12px; }
.kpi-base { color: #909399; }
.kpi-current { color: #409eff; }
.kpi-rate { font-size: 13px; font-weight: 600; }

.detail-section { margin-top: 8px; }
.detail-section >>> .el-tabs__header { margin-bottom: 4px; }
.detail-section >>> .el-tabs__item { font-size: 12px; height: 32px; line-height: 32px; }
</style>
