<template>
  <div class="inventory-overview">
    <el-row :gutter="20" class="metrics-row">
      <el-col :span="6">
        <el-card class="metric-card">
          <div class="metric-content">
            <div class="metric-icon" style="background-color: #409eff;">
              <i class="el-icon-box"></i>
            </div>
            <div class="metric-info">
              <div class="metric-label">总体库存量</div>
              <div class="metric-value">{{ overviewData.totalInventory }}</div>
              <div class="metric-unit">件</div>
              <div class="metric-sub">含组装转入 {{ overviewData.assemblyQty || 0 }} 件</div>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card class="metric-card">
          <div class="metric-content">
            <div class="metric-icon" style="background-color: #67c23a;">
              <i class="el-icon-money"></i>
            </div>
            <div class="metric-info">
              <div class="metric-label">库存价值</div>
              <div class="metric-value">{{ overviewData.totalValue }}</div>
              <div class="metric-unit">万元</div>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card class="metric-card">
          <div class="metric-content">
            <div class="metric-icon" style="background-color: #e6a23c;">
              <i class="el-icon-refresh"></i>
            </div>
            <div class="metric-info">
              <div class="metric-label">库存周转率</div>
              <div class="metric-value">{{ overviewData.turnoverRate }}</div>
              <div class="metric-unit">次</div>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card class="metric-card">
          <div class="metric-content">
            <div class="metric-icon" style="background-color: #f56c6c;">
              <i class="el-icon-truck"></i>
            </div>
            <div class="metric-info">
              <div class="metric-label">在途库存占比</div>
              <div class="metric-value">{{ overviewData.inTransitRatio }}</div>
              <div class="metric-unit">%</div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" class="upload-row">
      <el-col :span="24">
        <el-card class="upload-card">
          <template slot="header">
            <div class="card-header">
              <span>库存数据上传</span>
              <div class="card-actions">
                <el-button type="primary" size="small" @click="openUploadDialog">
                  <i class="el-icon-upload2"></i> 上传数据
                </el-button>
                <el-button size="small" @click="refreshData" :disabled="uploadTaskPolling">
                  <i class="el-icon-refresh"></i> 刷新
                </el-button>
              </div>
            </div>
          </template>
          <div class="upload-hint">
            支持上传入库、销售、组装、产品资料、半成品映射文件（xlsx/xls）。上传后会先创建后台任务，处理完成后自动刷新本页分析。
          </div>
          <div v-if="uploadTaskStatusText" class="upload-task-status">
            <el-tag :type="uploadTaskStatusType" size="mini">{{ uploadTaskStatusLabel }}</el-tag>
            <span>{{ uploadTaskStatusText }}</span>
          </div>
          <div v-if="lastUploadSummary" class="upload-summary">
            <el-tag type="success" size="mini">最近上传</el-tag>
            <span>{{ lastUploadSummary }}</span>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" class="charts-row">
      <el-col :span="24">
        <el-card>
          <template slot="header">
            <span>入库/销售/库存对比</span>
          </template>
          <div ref="inventoryComparisonChart" class="chart" />
          <el-empty v-if="!monthlyLoading && monthlyComparison.length === 0" description="暂无数据" />
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" class="charts-row">
      <el-col :span="24">
        <el-card>
          <template slot="header">
            <div class="card-header">
              <span>SKU指标汇总</span>
              <el-button type="primary" size="small" @click="refreshData" :disabled="uploadTaskPolling">
                <i class="el-icon-refresh"></i> 刷新
              </el-button>
            </div>
          </template>
          <el-table :data="skuTableData" stripe style="width: 100%" v-loading="loading">
            <el-table-column prop="sku" label="SKU" width="200" fixed />
            <el-table-column prop="attribute" label="属性" width="140">
              <template slot-scope="scope">
                {{ scope.row.attribute || '-' }}
              </template>
            </el-table-column>
            <el-table-column prop="spuName" label="SPU" width="200">
              <template slot-scope="scope">
                {{ scope.row.spuName || '-' }}
              </template>
            </el-table-column>
            <el-table-column prop="purchaseQty" label="入库数量" width="120" align="right">
              <template slot-scope="scope">
                {{ formatNumber(scope.row.purchaseQty) }}
              </template>
            </el-table-column>
            <el-table-column prop="salesQty" label="销售数量" width="120" align="right">
              <template slot-scope="scope">
                {{ formatNumber(scope.row.salesQty) }}
              </template>
            </el-table-column>
            <el-table-column prop="inventory" label="现有库存" width="120" align="right">
              <template slot-scope="scope">
                {{ formatNumber(scope.row.inventory) }}
              </template>
            </el-table-column>
            <el-table-column prop="purchaseAmount" label="入库总金额" width="150" align="right">
              <template slot-scope="scope">
                {{ formatNumber(scope.row.purchaseAmount) }}
              </template>
            </el-table-column>
            <el-table-column prop="amountRatio" label="入库资金占比(%)" width="150" align="right">
              <template slot-scope="scope">
                {{ scope.row.amountRatio }}%
              </template>
            </el-table-column>
            <el-table-column prop="turnoverRate" label="库存周转率" align="right">
              <template slot-scope="scope">
                <el-tag :type="getTurnoverRateType(scope.row.turnoverRate)">
                  {{ scope.row.turnoverRate }}
                </el-tag>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" class="charts-row">
      <el-col :span="24">
        <el-card>
          <template slot="header">
            <div class="card-header">
              <span>SPU指标汇总（成品）</span>
              <el-button type="primary" size="small" @click="refreshData" :disabled="uploadTaskPolling">
                <i class="el-icon-refresh"></i> 刷新
              </el-button>
            </div>
          </template>
          <el-table :data="spuTableData" stripe style="width: 100%" v-loading="spuLoading">
            <el-table-column prop="spu" label="SPU" width="220" fixed />
            <el-table-column prop="attribute" label="属性" width="140">
              <template slot-scope="scope">
                {{ scope.row.attribute || '-' }}
              </template>
            </el-table-column>
            <el-table-column prop="skuCount" label="SKU数" width="90" align="right" />
            <el-table-column prop="purchaseQty" label="入库数量" width="120" align="right">
              <template slot-scope="scope">
                {{ formatNumber(scope.row.purchaseQty) }}
              </template>
            </el-table-column>
            <el-table-column prop="salesQty" label="销售数量" width="120" align="right">
              <template slot-scope="scope">
                {{ formatNumber(scope.row.salesQty) }}
              </template>
            </el-table-column>
            <el-table-column prop="inventory" label="现有库存" width="120" align="right">
              <template slot-scope="scope">
                {{ formatNumber(scope.row.inventory) }}
              </template>
            </el-table-column>
            <el-table-column prop="purchaseAmount" label="入库总金额" width="150" align="right">
              <template slot-scope="scope">
                {{ formatNumber(scope.row.purchaseAmount) }}
              </template>
            </el-table-column>
            <el-table-column prop="amountRatio" label="入库资金占比(%)" width="150" align="right">
              <template slot-scope="scope">
                {{ scope.row.amountRatio }}%
              </template>
            </el-table-column>
            <el-table-column prop="turnoverRate" label="库存周转率" align="right">
              <template slot-scope="scope">
                <el-tag :type="getTurnoverRateType(scope.row.turnoverRate)">
                  {{ scope.row.turnoverRate }}
                </el-tag>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>

    <el-dialog
      title="上传库存分析数据"
      :visible.sync="uploadDialogVisible"
      width="720px"
      @close="resetUploadForm"
    >
      <el-alert
        type="info"
        show-icon
        :closable="false"
        title="至少上传入库数据与销售数据，组装/产品资料/半成品映射可选。"
        class="upload-alert"
      />
      <el-form label-width="110px" class="upload-form">
        <el-form-item label="入库数据">
          <div class="upload-field">
            <el-input v-model="uploadNames.purchase" placeholder="未选择文件" readonly />
            <el-button size="small" @click="triggerFile('purchase')">选择文件</el-button>
            <el-button v-if="uploadFiles.purchase" type="text" size="mini" @click="clearUploadFile('purchase')">清除</el-button>
          </div>
        </el-form-item>
        <el-form-item label="销售数据">
          <div class="upload-field">
            <el-input v-model="uploadNames.sales" placeholder="未选择文件" readonly />
            <el-button size="small" @click="triggerFile('sales')">选择文件</el-button>
            <el-button v-if="uploadFiles.sales" type="text" size="mini" @click="clearUploadFile('sales')">清除</el-button>
          </div>
        </el-form-item>
        <el-form-item label="组装数据">
          <div class="upload-field">
            <el-input v-model="uploadNames.assembly" placeholder="未选择文件" readonly />
            <el-button size="small" @click="triggerFile('assembly')">选择文件</el-button>
            <el-button v-if="uploadFiles.assembly" type="text" size="mini" @click="clearUploadFile('assembly')">清除</el-button>
          </div>
        </el-form-item>
        <el-form-item label="产品资料">
          <div class="upload-field">
            <el-input v-model="uploadNames.product" placeholder="未选择文件" readonly />
            <el-button size="small" @click="triggerFile('product')">选择文件</el-button>
            <el-button v-if="uploadFiles.product" type="text" size="mini" @click="clearUploadFile('product')">清除</el-button>
          </div>
        </el-form-item>
        <el-form-item label="半成品映射">
          <div class="upload-field">
            <el-input v-model="uploadNames.mapping" placeholder="未选择文件" readonly />
            <el-button size="small" @click="triggerFile('mapping')">选择文件</el-button>
            <el-button v-if="uploadFiles.mapping" type="text" size="mini" @click="clearUploadFile('mapping')">清除</el-button>
          </div>
        </el-form-item>
      </el-form>
      <input ref="purchaseInput" class="hidden-file-input" type="file" accept=".xlsx,.xls" @change="handleFileChange('purchase', $event)">
      <input ref="salesInput" class="hidden-file-input" type="file" accept=".xlsx,.xls" @change="handleFileChange('sales', $event)">
      <input ref="assemblyInput" class="hidden-file-input" type="file" accept=".xlsx,.xls" @change="handleFileChange('assembly', $event)">
      <input ref="productInput" class="hidden-file-input" type="file" accept=".xlsx,.xls" @change="handleFileChange('product', $event)">
      <input ref="mappingInput" class="hidden-file-input" type="file" accept=".xlsx,.xls" @change="handleFileChange('mapping', $event)">
      <span slot="footer" class="dialog-footer">
        <el-button @click="uploadDialogVisible = false" :disabled="uploadLoading">取消</el-button>
        <el-button type="primary" :loading="uploadLoading" @click="submitUpload">上传并处理</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import request from '@/utils/request'
