<template>
  <div class="month-on-month-analysis">
    <!-- 筛选区域：周/月/年切换 + 单周期选择 -->
    <div class="filter-section">
      <el-row :gutter="20" align="middle">
        <!-- 时间类型切换（默认选中“按周”） -->
        <el-col :span="6">
          <el-select 
            v-model="timeType" 
            placeholder="请选择时间类型"
            @change="handleTimeTypeChange"
            clearable
          >
            <el-option label="按周" value="week"></el-option>
            <el-option label="按月" value="month"></el-option>
            <el-option label="按年" value="year"></el-option>
          </el-select>
        </el-col>
        
        <!-- 日期选择器（单周期选择，非范围） -->
        <el-col :span="12">
          <!-- 1. 按周：单周选择器 -->
          <el-date-picker
            v-if="timeType === 'week'"
            v-model="dateRange"
            type="date"
            placeholder="选择周"
            format="yyyy年第WW周"
            value-format="yyyy-'W'WW"
            picker-options="{ type: 'week' }"
            :disabled-date="disableFutureDate"
          ></el-date-picker>

          <!-- 2. 按月：单月选择器 -->
          <el-date-picker
            v-else-if="timeType === 'month'"
            v-model="dateRange"
            type="date"
            placeholder="选择月"
            format="yyyy-MM"
            value-format="yyyy-MM"
            picker-options="{ type: 'month' }"
            :disabled-date="disableFutureDate"
          ></el-date-picker>

          <!-- 3. 按年：单年选择器 -->
          <el-date-picker
            v-else-if="timeType === 'year'"
            v-model="dateRange"
            type="date"
            placeholder="选择年"
            format="yyyy"
            value-format="yyyy"
            picker-options="{ type: 'year' }"
            :disabled-date="disableFutureDate"
          ></el-date-picker>
        </el-col>
        
        <!-- 查询/重置按钮（无选择时禁用查询） -->
        <el-col :span="6">
          <el-button type="primary" @click="handleQuery" :disabled="!dateRange">查询</el-button>
          <el-button type="text" @click="handleReset" style="margin-left: 10px;">重置</el-button>
        </el-col>
      </el-row>
    </div>
    
    <!-- 加载状态 -->
    <div v-if="loading" class="loading-container">
      <el-loading-spinner></el-loading-spinner>
      <p>数据加载中...</p>
    </div>
    
    <!-- 环比指标卡区域（保持原有展示逻辑） -->
    <div v-else class="indicator-cards">
      <el-row :gutter="20">
        <!-- 当期值 -->
        <el-col :span="6">
          <div class="indicator-card">
            <div class="card-header">
              <span class="card-title">当期值</span>
              <span class="card-period">{{ currentPeriodText }}</span>
            </div>
            <div class="card-value">{{ formatNumber(currentValue) }} {{ unit }}</div>
            <div class="card-desc">当前{{ timeTypeMap[timeType] }}的{{ indicatorName }}</div>
          </div>
        </el-col>
        
        <!-- 上期值 -->
        <el-col :span="6">
          <div class="indicator-card">
            <div class="card-header">
              <span class="card-title">上期值</span>
              <span class="card-period">{{ previousPeriodText }}</span>
            </div>
            <div class="card-value">{{ formatNumber(previousValue) }} {{ unit }}</div>
            <div class="card-desc">上一个{{ timeTypeMap[timeType] }}的{{ indicatorName }}</div>
          </div>
        </el-col>
        
        <!-- 增加值 -->
        <el-col :span="6">
          <div class="indicator-card">
            <div class="card-header">
              <span class="card-title">增加值</span>
              <span class="card-icon"><i class="el-icon-arrow-right"></i></span>
            </div>
            <div class="card-value" :class="increaseValue > 0 ? 'text-increase' : increaseValue < 0 ? 'text-decrease' : ''">
              {{ formatNumber(increaseValue) }} {{ unit }}
            </div>
            <div class="card-desc">当期 - 上期</div>
          </div>
        </el-col>
        
        <!-- 环比 -->
        <el-col :span="6">
          <div class="indicator-card">
            <div class="card-header">
              <span class="card-title">环比</span>
              <span class="card-icon"><i class="el-icon-refresh"></i></span>
            </div>
            <div class="card-value" :class="monthOnMonth > 0 ? 'text-increase' : monthOnMonth < 0 ? 'text-decrease' : ''">
              {{ monthOnMonth !== null ? (monthOnMonth * 100).toFixed(2) + '%' : '--' }}
            </div>
            <div class="card-desc">（当期 - 上期）/ 上期 × 100%</div>
          </div>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
