<template>
  <div class="app-container cp-annual-report" v-loading="loading">
    <el-card shadow="never" class="filter-card">
      <el-form size="small" :inline="true">
        <el-form-item>
          <template slot="label">{{ cpT("queryStatYear") }}</template>
          <el-date-picker
            v-model="statYear"
            type="year"
            value-format="yyyy"
            :placeholder="cpT('queryStatYearPh')"
            :clearable="false"
            style="width: 140px"
            @change="handleYearChange"
          />
        </el-form-item>
      </el-form>
    </el-card>

    <template v-if="!loading && !hasData">
      <el-card shadow="never" class="empty-card">
        <el-empty :description="cpT('emptyTitle')">
          <span class="empty-desc">{{ cpT("emptyDesc") }}</span>
        </el-empty>
      </el-card>
    </template>

    <template v-else-if="!loading && hasData">
      <el-card shadow="never" class="overview-card">
        <div slot="header" class="card-header">
          <span>{{ cpT("overviewTitle") }}</span>
          <span class="overview-tip">{{ cpT("summaryMaxMonthTip") }}</span>
        </div>
        <el-row :gutter="16">
          <el-col
            v-for="item in overviewItems"
            :key="item.key"
            :xs="12"
            :sm="8"
            :md="8"
            :lg="4"
            class="overview-col"
          >
            <div class="overview-item">
              <div class="overview-item__icon">
                <i class="el-icon-data-analysis" />
              </div>
              <div class="overview-item__value">{{ formatOverviewValue(item) }}</div>
              <div class="overview-item__label">{{ cpAch(item.labelKey) }}</div>
            </div>
          </el-col>
        </el-row>
      </el-card>

      <el-row :gutter="16" class="chart-row">
        <el-col :xs="24" :lg="8">
          <el-card shadow="never">
            <div slot="header">{{ cpT("chartCollectiveIncome") }}</div>
            <div ref="chartCollective" class="chart-box" />
          </el-card>
        </el-col>
        <el-col :xs="24" :lg="8">
          <el-card shadow="never">
            <div slot="header">{{ cpT("chartEmployment") }}</div>
            <div ref="chartEmployment" class="chart-box" />
          </el-card>
        </el-col>
        <el-col :xs="24" :lg="8">
          <el-card shadow="never">
            <div slot="header">{{ cpT("chartEnv") }}</div>
            <div ref="chartEnv" class="chart-box" />
          </el-card>
        </el-col>
      </el-row>

      <el-row :gutter="16" class="chart-row">
        <el-col :xs="24" :lg="8">
          <el-card shadow="never">
            <div slot="header">{{ cpT("chartGreen") }}</div>
            <div ref="chartGreen" class="chart-box" />
          </el-card>
        </el-col>
        <el-col :xs="24" :lg="8">
          <el-card shadow="never">
            <div slot="header">{{ cpT("chartCultural") }}</div>
            <div ref="chartCultural" class="chart-box" />
          </el-card>
        </el-col>
        <el-col :xs="24" :lg="8">
          <el-card shadow="never">
            <div slot="header">{{ cpT("chartEthnic") }}</div>
            <div ref="chartEthnic" class="chart-box" />
          </el-card>
        </el-col>
      </el-row>
    </template>
  </div>
</template>

<script>
import * as echarts from "echarts"
require("echarts/theme/macarons")
import { debounce } from "@/utils"
import commonProsperityLocaleMixin from "@/mixins/commonProsperityLocaleMixin"
import { getAchievementAnnualReport } from "@/api/commonProsperity/achievementReport"

const CHART_REFS = ["chartCollective", "chartEmployment", "chartEnv", "chartGreen", "chartCultural", "chartEthnic"]

