<template>
  <div class="cfo-value-trend-chart">
    <div class="value-trend-legend" aria-label="趋势图图例">
      <span><i class="verified"></i>财务已确认（实线）</span>
      <span><i class="pending"></i>实际待确认（虚线）</span>
      <span><i class="reversal"></i>冲回（点线）</span>
      <em>单位：{{ currency || '—' }}</em>
    </div>
    <div v-if="rows.length" ref="chartElement" class="value-trend-canvas" role="img" :aria-label="ariaLabel"></div>
    <div v-else class="value-trend-empty" role="status">
      <i class="mdi mdi-chart-line-variant" aria-hidden="true"></i>
      <span>当前筛选范围暂无实际结果趋势</span>
    </div>

    <details v-if="rows.length" class="value-trend-table-wrap">
      <summary>查看趋势明细表</summary>
      <div class="value-trend-table-scroll">
        <table>
          <caption class="sr-only">{{ currency }} 经营价值趋势明细</caption>
          <thead>
            <tr>
              <th scope="col">期间</th>
              <th scope="col">财务已确认</th>
              <th scope="col">实际待确认</th>
              <th scope="col">冲回</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="row in rows" :key="`${row.period}-${row.currency}`">
              <th scope="row">{{ row.period }}</th>
              <td>{{ formatMoney(row.verifiedNet, row.currency) }}</td>
              <td>{{ formatMoney(row.actualPending, row.currency) }}</td>
              <td>{{ formatMoney(row.reversal, row.currency) }}</td>
            </tr>
          </tbody>
        </table>
      </div>
    </details>
  </div>
</template>

<script setup>
import { computed, shallowRef } from 'vue'
import { LineChart } from 'echarts/charts'
import { AriaComponent, GridComponent, TooltipComponent } from 'echarts/components'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'

import { useEcharts } from '../../composables/useEcharts.js'
import { useThemeColors } from '../../composables/useThemeColors.js'
import { formatMoney } from '../../views/scripts/cfoValueDashboardModel.js'

use([AriaComponent, GridComponent, TooltipComponent, LineChart, CanvasRenderer])

const props = defineProps({
  rows: { type: Array, default: () => [] },
  currency: { type: String, default: '' }
})

const chartElement = shallowRef(null)
const themeColors = useThemeColors()
const reduceMotion = typeof window !== 'undefined'
  && typeof window.matchMedia === 'function'
  && window.matchMedia('(prefers-reduced-motion: reduce)').matches
const ariaLabel = computed(() => props.rows.map((row) => (
  `${row.period}，财务已确认${formatMoney(row.verifiedNet, row.currency)}`
  + `，实际待确认${formatMoney(row.actualPending, row.currency)}`
  + `，冲回${formatMoney(row.reversal, row.currency)}`
)).join('；'))

const chartOptions = computed(() => ({
  animation: !reduceMotion,
  animationDuration: reduceMotion ? 0 : 260,
  aria: {
    enabled: true,
    decal: { show: true },
    description: ariaLabel.value
  },
  grid: { top: 20, right: 24, bottom: 20, left: 30, containLabel: true },
  tooltip: {
    trigger: 'axis',
    backgroundColor: '#0f172a',
    borderWidth: 0,
    textStyle: { color: '#ffffff', fontSize: 12 },
    valueFormatter: (value) => formatMoney(value, props.currency)
  },
  xAxis: {
    type: 'category',
    boundaryGap: false,
    data: props.rows.map((row) => row.period),
    axisLine: { lineStyle: { color: '#cbd5e1' } },
    axisTick: { show: false },
    axisLabel: { color: '#64748b', fontSize: 12, hideOverlap: true }
  },
  yAxis: {
    type: 'value',
    splitNumber: 4,
    axisLine: { show: false },
    axisTick: { show: false },
    axisLabel: { color: '#64748b', fontSize: 12, formatter: compactNumber },
    splitLine: { lineStyle: { color: '#e2e8f0', type: 'dashed' } }
  },
  series: [
    buildSeries('财务已确认', props.rows.map((row) => row.verifiedNet), themeColors.value.success, 'solid'),
    buildSeries('实际待确认', props.rows.map((row) => row.actualPending), themeColors.value.chartAmber, 'dashed'),
    buildSeries('冲回', props.rows.map((row) => row.reversal), themeColors.value.chartDanger, 'dotted')
  ]
}))

useEcharts(chartElement, chartOptions)

function buildSeries(name, data, color, type) {
  return {
    name,
    type: 'line',
    data,
    smooth: true,
    symbol: 'circle',
    symbolSize: 7,
    lineStyle: { width: 2.5, color, type },
    itemStyle: { color: '#ffffff', borderColor: color, borderWidth: 2 },
    emphasis: { focus: 'series' }
  }
}

function compactNumber(value) {
  const number = Number(value || 0)
  if (Math.abs(number) >= 1_000_000) return `${(number / 1_000_000).toFixed(1)}m`
  if (Math.abs(number) >= 1_000) return `${(number / 1_000).toFixed(1)}k`
  return number.toLocaleString('zh-CN', { maximumFractionDigits: 0 })
}
</script>

<style scoped>
.cfo-value-trend-chart { display: grid; gap: 12px; min-width: 0; }
.value-trend-legend { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; color: var(--muted); font-size: 12px; }
.value-trend-legend span { display: inline-flex; align-items: center; gap: 6px; }
.value-trend-legend i { width: 20px; height: 0; border-top: 3px solid; }
.value-trend-legend i.verified { border-color: var(--success); }
.value-trend-legend i.pending { border-color: var(--warning); border-top-style: dashed; }
.value-trend-legend i.reversal { border-color: var(--danger); border-top-style: dotted; }
.value-trend-legend em { margin-left: auto; color: var(--text); font-style: normal; font-weight: 700; }
.value-trend-canvas { width: 100%; min-height: 290px; }
.value-trend-empty { min-height: 290px; display: grid; place-content: center; justify-items: center; gap: 10px; color: var(--muted); }
.value-trend-empty i { font-size: 32px; color: var(--line-strong); }
.value-trend-table-wrap { border-top: 1px solid var(--line); padding-top: 10px; }
.value-trend-table-wrap summary { min-height: 44px; display: inline-flex; align-items: center; color: var(--theme-primary-active); font-size: 12px; font-weight: 750; cursor: pointer; }
.value-trend-table-scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; min-width: 560px; }
th, td { padding: 9px 10px; border-bottom: 1px solid var(--line); color: var(--text); font-size: 12px; text-align: right; font-variant-numeric: tabular-nums; }
th:first-child, td:first-child { text-align: left; }
thead th { color: var(--muted); font-weight: 700; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
@media (max-width: 640px) {
  .value-trend-legend em { width: 100%; margin-left: 0; }
  .value-trend-canvas, .value-trend-empty { min-height: 240px; }
}
</style>