import * as echarts from 'echarts'
require('echarts/theme/macarons')

const TASK_POLL_INTERVAL = 2000
const TASK_POLL_LIMIT = 120

export default {
  name: 'StorageOverview',
  data() {
    return {
      overviewData: {
        totalInventory: 0,
        totalValue: 0,
        turnoverRate: 0,
        inTransitRatio: 0,
        assemblyQty: 0
      },
      monthlyComparison: [],
      monthlyLoading: false,
      skuTableData: [],
      spuTableData: [],
      loading: false,
      spuLoading: false,
      chartInstance: null,
      uploadDialogVisible: false,
      uploadLoading: false,
      uploadFiles: {
        purchase: null,
        sales: null,
        assembly: null,
        product: null,
        mapping: null
      },
      uploadNames: {
        purchase: '',
        sales: '',
        assembly: '',
        product: '',
        mapping: ''
      },
      lastUploadSummary: '',
      uploadTaskId: '',
      uploadTaskStatus: '',
      uploadTaskStatusText: '',
      uploadTaskPolling: false
    }
  },
  computed: {
    uploadTaskStatusType() {
      if (this.uploadTaskStatus === 'success') return 'success'
      if (this.uploadTaskStatus === 'failed') return 'danger'
      if (this.uploadTaskStatus === 'running') return 'warning'
      return 'info'
    },
    uploadTaskStatusLabel() {
      if (this.uploadTaskStatus === 'success') return '处理完成'
      if (this.uploadTaskStatus === 'failed') return '处理失败'
      if (this.uploadTaskStatus === 'running') return '处理中'
      if (this.uploadTaskStatus === 'pending') return '排队中'
      return '任务状态'
    }
  },
  mounted() {
    this.refreshData()
    this.$nextTick(() => {
      this.initChart()
    })
    window.addEventListener('resize', this.resizeChart)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resizeChart)
    if (this.chartInstance) {
      this.chartInstance.dispose()
      this.chartInstance = null
    }
  },
  methods: {
    inventoryRequest(config) {
      return request({ timeout: 120000, ...config })
    },
    normalizeResponse(res) {
      if (!res) return null
      if (res.code === 200) return res.data
      if (res.data) return res.data
      return null
    },
    initChart() {
      if (this.chartInstance || !this.$refs.inventoryComparisonChart) return
      this.chartInstance = echarts.init(this.$refs.inventoryComparisonChart, 'macarons')
      this.updateMonthlyChart()
    },
    resizeChart() {
      if (this.chartInstance) this.chartInstance.resize()
    },
    updateMonthlyChart() {
      if (!this.chartInstance) return
      const months = []
      const purchase = []
      const sales = []
      const inventory = []

      if (Array.isArray(this.monthlyComparison) && this.monthlyComparison.length) {
        this.monthlyComparison.forEach(item => {
          months.push(item.month)
          purchase.push(item.purchase || 0)
          sales.push(item.sales || 0)
          inventory.push(item.inventory || 0)
        })
      }

      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' }
        },
        legend: { data: ['入库', '销售', '当前库存'] },
        grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
        xAxis: { type: 'category', data: months },
        yAxis: { type: 'value', name: '数量 (件)' },
        series: [
          { name: '入库', type: 'bar', data: purchase, itemStyle: { color: '#5470c6' } },
          { name: '销售', type: 'bar', data: sales, itemStyle: { color: '#91cc75' } },
          { name: '当前库存', type: 'line', data: inventory, itemStyle: { color: '#fac858' }, lineStyle: { width: 3 }, smooth: true }
        ]
      }
      this.chartInstance.setOption(option, true)
    },
    async fetchOverviewData() {
      try {
        const res = await this.inventoryRequest({ url: '/api/inventory/overview', method: 'get' })
        const data = this.normalizeResponse(res)
        if (data) this.overviewData = { ...this.overviewData, ...data }
      } catch (error) {
        console.error('获取总览数据失败:', error)
      }
    },
    async fetchMonthlyComparison() {
      this.monthlyLoading = true
      try {
        const res = await this.inventoryRequest({ url: '/api/inventory/monthly-comparison', method: 'get' })
        const data = this.normalizeResponse(res)
        if (data && Array.isArray(data.months)) {
          this.monthlyComparison = data.months.map((month, idx) => ({
            month,
            purchase: data.purchase ? data.purchase[idx] : 0,
            sales: data.sales ? data.sales[idx] : 0,
            inventory: data.inventory ? data.inventory[idx] : 0
          }))
        } else if (Array.isArray(data)) {
          this.monthlyComparison = data
        } else {
          this.monthlyComparison = []
        }
      } catch (error) {
        console.error('获取月度对比数据失败:', error)
      } finally {
        this.monthlyLoading = false
        this.$nextTick(() => this.updateMonthlyChart())
      }
    },
    async fetchSkuSummary() {
      this.loading = true
      try {
        const res = await this.inventoryRequest({ url: '/api/inventory/sku-summary', method: 'get' })
        const data = this.normalizeResponse(res)
        if (Array.isArray(data)) this.skuTableData = data
      } catch (error) {
        console.error('获取SKU汇总数据失败:', error)
      } finally {
        this.loading = false
      }
    },
    async fetchSpuSummary() {
      this.spuLoading = true
      try {
        const res = await this.inventoryRequest({ url: '/api/inventory/spu-summary', method: 'get' })
        const data = this.normalizeResponse(res)
        if (Array.isArray(data)) this.spuTableData = data
      } catch (error) {
        console.error('获取SPU汇总数据失败:', error)
      } finally {
        this.spuLoading = false
      }
    },
    async refreshData() {
      await this.fetchOverviewData()
      await this.fetchMonthlyComparison()
      await this.fetchSkuSummary()
      await this.fetchSpuSummary()
    },
    openUploadDialog() {
      this.uploadDialogVisible = true
    },
    triggerFile(type) {
      const refKey = `${type}Input`
      const input = this.$refs[refKey]
      if (input && input.click) {
        input.click()
      }
    },
    handleFileChange(type, event) {
      const file = event && event.target ? event.target.files[0] : null
      if (!file) {
        return
      }
      const name = (file.name || '').toLowerCase()
      if (!name.endsWith('.xlsx') && !name.endsWith('.xls')) {
        this.$message.error('仅支持上传 xlsx/xls 文件')
        if (event && event.target) event.target.value = ''
        return
      }
      this.uploadFiles[type] = file
      this.uploadNames[type] = file.name
      if (event && event.target) event.target.value = ''
    },
    clearUploadFile(type) {
      this.uploadFiles[type] = null
      this.uploadNames[type] = ''
    },
    resetUploadForm() {
      this.uploadFiles = {
        purchase: null,
        sales: null,
        assembly: null,
        product: null,
        mapping: null
      }
      this.uploadNames = {
        purchase: '',
        sales: '',
        assembly: '',
        product: '',
        mapping: ''
      }
      this.uploadLoading = false
    },
    hasUploadFiles() {
      return ['purchase', 'sales', 'assembly', 'product', 'mapping'].some(key => this.uploadFiles[key])
    },
    async submitUpload() {
      if (!this.hasUploadFiles()) {
        this.$message.error('请至少选择一个要上传的文件')
        return
      }
      const formData = new FormData()
      if (this.uploadFiles.purchase) formData.append('purchaseFile', this.uploadFiles.purchase)
      if (this.uploadFiles.sales) formData.append('salesFile', this.uploadFiles.sales)
      if (this.uploadFiles.assembly) formData.append('assemblyFile', this.uploadFiles.assembly)
      if (this.uploadFiles.product) formData.append('productFile', this.uploadFiles.product)
      if (this.uploadFiles.mapping) formData.append('semiMappingFile', this.uploadFiles.mapping)

      this.uploadLoading = true
      this.uploadTaskStatus = 'pending'
      this.uploadTaskStatusText = '文件上传中，请稍候'
      try {
        const res = await this.inventoryRequest({
          url: '/api/inventory/upload',
          method: 'post',
          data: formData,
          headers: { 'Content-Type': 'multipart/form-data', repeatSubmit: false },
          timeout: 300000
        })
        if (!(res && res.code === 200 && res.data && res.data.taskId)) {
          this.$message.error((res && res.msg) || '上传失败')
          this.uploadTaskStatus = 'failed'
          this.uploadTaskStatusText = (res && res.msg) || '上传失败'
          return
        }
        this.uploadTaskId = res.data.taskId
        this.uploadTaskStatus = res.data.status || 'pending'
        this.uploadTaskStatusText = res.data.message || '任务已创建，等待后台处理'
        this.lastUploadSummary = `已接收 ${res.data.count || 0} 个文件，任务ID：${this.uploadTaskId}`
        this.uploadDialogVisible = false
        this.resetUploadForm()
        this.$message.success('上传成功，后台正在处理库存数据')
        await this.pollUploadTask(this.uploadTaskId)
      } catch (error) {
        console.error('上传库存数据失败:', error)
        this.uploadTaskStatus = 'failed'
        this.uploadTaskStatusText = '上传失败，请检查文件格式或后端日志'
        this.$message.error('上传失败，请检查文件格式或后端日志')
      } finally {
        this.uploadLoading = false
      }
    },
    async pollUploadTask(taskId) {
      this.uploadTaskPolling = true
      try {
        for (let attempt = 0; attempt < TASK_POLL_LIMIT; attempt++) {
          const res = await this.inventoryRequest({
            url: `/api/inventory/upload-task/${taskId}`,
            method: 'get',
            timeout: 30000
          })
          const data = this.normalizeResponse(res)
          if (!data) {
            throw new Error((res && res.msg) || '任务状态获取失败')
          }
          this.uploadTaskStatus = data.status || 'pending'
          this.uploadTaskStatusText = data.message || '后台处理中'
          if (data.status === 'success') {
            this.lastUploadSummary = `已处理 ${data.count || 0} 个文件`
            this.$message.success('库存数据处理完成，已刷新分析结果')
            await this.refreshData()
            return
          }
          if (data.status === 'failed') {
            throw new Error(data.message || '库存数据处理失败')
          }
          await this.sleep(TASK_POLL_INTERVAL)
        }
        throw new Error('库存数据处理超时，请稍后手动刷新')
      } catch (error) {
        this.uploadTaskStatus = 'failed'
        this.uploadTaskStatusText = error.message || '库存数据处理失败'
        this.$message.error(this.uploadTaskStatusText)
      } finally {
        this.uploadTaskPolling = false
      }
    },
    sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms))
    },
    getTurnoverRateType(rate) {
      if (rate === 0) return 'info'
      if (rate >= 1) return 'success'
      if (rate >= 0.5) return 'warning'
      return 'danger'
    },
    formatNumber(value) {
      const num = Number(value || 0)
      return num.toLocaleString()
    }
  }
}
</script>