export default {
  name: 'CycleAnalysis',
  props: {
    // 数据单位（如：kWh、Nm³、元）
    unit: {
      type: String,
      default: 'kWh'
    },
    // 指标名称（如：能耗、费用、产量）
    indicatorName: {
      type: String,
      default: '能耗'
    }
  },
  data() {
    return {
      // 时间类型：默认按周（week）
      timeType: 'week',
      // 单周期选择值（格式：week→yyyy-Www，month→yyyy-MM，year→yyyy）
      dateRange: '',
      // 加载状态
      loading: false,
      // 核心数据
      currentValue: null,  // 当期值
      previousValue: null, // 上期值
      increaseValue: null, // 增加值（当期-上期）
      monthOnMonth: null,  // 环比（(当期-上期)/上期）
      // 周期文本描述（如：2025年第23周、2025年06月）
      currentPeriodText: '',
      previousPeriodText: '',
      // 时间类型映射（用于文案显示）
      timeTypeMap: {
        week: '周',
        month: '月',
        year: '年'
      }
    }
  },
  mounted() {
    // 初始化默认周期（当前周/月/年）+ 自动查询一次
    this.initDateRange()
    this.handleQuery()
  },
  methods: {
    /**
     * 初始化默认周期（当前时间类型的当前周期）
     */
    initDateRange() {
      const now = new Date()
      const year = now.getFullYear()
      let currentPeriod

      switch (this.timeType) {
        case 'week':
          // 周格式：yyyy-Www（两位周数）
          const [currentWeek] = this.getWeekInfo(now)
          currentPeriod = `${year}-W${this.padZero(currentWeek)}`
          break

        case 'month':
          // 月格式：yyyy-MM（两位月份）
          const currentMonth = now.getMonth() + 1
          currentPeriod = `${year}-${this.padZero(currentMonth)}`
          break

        case 'year':
          // 年格式：yyyy
          currentPeriod = `${year}`
          break
      }

      this.dateRange = currentPeriod
      // 同步更新周期文本（当期+上期）
      this.updatePeriodText()
    },

    /**
     * 获取周信息（本年周数 + 周起始日期）
     * @param {Date} date - 日期对象
     * @returns {Array} [周数, 周起始日期（Date）]
     */
    getWeekInfo(date) {
      const firstDayOfYear = new Date(date.getFullYear(), 0, 1)
      const pastDaysOfYear = (date - firstDayOfYear) / (24 * 60 * 60 * 1000)
      // 周日为一周第一天，计算本年周数
      const weekNumber = Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7)
      // 计算当前周的起始日期（周日）
      const weekStart = new Date(date)
      weekStart.setDate(date.getDate() - date.getDay())
      return [weekNumber, weekStart]
    },

    /**
     * 计算上期周期（根据当前周期自动推导）
     * @param {String} currentPeriod - 当前周期（如：2025-W23、2025-06、2025）
     * @param {String} timeType - 时间类型（week/month/year）
     * @returns {String} 上期周期
     */
    getPreviousPeriod(currentPeriod, timeType) {
      const [year, part] = currentPeriod.split(
        timeType === 'week' ? '-W' : timeType === 'month' ? '-' : ''
      )
      let prevYear = parseInt(year)
      let prevPart

      switch (timeType) {
        case 'week':
          const currentWeek = parseInt(part)
          // 若当前是第1周，上期为上一年最后一周
          if (currentWeek === 1) {
            prevYear -= 1
            prevPart = this.getLastWeekOfYear(prevYear)
          } else {
            prevPart = currentWeek - 1
          }
          return `${prevYear}-W${this.padZero(prevPart)}`

        case 'month':
          const currentMonth = parseInt(part)
          // 若当前是1月，上期为上一年12月
          if (currentMonth === 1) {
            prevYear -= 1
            prevPart = 12
          } else {
            prevPart = currentMonth - 1
          }
          return `${prevYear}-${this.padZero(prevPart)}`

        case 'year':
          // 上期为上一年
          return `${prevYear - 1}`
      }
    },

    /**
     * 获取某一年的最后一周（处理跨年周场景）
     * @param {Number} year - 年份
     * @returns {Number} 最后一周的周数
     */
    getLastWeekOfYear(year) {
      const lastDayOfYear = new Date(year, 11, 31) // 12月31日
      const [lastWeek] = this.getWeekInfo(lastDayOfYear)
      return lastWeek
    },

    /**
     * 将周期转换为时间段（startDate ~ endDate，格式：yyyy-MM-dd）
     * @param {String} period - 周期（如：2025-W23、2025-06、2025）
     * @param {String} timeType - 时间类型（week/month/year）
     * @returns {Object} { start: 开始日期, end: 结束日期 }
     */
    getPeriodTimeRange(period, timeType) {
      let startDate, endDate
      const [year, part] = period.split(
        timeType === 'week' ? '-W' : timeType === 'month' ? '-' : ''
      )
      const targetYear = parseInt(year)

      switch (timeType) {
        case 'week':
          const week = parseInt(part)
          // 计算该年第N周的起始日期（周日）
          const firstDayOfYear = new Date(targetYear, 0, 1)
          const firstWeekStart = new Date(firstDayOfYear)
          firstWeekStart.setDate(firstDayOfYear.getDate() - firstDayOfYear.getDay())
          // 第N周起始 = 第一周起始 + (N-1)*7天
          startDate = new Date(firstWeekStart)
          startDate.setDate(firstWeekStart.getDate() + (week - 1) * 7)
          // 第N周结束 = 起始 + 6天（周六）
          endDate = new Date(startDate)
          endDate.setDate(startDate.getDate() + 6)
          break

        case 'month':
          const month = parseInt(part) - 1 // 月份从0开始
          startDate = new Date(targetYear, month, 1) // 当月1号
          endDate = new Date(targetYear, month + 1, 0) // 当月最后一天
          break

        case 'year':
          startDate = new Date(targetYear, 0, 1) // 1月1号
          endDate = new Date(targetYear, 11, 31) // 12月31号
          break
      }

      // 格式化为 yyyy-MM-dd
      const format = (date) => date.toISOString().split('T')[0]
      return { start: format(startDate), end: format(endDate) }
    },

    /**
     * 更新周期文本描述（当期+上期）
     */
    updatePeriodText() {
      if (!this.dateRange) return
      const currentPeriod = this.dateRange
      const previousPeriod = this.getPreviousPeriod(currentPeriod, this.timeType)

      switch (this.timeType) {
        case 'week':
          const [currWYear, currW] = currentPeriod.split('-W')
          const [prevWYear, prevW] = previousPeriod.split('-W')
          this.currentPeriodText = `${currWYear}年第${currW}周`
          this.previousPeriodText = `${prevWYear}年第${prevW}周`
          break

        case 'month':
          const [currMYear, currM] = currentPeriod.split('-')
          const [prevMYear, prevM] = previousPeriod.split('-')
          this.currentPeriodText = `${currMYear}年${currM}月`
          this.previousPeriodText = `${prevMYear}年${prevM}月`
          break

        case 'year':
          this.currentPeriodText = `${currentPeriod}年`
          this.previousPeriodText = `${previousPeriod}年`
          break
      }
    },

    /**
     * 时间类型切换：重置周期 + 自动查询
     */
    handleTimeTypeChange() {
      this.dateRange = ''
      this.initDateRange()
      this.resetData()
      this.handleQuery()
    },

    /**
     * 查询按钮：构建参数 + 调用接口 + 计算环比
     */
    handleQuery() {
      this.loading = true
      // 1. 构建接口参数（含当期/上期时间段）
      const apiParams = this.buildApiParams()
      // 2. 调用接口（实际项目替换为axios）
      this.mockApiRequest(apiParams)
        .then(({ currentValue, previousValue }) => {
          // 3. 保存原始数据（保留2位小数）
          this.currentValue = Number(currentValue.toFixed(2))
          this.previousValue = Number(previousValue.toFixed(2))
          // 4. 计算增加值和环比
          this.calculateIndicators()
          // 5. 更新周期文本
          this.updatePeriodText()
        })
        .catch(err => {
          this.$message.error(`数据获取失败：${err.message}`)
          this.resetData()
        })
        .finally(() => {
          this.loading = false
        })
    },

    /**
     * 构建接口参数（核心：传递当期/上期时间段）
     * @returns {Object} 接口请求参数
     */
    buildApiParams() {
      if (!this.dateRange) return {}
      // 当前周期 + 上期周期
      const currentPeriod = this.dateRange
      const previousPeriod = this.getPreviousPeriod(currentPeriod, this.timeType)
      // 转换为时间段（start/end: yyyy-MM-dd）
      const currentTimeRange = this.getPeriodTimeRange(currentPeriod, this.timeType)
      const previousTimeRange = this.getPeriodTimeRange(previousPeriod, this.timeType)

      return {
        indicatorName: this.indicatorName, // 指标名称（如：能耗）
        timeType: this.timeType, // 时间类型（week/month/year）
        currentRange: currentTimeRange, // 当期时间段
        previousRange: previousTimeRange // 上期时间段
      }
    },

    /**
     * 模拟接口请求（实际项目替换为axios.post/get）
     * @param {Object} params - 接口参数
     * @returns {Promise} 包含当期/上期值的Promise
     */
    mockApiRequest(params) {
      return new Promise((resolve) => {
        // 模拟网络延迟
        setTimeout(() => {
          // 根据时间类型生成合理范围的随机数据（以上期为基础）
          let baseValue = 0
          switch (params.timeType) {
            case 'week':
              baseValue = 7000 + Math.random() * 2000 // 周数据：7000-9000
              break
            case 'month':
              baseValue = 30000 + Math.random() * 5000 // 月数据：30000-35000
              break
            case 'year':
              baseValue = 365000 + Math.random() * 50000 // 年数据：36.5万-41.5万
              break
          }

          // 当期值 = 上期值 × 随机波动（-5% ~ +15%）
          const previousValue = baseValue
          const fluctuation = -0.05 + Math.random() * 0.2 // 波动范围：-5% ~ +15%
          const currentValue = previousValue * (1 + fluctuation)

          resolve({ currentValue, previousValue })
        }, 800)
      })
    },

    /**
     * 计算增加值和环比（处理上期为0的异常场景）
     */
    calculateIndicators() {
      // 增加值 = 当期 - 上期
      this.increaseValue = this.currentValue - this.previousValue
      // 环比 = (当期 - 上期) / 上期（上期为0时特殊处理）
      if (this.previousValue === 0) {
        this.monthOnMonth = this.currentValue > 0 ? 1 : 0 // 上期为0时，当期有值则环比100%
      } else {
        this.monthOnMonth = this.increaseValue / this.previousValue
      }
    },

    /**
     * 重置：恢复默认周期 + 清空数据 + 自动查询
     */
    handleReset() {
      this.initDateRange()
      this.resetData()
      this.handleQuery()
    },

    /**
     * 清空核心数据
     */
    resetData() {
      this.currentValue = null
      this.previousValue = null
      this.increaseValue = null
      this.monthOnMonth = null
      this.currentPeriodText = ''
      this.previousPeriodText = ''
    },

    /**
     * 数字补零（确保周数/月份为两位）
     * @param {Number} num - 需补零的数字
     * @returns {String} 补零后的字符串
     */
    padZero(num) {
      return num < 10 ? `0${num}` : `${num}`
    },

    /**
     * 格式化数字（千分位分隔 + 保留2位小数）
     * @param {Number} num - 需格式化的数字
     * @returns {String} 格式化后的字符串
     */
    formatNumber(num) {
      if (num === null || isNaN(num)) return '--'
      return num.toLocaleString('zh-CN', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
      })
    },

    /**
     * 禁用未来日期选择（无法选择未到的周/月/年）
     * @param {Date} date - 待判断日期
     * @returns {Boolean} 是否禁用
     */
    disableFutureDate(date) {
      return date > new Date()
    },

    refresh() {
      this.handleQuery()
    }
  }
}
</script>

