<template>
  <div class="screen-page ts-page" :class="{ 'is-loading': loading }">
    <div v-if="loadError" class="ts-error" @click="onRetry">
      {{ loadError }}（点击重试）
    </div>
    <!-- <div class="ts-year-bar">
      <label class="ts-year-bar__label">统计年份</label>
      <select
        v-model="statYear"
        class="ts-year-bar__select"
        :disabled="loading"
        @change="onYearChange"
      >
        <option v-for="y in availableYears" :key="y" :value="String(y)">{{ y }}年</option>
      </select>
      <span v-if="statDate" class="ts-year-bar__date">统计日 {{ statDate }}</span>
      <button
        type="button"
        class="ts-year-bar__refresh"
        :disabled="loading || refreshing"
        @click="onManualRefresh"
      >
        {{ refreshing ? '刷新中…' : '刷新' }}
      </button>
    </div> -->

    <!-- 左栏：牦牛交易 -->
    <div class="screen-page--home-column">
      <div class="screen-page--home-column-top">
        <div class="top_title">交易总览 ཚོང་འདོན་ཀྱི་རྒྱུན་བསྡུས།</div>
        <div class="ts-overview-grid">
          <div
            v-for="item in tradeOverviewItems"
            :key="item.key"
            class="ts-overview-cell"
            :class="{ 'ts-overview-cell--placeholder': item.placeholder }"
          >
            <div class="content_title"><div>{{ item.label }}</div></div>
            <div class="content_num">
              <strong v-if="item.placeholder" class="content_num__value">—</strong>
              <ScreenScrollNumber
                v-else
                class="content_num__value"
                :value="item.rawValue"
                :format="item.format"
              />
              <span v-if="item.unit" class="content_num__unit">{{ item.unit }}</span>
            </div>
          </div>
        </div>
      </div>

      <div class="screen-page--home-column-flex">
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">产地行情 ཐོག་མའི་གནས་ཚད།</div>
          <div class="flex_content flex_content--quote">
            <div class="quote-summary">
              <div class="quote-summary__item">
                <div class="quote-summary__label">7日均价</div>
                <div class="quote-summary__val">
                  <strong>{{ formatPrice(originQuote?.avgPrice7d) }}</strong>
                  <span class="quote-summary__unit">{{ originQuote?.priceUnitLabel || '' }}</span>
                </div>
              </div>
              <div class="quote-summary__item">
                <div class="quote-summary__label">7日最低价</div>
                <div class="quote-summary__val">
                  <strong>{{ formatPrice(originQuote?.minPrice7d) }}</strong>
                </div>
              </div>
              <div class="quote-summary__item">
                <div class="quote-summary__label">7日最高价</div>
                <div class="quote-summary__val">
                  <strong>{{ formatPrice(originQuote?.maxPrice7d) }}</strong>
                </div>
              </div>
              <div class="quote-summary__item">
                <div class="quote-summary__label">最近行情日</div>
                <div class="quote-summary__val quote-summary__val--date">
                  <strong>{{ originQuote?.lastQuoteDate || '—' }}</strong>
                </div>
              </div>
            </div>
            <div class="quote-chart">
              <ScreenChart :option="originQuoteChartOption" />
            </div>
          </div>
        </div>
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">牦牛交易数额趋势 གཡག་ཚོང་གི་འབོར་གྱི་འགྲོ་སྟངས།</div>
          <div class="flex_content">
            <ScreenChart :option="monthlyTrendChartOption" />
          </div>
        </div>
      </div>

      <div class="screen-page--home-column-flex">
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">牦牛销售去向 གཡག་ཚོང་འདོན་གྱི་ཕྱིར་སྐྱོད།</div>
          <div class="flex_content">
            <ScreenChart :option="destinationChartOption" />
          </div>
        </div>
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">品质等级占比 སྤུན་ཤེས་རྩིས་ཀྱི་ཆ་འདུམ།</div>
          <div class="flex_content">
            <ScreenChart :option="qualityGradeChartOption" />
          </div>
        </div>
      </div>
    </div>

    <!-- 右栏：农资商城 -->
    <div class="screen-page--home-column" :class="{ 'ts-mall-unavailable': !mallStatsAvailable }">
      <div class="screen-page--home-column-right ts-mall-panel">
        <div class="top_title">
          农资品类销售 ཞིང་ལས་རྒྱུ་ཆ་རིགས་ཀྱི་ཚོང་འདོན།
        </div>
        <div class="ts-mall-top">
          <div class="ts-mall-top__pie">
            <ScreenChart :option="categorySalesChartOption" />
          </div>
          <div class="ts-mall-top__hot">
            <div class="ts-mall-hot-title">热销农资 Top5</div>
            <ul v-if="hotCategoryItems.length" class="ts-mall-hot-list">
              <li v-for="item in hotCategoryItems" :key="item.rank" class="ts-mall-hot-list__row">
                <span class="ts-mall-hot-list__rank">{{ item.rank }}</span>
                <span class="ts-mall-hot-list__name" :title="item.categoryName">{{ item.categoryName }}</span>
                <span class="ts-mall-hot-list__qty">{{ formatNum(item.qty) }} 件</span>
              </li>
            </ul>
            <span v-else class="ts-placeholder ts-placeholder--sm">{{ mallEmptyHint }}</span>
          </div>
        </div>
      </div>
      <div class="screen-page--home-column-flex">
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">商城订单趋势 ཚོང་ཁང་གི་བཀོད་རྩིས་འགྲོ་སྟངས།</div>
          <div class="flex_content">
            <ScreenChart :option="mallOrderTrendChartOption" />
          </div>
        </div>
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">店铺入驻 ཚོང་ཁང་གི་ཞུགས་སྒོ།</div>
          <div class="flex_content">
            <ScreenChart :option="shopEntryChartOption" />
          </div>
        </div>
      </div>
      <div class="screen-page--home-column-flex">
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">消费区域排名(前5) ཟས་སྤྱོད་ས་ཁུལ་གོ་རྒྱ་(གོང་ལྔ)</div>
          <div class="flex_content">
            <ScreenChart :option="regionRankChartOption" />
          </div>
        </div>
        <div class="screen-page--home-column-flex-item">
          <div class="flex_title">消费者评价 སྤྱོད་མིའི་དཔྱད་པ།</div>
          <div class="flex_content">
            <ScreenChart :option="reviewWordCloudChartOption" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue'