<style scoped>
.inventory-overview {
  width: 100%;
}

.metrics-row {
  margin-bottom: 20px;
}

.metric-card {
  cursor: pointer;
  transition: transform 0.3s;
}

.metric-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.metric-content {
  display: flex;
  align-items: center;
  gap: 15px;
}

.metric-icon {
  width: 60px;
  height: 60px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 28px;
}

.metric-info {
  flex: 1;
}

.metric-label {
  font-size: 14px;
  color: #909399;
  margin-bottom: 8px;
}

.metric-value {
  font-size: 28px;
  font-weight: bold;
  color: #303133;
  line-height: 1;
}

.metric-unit,
.metric-sub {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}

.charts-row {
  margin-bottom: 20px;
}

.upload-row {
  margin-bottom: 20px;
}

.upload-card .card-actions {
  display: flex;
  gap: 8px;
}

.upload-hint {
  font-size: 13px;
  color: #909399;
  line-height: 1.6;
}

.upload-task-status,
.upload-summary {
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  color: #606266;
}

.upload-form {
  margin-top: 16px;
}

.upload-field {
  display: flex;
  align-items: center;
  gap: 10px;
}

.hidden-file-input {
  display: none;
}

.upload-alert {
  margin-bottom: 12px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.chart {
  height: 300px;
}
</style>