<style scoped>
.month-on-month-analysis {
  padding: 20px;
  background-color: #fff;
  border-radius: 6px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}

.filter-section {
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #f0f0f0;
}

.indicator-cards {
  margin-top: 10px;
}

.indicator-card {
  background-color: #fff;
  border-radius: 6px;
  padding: 18px;
  height: 100%;
  border: 1px solid #f0f0f0;
  transition: all 0.3s ease;
}

.indicator-card:hover {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  transform: translateY(-2px);
}

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

.card-title {
  font-size: 14px;
  color: #666;
  font-weight: 500;
}

.card-period {
  font-size: 12px;
  color: #999;
  background-color: #f5f7fa;
  padding: 2px 8px;
  border-radius: 4px;
}

.card-icon {
  color: #409eff;
  font-size: 14px;
}

.card-value {
  font-size: 26px;
  font-weight: 600;
  color: #333;
  margin-bottom: 6px;
  transition: color 0.3s ease;
}

.card-desc {
  font-size: 12px;
  color: #999;
}

/* 增加值/环比颜色：上升红、下降绿 */
.text-increase {
  color: #f56c6c;
}

.text-decrease {
  color: #67c23a;
}

/* 加载状态 */
.loading-container {
  text-align: center;
  padding: 60px 0;
  color: #666;
}

.loading-container p {
  margin-top: 12px;
  font-size: 14px;
}
</style>