import ScreenChart from '@/components/ScreenChart.vue'
import ScreenScrollNumber from '@/components/ScreenScrollNumber.vue'
import { getTradeSalesDashboard } from '@/api/tradeSales'
import {
  buildCategorySalesPieOption,
  buildMallOrderTrendOption,
  buildOriginQuoteOption,
  buildQualityGradePieOption,
  buildRegionRankBarOption,
  buildReviewWordCloudOption,
  buildSalesDestinationBarOption,
  buildShopEntryPieOption,
  buildTradeMonthlyOption
} from './chartOptions'

/** 自动轮播刷新周期（对齐功能需求 §7.3，默认 3 分钟） */
const DASHBOARD_REFRESH_MS = 3 * 60 * 1000

const loading = ref(false)
const refreshing = ref(false)
const loadError = ref('')
const statYear = ref(String(new Date().getFullYear()))
const statDate = ref('')
const availableYears = ref([new Date().getFullYear()])

const tradeOverview = ref(null)
const originQuote = ref(null)
const tradeMonthlyTrend = ref([])
const salesDestination = ref([])
const qualityGrade = ref(null)
const mallStatsAvailable = ref(false)
const categorySales = ref(null)
const hotCategoryRank = ref(null)
const mallOrderTrend = ref(null)
const shopEntry = ref(null)
const regionRank = ref(null)
const reviewWordCloud = ref(null)

let dashboardTimer = null

const mallAvailable = computed(() => mallStatsAvailable.value)