export default {
  name: "CommonProsperityAchievementReport",
  mixins: [commonProsperityLocaleMixin],
  data() {
    const y = String(new Date().getFullYear())
    return {
      cpNs: "achievementReport",
      loading: false,
      statYear: y,
      hasData: false,
      reportData: null,
      charts: {},
      resizeHandler: null
    }
  },
  computed: {
    overviewItems() {
      return [
        { key: "collectiveEconomyIncome", labelKey: "formCollectiveIncome", format: "money" },
        { key: "employmentDrivenCount", labelKey: "formEmploymentDriven", format: "intPerson" },
        { key: "newJobPositions", labelKey: "formNewJobs", format: "intGe" },
        { key: "envProjectCount", labelKey: "formEnvProjects", format: "intGe" },
        { key: "newGreenArea", labelKey: "formGreenArea", format: "area" },
        { key: "culturalHeritageCount", labelKey: "formCulturalHeritage", format: "intPerson" },
        { key: "ethnicIntegrationProjectCount", labelKey: "formEthnicIntegration", format: "intGe" },
        { key: "ethnicUnityActivityCount", labelKey: "formEthnicUnity", format: "intGe" },
        { key: "digitalPlatformUsageRate", labelKey: "formDigitalRate", format: "rate" },
        { key: "regionalPublicBrandCount", labelKey: "formBrandCount", format: "intGe" },
        { key: "brandPremiumRate", labelKey: "formBrandPremium", format: "rate" }
      ]
    },
    monthLabels() {
      // 横轴：接口返回的 1～最大统计月（不再固定 12 月）
      return this.sortedMonthly.map((row) => this.cpT("monthLabel", { m: Number(row.month) }))
    },
    /** 按 month 升序的分月序列 */
    sortedMonthly() {
      const monthly = (this.reportData && this.reportData.monthly) || []
      return [...monthly]
        .filter((row) => row && row.month != null)
        .sort((a, b) => Number(a.month) - Number(b.month))
    },
    summary() {
      return (this.reportData && this.reportData.summary) || {}
    }
  },
  mounted() {
    this.resizeHandler = debounce(() => this.resizeCharts(), 120)
    window.addEventListener("resize", this.resizeHandler)
    this.loadReport()
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.resizeHandler)
    this.disposeCharts()
  },
  methods: {
    cpAch(key) {
      return this.$t(`commonProsperity.achievement.${key}`)
    },
    dash() {
      return this.$t("commonProsperity.status.dash")
    },
    formatMoney(val) {
      if (val == null || val === "") {
        return this.dash()
      }
      return val + " " + this.cpCommon("unitWanYuan")
    },
    formatArea(val) {
      if (val == null || val === "") {
        return this.dash()
      }
      return val + " " + this.cpCommon("unitMu")
    },
    formatRate(val) {
      if (val == null || val === "") {
        return this.dash()
      }
      return (Number(val) * 100).toFixed(2) + "%"
    },
    formatIntWithUnit(val, unitKey) {
      if (val == null || val === "") {
        return this.dash()
      }
      return val + " " + this.cpCommon(unitKey)
    },
    formatOverviewValue(item) {
      const v = this.summary[item.key]
      if (v == null || v === "") {
        return this.dash()
      }
      switch (item.format) {
        case "money":
          return this.formatMoney(v)
        case "area":
          return this.formatArea(v)
        case "rate":
          return this.formatRate(v)
        case "intPerson":
          return this.formatIntWithUnit(v, "unitPerson")
        case "intGe":
          return this.formatIntWithUnit(v, "unitGe")
        default:
          return v
      }
    },
    seriesByField(field) {
      // 直接按接口 monthly 顺序取值；缺月后端已补 0
      return this.sortedMonthly.map((row) => {
        if (row[field] == null || row[field] === "") {
          return 0
        }
        return Number(row[field])
      })
    },
    /** 单轴刻度上限：留约 20% 顶部空隙，避免折线贴顶与另一轴曲线完全重合感 */
    axisMaxPadding(values) {
      const nums = (values || []).filter((v) => v != null && !isNaN(v))
      if (!nums.length) {
        return 10
      }
      const max = Math.max(...nums, 0)
      if (max <= 0) {
        return 10
      }
      return Math.ceil(max * 1.2) || 10
    },
    handleYearChange() {
      if (!this.statYear) {
        this.statYear = String(new Date().getFullYear())
      }
      this.loadReport()
    },
    loadReport() {
      const year = String(this.statYear).substring(0, 4)
      this.loading = true
      this.disposeCharts()
      getAchievementAnnualReport(year)
        .then((res) => {
          const data = res.data || {}
          this.reportData = data
          this.hasData = data.hasData === true
        })
        .catch(() => {
          this.hasData = false
          this.reportData = null
          this.$modal.msgError(this.cpT("loadFailed"))
        })
        .finally(() => {
          this.loading = false
          if (this.hasData) {
            this.scheduleRenderCharts()
          }
        })
    },
    /** 图表在 v-else-if="!loading && hasData" 内，须 loading 结束且 DOM 挂载后再 init */
    scheduleRenderCharts(retry = 0) {
      this.$nextTick(() => {
        if (!this.$refs.chartCollective) {
          if (retry < 8) {
            this.scheduleRenderCharts(retry + 1)
          }
          return
        }
        this.renderCharts()
        this.$nextTick(() => this.resizeCharts())
      })
    },
    getChart(dom) {
      if (!dom) {
        return null
      }
      let chart = echarts.getInstanceByDom(dom)
      if (!chart) {
        chart = echarts.init(dom, "macarons")
      }
      return chart
    },
    disposeCharts() {
      CHART_REFS.forEach((ref) => {
        const dom = this.$refs[ref]
        if (!dom) {
          return
        }
        const inst = echarts.getInstanceByDom(dom)
        if (inst) {
          inst.dispose()
        }
      })
      this.charts = {}
    },
    resizeCharts() {
      Object.keys(this.charts).forEach((k) => {
        this.charts[k] && this.charts[k].resize()
      })
    },
    renderCharts() {
      this.renderCollectiveChart()
      this.renderEmploymentChart()
      this.renderEnvChart()
      this.renderGreenChart()
      this.renderCulturalChart()
      this.renderEthnicChart()
    },
    renderCollectiveChart() {
      const dom = this.$refs.chartCollective
      const chart = this.getChart(dom)
      if (!chart) {
        return
      }
      const data = this.seriesByField("collectiveEconomyIncome")
      chart.setOption(
        {
          tooltip: {
            trigger: "axis",
            axisPointer: { type: "shadow" },
            formatter: (params) => {
              const p = params[0]
              return `${p.name}<br/>${p.seriesName}: ${p.value} ${this.cpCommon("unitWanYuan")}`
            }
          },
          grid: { left: "3%", right: "8%", bottom: "3%", top: 16, containLabel: true },
          xAxis: { type: "value", name: this.cpCommon("unitWanYuan") },
          yAxis: { type: "category", data: this.monthLabels, inverse: true },
          series: [
            {
              name: this.cpAch("formCollectiveIncome"),
              type: "bar",
              data,
              barMaxWidth: 18
            }
          ]
        },
        true
      )
      this.charts.collective = chart
    },
    renderEmploymentChart() {
      const dom = this.$refs.chartEmployment
      const chart = this.getChart(dom)
      if (!chart) {
        return
      }
      const unitPerson = this.cpCommon("unitPerson")
      const unitGe = this.cpCommon("unitGe")
      const employmentData = this.seriesByField("employmentDrivenCount")
      const jobsData = this.seriesByField("newJobPositions")
      chart.setOption(
        {
          tooltip: {
            trigger: "axis",
            formatter: (params) => {
              if (!params || !params.length) {
                return ""
              }
              let html = params[0].name + "<br/>"
              params.forEach((p) => {
                const unit = p.seriesName === this.cpT("seriesEmploymentDriven") ? unitPerson : unitGe
                html += `${p.marker}${p.seriesName}: ${p.value} ${unit}<br/>`
              })
              return html
            }
          },
          legend: { data: [this.cpT("seriesEmploymentDriven"), this.cpT("seriesNewJobs")] },
          grid: { left: "3%", right: "12%", bottom: "12%", top: 40, containLabel: true },
          xAxis: { type: "category", boundaryGap: false, data: this.monthLabels },
          yAxis: [
            {
              type: "value",
              name: unitPerson,
              position: "left",
              min: 0,
              max: this.axisMaxPadding(employmentData),
              splitNumber: 5
            },
            {
              type: "value",
              name: unitGe,
              position: "right",
              min: 0,
              max: this.axisMaxPadding(jobsData),
              splitNumber: 5
            }
          ],
          series: [
            {
              name: this.cpT("seriesEmploymentDriven"),
              type: "line",
              yAxisIndex: 0,
              smooth: false,
              symbol: "circle",
              symbolSize: 7,
              lineStyle: { width: 2, color: "#5470c6" },
              itemStyle: { color: "#5470c6" },
              data: employmentData
            },
            {
              name: this.cpT("seriesNewJobs"),
              type: "line",
              yAxisIndex: 1,
              smooth: false,
              symbol: "diamond",
              symbolSize: 8,
              lineStyle: { width: 2, color: "#ee6666", type: "dashed" },
              itemStyle: { color: "#ee6666", borderWidth: 2 },
              data: jobsData
            }
          ]
        },
        true
      )
      this.charts.employment = chart
    },
    renderEnvChart() {
      const dom = this.$refs.chartEnv
      const chart = this.getChart(dom)
      if (!chart) {
        return
      }
      chart.setOption(
        {
          tooltip: { trigger: "axis", axisPointer: { type: "shadow" } },
          grid: { left: "3%", right: "4%", bottom: "12%", top: 16, containLabel: true },
          xAxis: { type: "category", data: this.monthLabels },
          yAxis: { type: "value", name: this.cpCommon("unitGe") },
          series: [
            {
              name: this.cpAch("formEnvProjects"),
              type: "bar",
              barMaxWidth: 28,
              data: this.seriesByField("envProjectCount")
            }
          ]
        },
        true
      )
      this.charts.env = chart
    },
    renderGreenChart() {
      const dom = this.$refs.chartGreen
      const chart = this.getChart(dom)
      if (!chart) {
        return
      }
      chart.setOption(
        {
          tooltip: { trigger: "axis" },
          grid: { left: "3%", right: "4%", bottom: "12%", top: 16, containLabel: true },
          xAxis: { type: "category", boundaryGap: false, data: this.monthLabels },
          yAxis: { type: "value", name: this.cpCommon("unitMu") },
          series: [
            {
              name: this.cpAch("formGreenArea"),
              type: "line",
              smooth: true,
              data: this.seriesByField("newGreenArea")
            }
          ]
        },
        true
      )
      this.charts.green = chart
    },
    renderCulturalChart() {
      const dom = this.$refs.chartCultural
      const chart = this.getChart(dom)
      if (!chart) {
        return
      }
      chart.setOption(
        {
          tooltip: { trigger: "axis", axisPointer: { type: "shadow" } },
          grid: { left: "3%", right: "4%", bottom: "12%", top: 16, containLabel: true },
          xAxis: { type: "category", data: this.monthLabels },
          yAxis: { type: "value", name: this.cpCommon("unitPerson") },
          series: [
            {
              name: this.cpAch("formCulturalHeritage"),
              type: "bar",
              barMaxWidth: 28,
              data: this.seriesByField("culturalHeritageCount")
            }
          ]
        },
        true
      )
      this.charts.cultural = chart
    },
    renderEthnicChart() {
      const dom = this.$refs.chartEthnic
      const chart = this.getChart(dom)
      if (!chart) {
        return
      }
      chart.setOption(
        {
          tooltip: { trigger: "axis", axisPointer: { type: "shadow" } },
          legend: { data: [this.cpT("seriesEthnicIntegration"), this.cpT("seriesEthnicUnity")] },
          grid: { left: "3%", right: "4%", bottom: "12%", top: 40, containLabel: true },
          xAxis: { type: "category", data: this.monthLabels },
          yAxis: { type: "value", name: this.cpCommon("unitGe") },
          series: [
            {
              name: this.cpT("seriesEthnicIntegration"),
              type: "bar",
              stack: "ethnic",
              barMaxWidth: 28,
              data: this.seriesByField("ethnicIntegrationProjectCount")
            },
            {
              name: this.cpT("seriesEthnicUnity"),
              type: "bar",
              stack: "ethnic",
              barMaxWidth: 28,
              data: this.seriesByField("ethnicUnityActivityCount")
            }
          ]
        },
        true
      )
      this.charts.ethnic = chart
    }
  }
}
</script>

<style scoped>
.cp-annual-report .filter-card {
  margin-bottom: 16px;
}
.cp-annual-report .empty-card {
  margin-top: 16px;
}
.empty-desc {
  display: block;
  margin-top: 8px;
  color: #909399;
  font-size: 13px;
}
.overview-card {
  margin-bottom: 16px;
}
.card-header {
  font-weight: 600;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.overview-tip {
  font-weight: 400;
  font-size: 12px;
  color: #909399;
}
.overview-col {
  margin-bottom: 16px;
}
.overview-item {
  text-align: center;
  padding: 12px 8px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  background: #fafafa;
  min-height: 100px;
}
.overview-item__icon {
  font-size: 28px;
  color: #409eff;
  margin-bottom: 8px;
}
.overview-item__value {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
  line-height: 1.4;
  word-break: break-all;
}
.overview-item__label {
  margin-top: 6px;
  font-size: 12px;
  color: #909399;
  line-height: 1.3;
}
.chart-row {
  margin-bottom: 16px;
}
.chart-box {
  height: 320px;
  width: 100%;
}
</style>