const originQuoteChartOption = computed(() => buildOriginQuoteOption(originQuote.value))
const monthlyTrendChartOption = computed(() => buildTradeMonthlyOption(tradeMonthlyTrend.value))
const destinationChartOption = computed(() => buildSalesDestinationBarOption(salesDestination.value))
const qualityGradeChartOption = computed(() => buildQualityGradePieOption(qualityGrade.value))
const categorySalesChartOption = computed(() =>
  buildCategorySalesPieOption(categorySales.value, mallAvailable.value)
)
const mallOrderTrendChartOption = computed(() =>
  buildMallOrderTrendOption(mallOrderTrend.value, mallAvailable.value)
)
const shopEntryChartOption = computed(() => buildShopEntryPieOption(shopEntry.value, mallAvailable.value))
const regionRankChartOption = computed(() => buildRegionRankBarOption(regionRank.value, mallAvailable.value))
const reviewWordCloudChartOption = computed(() =>
  buildReviewWordCloudOption(reviewWordCloud.value, mallAvailable.value)
)

const hotCategoryItems = computed(() => {
  const items = hotCategoryRank.value?.items || []
  return [...items].sort((a, b) => (a.rank || 0) - (b.rank || 0))
})

const mallEmptyHint = computed(() => (mallStatsAvailable.value ? '暂无热销数据' : '商城统计未接入'))

/** 右栏品类/热销标题：展示统计年 Y（对齐 v1.2 categorySales.statYear） */
const categoryStatYearLabel = computed(() => {
  const y =
    categorySales.value?.statYear ??
    hotCategoryRank.value?.statYear ??
    statYear.value
  if (y === null || y === undefined || y === '') {
    return ''
  }
  return `${y}年`
})

const tradeOverviewItems = computed(() => {
  const o = tradeOverview.value
  return [
    {
      key: 'orderCount',
      label: '牦牛交易订单数',
      unit: '单',
      rawValue: o?.orderCount,
      format: 'int',
      placeholder: false
    },
    {
      key: 'tradeHeads',
      label: '牦牛交易量',
      unit: '头',
      rawValue: o?.tradeHeads,
      format: 'int',
      placeholder: false
    },
    {
      key: 'tradeAmount',
      label: '牦牛交易总额',
      unit: '元',
      rawValue: o?.tradeAmount,
      format: 'money',
      placeholder: false
    },
    {
      key: 'supplierCount',
      label: '入驻商铺数',
      unit: '家',
      rawValue: o?.supplierCount,
      format: 'int',
      placeholder: false
    },
    {
      key: 'agriOrderCount',
      label: '农资订单量',
      unit: '单',
      rawValue: o?.agriOrderCount,
      format: 'int',
      placeholder: o?.agriOrderCount == null
    },
    {
      key: 'agriSalesAmount',
      label: '农资销售额',
      unit: '元',
      rawValue: o?.agriSalesAmount,
      format: 'money',
      placeholder: o?.agriSalesAmount == null
    }
  ]
})

function formatNum(val) {
  if (val === null || val === undefined || val === '') {
    return '0'
  }
  const n = Number(val)
  if (Number.isNaN(n)) {
    return '0'
  }
  return n.toLocaleString('zh-CN')
}

function formatPrice(val) {
  if (val === null || val === undefined || val === '') {
    return '—'
  }
  const n = Number(val)
  if (Number.isNaN(n)) {
    return '—'
  }
  return n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
}

function resetDashboard() {
  tradeOverview.value = null
  originQuote.value = null
  tradeMonthlyTrend.value = []
  salesDestination.value = []
  qualityGrade.value = null
  mallStatsAvailable.value = false
  categorySales.value = null
  hotCategoryRank.value = null
  mallOrderTrend.value = null
  shopEntry.value = null
  regionRank.value = null
  reviewWordCloud.value = null
}

function applyDashboard(data) {
  if (!data) {
    return
  }
  if (data.statYear) {
    statYear.value = String(data.statYear)
  }
  statDate.value = data.statDate || ''
  availableYears.value = data.availableYears?.length
    ? [...data.availableYears]
    : [Number(statYear.value)]
  tradeOverview.value = data.tradeOverview || null
  originQuote.value = data.originQuote || null
  tradeMonthlyTrend.value = data.tradeMonthlyTrend || []
  salesDestination.value = data.salesDestination || []
  qualityGrade.value = data.qualityGrade || null
  mallStatsAvailable.value = data.mallStatsAvailable || false
  categorySales.value = data.categorySales || null
  hotCategoryRank.value = data.hotCategoryRank || null
  mallOrderTrend.value = data.mallOrderTrend || null
  shopEntry.value = data.shopEntry || null
  regionRank.value = data.regionRank || null
  reviewWordCloud.value = data.reviewWordCloud || null
}

async function fetchDashboard(forceRefresh = false) {
  if (forceRefresh) {
    if (refreshing.value) {
      return
    }
    refreshing.value = true
  } else {
    loading.value = true
    resetDashboard()
  }
  loadError.value = ''
  try {
    const res = await getTradeSalesDashboard(statYear.value, forceRefresh)
    applyDashboard(res.data)
  } catch (e) {
    loadError.value = e?.message || '看板数据加载失败'
  } finally {
    loading.value = false
    refreshing.value = false
  }
}

function onYearChange() {
  fetchDashboard()
}

function onManualRefresh() {
  fetchDashboard(true)
}

function onRetry() {
  fetchDashboard()
}

function startDashboardTimer() {
  dashboardTimer = setInterval(() => {
    fetchDashboard(true)
  }, DASHBOARD_REFRESH_MS)
}

onMounted(() => {
  fetchDashboard()
  startDashboardTimer()
})

onUnmounted(() => {
  if (dashboardTimer) {
    clearInterval(dashboardTimer)
    dashboardTimer = null
  }
})
</script>

<style scoped>
.ts-page {
  position: relative;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  padding: 20px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

.ts-page.is-loading {
  opacity: 0.92;
}

.ts-error {
  position: absolute;
  top: 4px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  padding: 4px 12px;
  font-size: 12px;
  color: #ffb4b4;
  background: rgba(80, 20, 20, 0.75);
  border-radius: 4px;
  cursor: pointer;
}

.ts-year-bar {
  position: absolute;
  top: 8px;
  right: 24px;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
}

.ts-year-bar__label {
  font-size: 12px;
  color: var(--screen-text-secondary, #a8d4c8);
}

.ts-year-bar__select {
  min-width: 88px;
  height: 28px;
  padding: 0 8px;
  font-size: 13px;
  color: #e8eef5;
  background: rgba(4, 48, 40, 0.85);
  border: 1px solid var(--screen-line-dim, rgba(61, 217, 176, 0.42));
  border-radius: 4px;
  outline: none;
}

.ts-year-bar__date {
  font-size: 11px;
  color: rgba(168, 212, 200, 0.75);
}

.ts-year-bar__refresh {
  height: 28px;
  padding: 0 10px;
  font-size: 12px;
  color: #e8eef5;
  background: rgba(4, 48, 40, 0.85);
  border: 1px solid var(--screen-line-dim, rgba(61, 217, 176, 0.42));
  border-radius: 4px;
  cursor: pointer;
}

.ts-year-bar__refresh:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.screen-page--home-column {
  width: 617px;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.screen-page--home-column-top {
  width: 617px;
  height: 201px;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  background: url('../../assets/sale/sale.png') no-repeat center center;
  background-size: 100% 100%;
}

.screen-page--home-column-right {
  width: 617px;
  height: 201px;
  background: url('../../assets/pro/pro.png') no-repeat center center;
  background-size: 100% 100%;
}

.ts-mall-panel {
  display: flex;
  flex-direction: column;
}

.ts-mall-stat-year {
  font-size: 12px;
  color: rgba(168, 212, 200, 0.8);
  margin-left: 4px;
}

.ts-mall-top {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: row;
  gap: 8px;
  padding: 0 12px 10px 28px;
  box-sizing: border-box;
}

.ts-mall-top__pie {
  flex: 1.1;
  min-width: 0;
  min-height: 0;
}

.ts-mall-top__hot {
  flex: 0.9;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 4px 6px;
  background: rgba(4, 48, 40, 0.35);
  border-radius: 4px;
  border: 1px solid rgba(61, 217, 176, 0.18);
}

.ts-mall-hot-title {
  font-size: 11px;
  color: #a8d4c8;
  margin-bottom: 4px;
  flex-shrink: 0;
}

.ts-mall-hot-list {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.ts-mall-hot-list__row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  color: #e8eef5;
  line-height: 1.6;
}

.ts-mall-hot-list__rank {
  width: 16px;
  text-align: center;
  color: #ecd27b;
  flex-shrink: 0;
}

.ts-mall-hot-list__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #a8d4c8;
}

.ts-mall-hot-list__qty {
  flex-shrink: 0;
  color: #5ef0c8;
  font-weight: 600;
}

.ts-placeholder {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 24px;
  text-align: center;
  font-size: 14px;
  color: rgba(168, 212, 200, 0.75);
}

.ts-placeholder--sm {
  font-size: 13px;
}

.screen-page--home-column-flex {
  width: 617px;
  height: 223px;
  display: flex;
  justify-content: space-between;
}

.screen-page--home-column-flex-item {
  width: 304px;
  height: 223px;
  background: url('../../assets/home/mini_box.png') no-repeat center center;
  background-size: 100% 100%;
}

.top_title {
  width: 100%;
  height: 35px;
  box-sizing: border-box;
  font-size: 18px;
  color: #fff;
  line-height: 35px;
  padding-left: 100px;
  margin-bottom: 8px;
  flex-shrink: 0;
}

.ts-overview-grid {
  flex: 1;
  min-height: 0;
  box-sizing: border-box;
  padding: 6px 20px 14px 32px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 1fr);
  gap: 4px 40px;
}

.ts-overview-cell {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  min-height: 0;
  width: 100%;
  text-align: right;
  box-sizing: border-box;
  padding-right: 10px;
}

.ts-overview-cell .content_title {
  width: 100%;
  text-align: right;
}

.ts-overview-cell .content_num {
  width: 100%;
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 6px;
  margin: 4px 0 0;
  line-height: 1.3;
}

.content_num__value {
  flex: 1;
  min-width: 0;
  text-align: right;
  font-size: 24px;
  font-weight: 600;
  background: linear-gradient(to bottom, #98e9aa, #ecd27b);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.content_num :deep(.screen-scroll-number) {
  flex: 1;
  min-width: 0;
  justify-content: flex-end;
  font-size: 24px;
  font-weight: 600;
}

.content_num :deep(.screen-scroll-number__strip),
.content_num :deep(.screen-scroll-number__sep) {
  background: linear-gradient(to bottom, #98e9aa, #ecd27b);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.content_num__unit {
  flex-shrink: 0;
  font-size: 12px;
  color: #a8d4c8;
  line-height: 1.2;
  text-align: right;
}

.ts-overview-cell--placeholder .content_num__value {
  font-size: 18px;
  background: none;
  -webkit-background-clip: unset;
  background-clip: unset;
  color: #6a9f90;
}

.content_title {
  font-size: 11px;
  color: #a8d4c8;
  line-height: 1.3;
}

.flex_title {
  width: 100%;
  box-sizing: border-box;
  height: 35px;
  font-size: 16px;
  color: #fff;
  line-height: 35px;
  padding-left: 45px;
  margin-bottom: 5px;
}

.flex_content {
  width: 100%;
  height: 180px;
  box-sizing: border-box;
  padding: 5px;
}

.flex_content--quote {
  display: flex;
  flex-direction: column;
  padding: 4px 6px;
}

.quote-summary {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 4px;
  min-height: 42px;
  flex-shrink: 0;
}

.quote-summary__item {
  flex: 1 1 calc(50% - 4px);
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(4, 48, 40, 0.45);
  border-radius: 4px;
  border: 1px solid rgba(61, 217, 176, 0.2);
  padding: 2px 0;
}

.quote-summary__label {
  font-size: 9px;
  color: #a8d4c8;
}

.quote-summary__val {
  font-size: 10px;
  color: #fff;
}

.quote-summary__val strong {
  font-size: 12px;
  background: linear-gradient(to bottom, #98e9aa, #ecd27b);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.quote-summary__val--date strong {
  font-size: 10px;
}

.quote-summary__unit {
  font-size: 9px;
  color: #a8d4c8;
  margin-left: 2px;
}

.quote-chart {
  flex: 1;
  min-height: 0;
}
</style>
