/* ════════════════════════════════════════════════════════
 * page-monthly-summary.js — Turn C
 * ────────────────────────────────────────────────────────
 * monthly_summary_analysis.html 的 ECharts + DataTable 邏輯
 *
 * 注意：依賴 analysis-chart-theme.js 對 echarts.init 的攔截，
 * 它會自動把 option.color 換成 .momo-app[data-page-group] 的
 * --momo-page-chart-* 暖色調 palette，因此本檔保留原 itemStyle.color
 * 邏輯時，會被自動覆寫；分類/條件配色（如 BCG 象限）保持顯式指定。
 * ════════════════════════════════════════════════════════ */
(function () {
  'use strict';

  let table;
  let compareChart, yoyTrendChart, vendorRankingChart, divisionDistChart, priceRangeChart;
  let bcgMatrixChart, priceVolumeScatterChart, seasonalityHeatmapChart, areaRankingChart;
  let specialChart, bodyCareChart, makeupFragranceChart, privacyInfantChart;

  let currentFilters = { year: '', month: '', area: '', vendor: '', trade: '' };
  const compactMediaQuery = window.matchMedia('(max-width: 768px)');

  function isCompactViewport() {
    return compactMediaQuery.matches;
  }

  $(function () {
    compareChart            = echarts.init(document.getElementById('compareChart'));
    yoyTrendChart           = echarts.init(document.getElementById('yoyTrendChart'));
    vendorRankingChart      = echarts.init(document.getElementById('vendorRankingChart'));
    divisionDistChart       = echarts.init(document.getElementById('divisionDistChart'));
    priceRangeChart         = echarts.init(document.getElementById('priceRangeChart'));
    bcgMatrixChart          = echarts.init(document.getElementById('bcgMatrixChart'));
    priceVolumeScatterChart = echarts.init(document.getElementById('priceVolumeScatterChart'));
    seasonalityHeatmapChart = echarts.init(document.getElementById('seasonalityHeatmapChart'));
    areaRankingChart        = echarts.init(document.getElementById('areaRankingChart'));
    specialChart            = echarts.init(document.getElementById('specialChart'));
    bodyCareChart           = echarts.init(document.getElementById('bodyCareChart'));
    makeupFragranceChart    = echarts.init(document.getElementById('makeupFragranceChart'));
    privacyInfantChart      = echarts.init(document.getElementById('privacyInfantChart'));

    table = $('#summaryTable').DataTable({
      language: { url: '//cdn.datatables.net/plug-ins/1.11.5/i18n/zh-HANT.json' },
      autoWidth: false,
      deferRender: true,
      pageLength: 20,
      order: [[0, 'desc'], [7, 'desc']],
      columnDefs: [
        { targets: [7], className: 'text-end fw-bold' },
        { targets: 8, className: 'text-center' }
      ]
    });

    window.addEventListener('resize', () => {
      [compareChart, yoyTrendChart, vendorRankingChart, divisionDistChart, priceRangeChart,
       bcgMatrixChart, priceVolumeScatterChart, seasonalityHeatmapChart, areaRankingChart,
       specialChart, bodyCareChart, makeupFragranceChart, privacyInfantChart]
        .forEach(c => c && c.resize());
    });
    const refreshForViewport = () => fetchData();
    if (compactMediaQuery.addEventListener) {
      compactMediaQuery.addEventListener('change', refreshForViewport);
    } else if (compactMediaQuery.addListener) {
      compactMediaQuery.addListener(refreshForViewport);
    }

    fetchData();
  });

  // ── API ───────────────────────────────────────────────
  function fetchData() {
    $('#loadingOverlay').css('display', 'flex');
    let url = `/api/monthly_summary_data?limit=2000`;
    if (currentFilters.year)   url += `&year=${currentFilters.year}`;
    if (currentFilters.month)  url += `&month=${currentFilters.month}`;
    if (currentFilters.area)   url += `&area_name=${encodeURIComponent(currentFilters.area)}`;
    if (currentFilters.vendor) url += `&vendor=${encodeURIComponent(currentFilters.vendor)}`;
    if (currentFilters.trade)  url += `&trade_type=${encodeURIComponent(currentFilters.trade)}`;

    fetch(url).then(r => r.json()).then(data => {
      if (data.status === 'success') { updateUI(data); updateFilters(data.filters); }
      $('#loadingOverlay').hide();
    }).catch(err => { console.error(err); $('#loadingOverlay').hide(); });

    fetchSpecialChartData();
  }

  function fetchSpecialChartData() {
    const pairs = [
      ['開架保養,臉部清潔', specialChart, 'specialChartTableBody'],
      ['身體保養', bodyCareChart, 'bodyCareChartTableBody'],
      ['彩妝/指彩,精油擴香', makeupFragranceChart, 'makeupFragranceChartTableBody'],
      ['私密保養,嬰幼洗沐', privacyInfantChart, 'privacyInfantChartTableBody']
    ];
    pairs.forEach(([area, chart, tbody]) => {
      fetch(`/api/monthly_summary_trend?area_name=${encodeURIComponent(area)}`)
        .then(r => r.json())
        .then(d => { if (d.status === 'success') renderExcelChart(chart, tbody, d.trend); })
        .catch(err => console.error('monthly special trend failed', err));
    });
  }

  // ── Filter ────────────────────────────────────────────
  function selectFilter(type, value) {
    currentFilters[type] = value;
    const btnMap = { year:'btnYear', month:'btnMonth', area:'btnArea', vendor:'btnVendor', trade:'btnTrade' };
    const defaultMap = { year:'選擇年份', month:'選擇月份', area:'所有區域', vendor:'所有廠商', trade:'所有類別' };
    $(`#${btnMap[type]}`).text(value || defaultMap[type]);
    fetchData();
  }
  window.selectFilter = selectFilter;

  function filterList(input) {
    const filter = input.value.toLowerCase();
    const list = input.closest('ul').querySelectorAll('li:not(:first-child)');
    list.forEach(li => {
      const t = (li.textContent || li.innerText).toLowerCase();
      li.style.display = t.indexOf(filter) > -1 ? '' : 'none';
    });
  }
  window.filterList = filterList;

  function updateFilters(f) {
    const populate = (id, list, type) => {
      const el = $(id);
      if (el.children().length > 1) return;
      list.forEach(v => el.append(`<li><a class="dropdown-item" href="#" onclick="selectFilter('${type}', '${v}')">${v}</a></li>`));
    };
    populate('#listYear',   f.years,                                       'year');
    populate('#listMonth',  f.months.map(String).sort((a,b) => a - b),     'month');
    populate('#listArea',   f.areas,                                       'area');
    populate('#listTrade',  f.trades,                                      'trade');
    populate('#listVendor', f.vendors,                                     'vendor');
  }

  // ── UI updates ────────────────────────────────────────
  function updateUI(data) {
    $('#totalRows').text(data.total_rows.toLocaleString());
    $('#totalMonths').text(data.total_months);

    const k = data.kpis || {};
    $('#kpiSales').text('$' + (k.sales || 0).toLocaleString());
    $('#kpiProfit').text('$' + (k.profit || 0).toLocaleString());
    $('#kpiMargin').text(k.margin || '-');
    $('#kpiVol').text((k.vol || 0).toLocaleString());

    if (k.sales_yoa > 0) {
      const yoy = ((k.sales - k.sales_yoa) / k.sales_yoa * 100).toFixed(1);
      const cls = yoy >= 0 ? 'text-danger' : 'text-success';
      $('#kpiSalesYoY').html(`<span class="${cls} fw-bold"><i class="fas fa-caret-up"></i> ${yoy}%</span> vs 去年同期`);
    } else { $('#kpiSalesYoY').text('-'); }

    table.clear();
    (data.rows || []).forEach(row => {
      const sales = row.sales_amt_curr || 0;
      const prevYear = row.sales_amt_yoa || 0;
      let yoyHtml = '-';
      if (prevYear > 0) {
        const yoy = ((sales - prevYear) / prevYear * 100).toFixed(1);
        const cls = yoy >= 0 ? 'text-danger' : 'text-success';
        yoyHtml = `<span class="${cls} fw-bold">${yoy > 0 ? '+' : ''}${yoy}%</span>`;
      }
      table.row.add([
        `${row.year}/${row.month}`, row.division, row.area_name || '-', row.pm_name || '-',
        `<span class="text-primary fw-600">${row.brand_name}</span>`,
        `<span class="small text-muted">${row.vendor_name}</span>`,
        `<span class="badge bg-light text-dark border">${row.trade_type || '-'}</span>`,
        sales.toLocaleString(), yoyHtml
      ]);
    });
    table.draw();

    renderExcelChart(compareChart, 'compareChartTableBody', data.trend);
    updateHighlights(data.highlights);
    renderYoYTrendChart(yoyTrendChart, 'yoyTrendChartTableBody', data.yoy_trend);
    renderVendorRankingChart(vendorRankingChart, 'vendorRankingChartTableBody', data.vendor_ranking);
    renderDivisionDistChart(divisionDistChart, 'divisionDistChartTableBody', data.division_dist);
    renderPriceRangeChart(priceRangeChart, 'priceRangeChartTableBody', data.price_contribution);
    renderBCGMatrixChart(bcgMatrixChart, data.bcg_data);
    renderScatterChart(priceVolumeScatterChart, data.bcg_data);
    renderSeasonalityHeatmap(seasonalityHeatmapChart, data.heatmap_data);
    renderAreaRankingChart(areaRankingChart, 'areaRankingChartTableBody', data.area_ranking);
  }

  // ── Highlights (Top 3) ────────────────────────────────
  function updateHighlights(h) {
    if (!h || (!h.rev_top.length && !h.profit_top.length)) { $('#highlightsRow').hide(); return; }
    $('#highlightsRow').show();
    const r = (id, list, prefix='') => {
      const t = $(`#${id}`); t.empty();
      list.forEach((it, i) => t.append(`<tr><td class="ps-3"><span class="badge bg-secondary rounded-pill me-2">${i+1}</span>${it.name}</td><td class="text-end pe-3 fw-bold">${prefix}${it.value.toLocaleString()}</td></tr>`));
    };
    r('revHighlightsBody', h.rev_top, '$');
    r('profitHighlightsBody', h.profit_top, '$');
    r('volHighlightsBody', h.vol_top, '');
  }

  // ── Excel-style 主對比圖 ─────────────────────────────
  function renderExcelChart(chart, tableBodyId, trend) {
    if (!trend) return;
    const compact = isCompactViewport();
    const years = [...new Set(trend.map(t => t.date.split('/')[0]))].sort().reverse();
    const currYear = years[0] || String(new Date().getFullYear());
    const prevYear = String(parseInt(currYear) - 1);
    const months = Array.from({ length: 12 }, (_, i) => String(i + 1));
    const currData = new Array(12).fill(0);
    const prevData = new Array(12).fill(0);
    const yoyData  = new Array(12).fill(0);
    trend.forEach(t => {
      const [y, m] = t.date.split('/');
      if (y === currYear) currData[parseInt(m) - 1] = t.sales;
      if (y === prevYear) prevData[parseInt(m) - 1] = t.sales;
    });
    for (let i = 0; i < 12; i++) {
      if (prevData[i] > 0) yoyData[i] = parseFloat(((currData[i] - prevData[i]) / prevData[i] * 100).toFixed(1));
    }

    const C1 = 'var(--momo-warm-caramel, #c96442)';
    const C2 = 'var(--momo-warm-olive, #6f7a4a)';
    const CM = 'var(--momo-text-tertiary, #94a3b8)';

    const tableHtml = `
      <tr><td class="ms-cmp__hd">月份</td>${months.map(m => `<td class="ms-cmp__mh">${m}</td>`).join('')}</tr>
      <tr><td class="text-start ps-2"><span class="ms-cmp__sw" style="background:${C1}"></span>${currYear}</td>${currData.map(v => `<td>${v > 0 ? v.toLocaleString() : '-'}</td>`).join('')}</tr>
      <tr><td class="text-start ps-2"><span class="ms-cmp__sw" style="background:${C2}"></span>${prevYear}</td>${prevData.map(v => `<td>${v > 0 ? v.toLocaleString() : '-'}</td>`).join('')}</tr>
      <tr><td class="text-start ps-2"><i class="fas fa-minus" style="color:${CM};margin-right:5px;"></i>YOY</td>${yoyData.map((v, i) => `<td>${(currData[i] > 0 || prevData[i] > 0) ? v + '%' : '-'}</td>`).join('')}</tr>`;
    $(`#${tableBodyId}`).html(tableHtml);

    chart.setOption({
      tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
      legend: { data: [currYear, prevYear, 'YOY'], bottom: 0, show: false },
      grid: {
        left: compact ? '42' : '80',
        right: compact ? '16' : '50',
        top: compact ? '26' : '50',
        bottom: compact ? '28' : '20'
      },
      xAxis: {
        type: 'category',
        data: months,
        axisLabel: { show: compact, interval: 0, fontSize: 10 },
        axisTick: { show: true }
      },
      yAxis: [
        { type: 'value', name: compact ? '' : '業績', axisLabel: { formatter: v => compact ? (v/10000).toFixed(0) + '萬' : v.toLocaleString(), fontSize: compact ? 10 : 12 }, splitLine: { lineStyle: { type: 'dashed' } } },
        { type: 'value', name: compact ? '' : 'YoY',  axisLabel: { formatter: '{value}%', fontSize: compact ? 10 : 12 }, splitLine: { show: false } }
      ],
      series: [
        { name: currYear, type: 'bar', data: currData, barMaxWidth: compact ? 12 : 20,
          label: { show: !compact, position: 'top', fontSize: 16, fontWeight: 'bold', formatter: p => p.value ? (p.value/10000).toFixed(0) + '萬' : '' } },
        { name: prevYear, type: 'bar', data: prevData, barMaxWidth: compact ? 12 : 20,
          label: { show: !compact, position: 'top', fontSize: 16, fontWeight: 'bold', formatter: p => p.value ? (p.value/10000).toFixed(0) + '萬' : '' } },
        { name: 'YOY', type: 'line', yAxisIndex: 1, data: yoyData, smooth: true,
          lineStyle: { width: compact ? 1.5 : 2 }, symbol: 'circle', symbolSize: compact ? 4 : 6,
          label: { show: !compact, position: 'bottom', fontSize: 16, fontWeight: 'bold', formatter: p => p.value ? p.value + '%' : '' } }
      ]
    });
  }

  // ── YoY Trend ─────────────────────────────────────────
  function renderYoYTrendChart(chart, tableId, data) {
    if (!data || !data.length) return;
    const compact = isCompactViewport();
    const dates = data.map(d => d.date.split('/')[1] + '月');
    const currData = data.map(d => d.curr);
    const yoaData  = data.map(d => d.yoa);
    const years = [...new Set(data.map(d => d.date.split('/')[0]))];
    const currYearStr = years[0] || '本期';

    let html = `
      <tr><td class="ms-cmp__hd">月份</td>${dates.map(m => `<td class="ms-cmp__mh">${m}</td>`).join('')}</tr>
      <tr><td class="text-start ps-2"><span class="ms-cmp__sw ms-cmp__sw--accent"></span>${currYearStr}</td>${currData.map(v => `<td>${v > 0 ? v.toLocaleString() : '-'}</td>`).join('')}</tr>
      <tr><td class="text-start ps-2"><span class="ms-cmp__sw ms-cmp__sw--muted"></span>去年同期</td>${yoaData.map(v => `<td>${v > 0 ? v.toLocaleString() : '-'}</td>`).join('')}</tr>`;
    $(`#${tableId}`).html(html);

    chart.setOption({
      tooltip: { trigger: 'axis' },
      grid: { left: compact ? '42' : '60', right: compact ? '14' : '30', top: compact ? '24' : '40', bottom: compact ? '26' : '20' },
      legend: { data: [currYearStr, '去年同期'], bottom: 0, show: !compact },
      xAxis: { type: 'category', data: dates, axisLabel: { fontSize: compact ? 10 : 12 } },
      yAxis: { type: 'value', axisLabel: { formatter: v => (v/10000).toFixed(0) + '萬', fontSize: compact ? 10 : 12 } },
      series: [
        { name: currYearStr, type: 'line', data: currData, lineStyle: { width: 3 }, showSymbol: false, areaStyle: { opacity: 0.12 } },
        { name: '去年同期',   type: 'line', data: yoaData,  lineStyle: { type: 'dashed' }, showSymbol: false }
      ]
    });
  }

  // ── 類別分佈 (雙圓餅) ─────────────────────────────────
  function renderDivisionDistChart(chart, _tableId, data) {
    if (!data || !data.length) return;
    const compact = isCompactViewport();
    const pie = key => data.map(d => ({ name: d.name, value: d[key] || 0 })).filter(d => d.value > 0);
    chart.setOption({
      title: [
        { text: '2024 年', left: '23%', top: compact ? '2%' : '5%', textAlign: 'center', textStyle: { fontSize: compact ? 12 : 16, fontWeight: 'bold' } },
        { text: '2025 年', left: '73%', top: compact ? '2%' : '5%', textAlign: 'center', textStyle: { fontSize: compact ? 12 : 16, fontWeight: 'bold' } }
      ],
      tooltip: { trigger: 'item', formatter: p => `<strong>${p.name}</strong><br/>業績: ${(p.value/10000).toFixed(0)}萬<br/>佔比: ${p.percent.toFixed(1)}%` },
      legend: { type: 'scroll', orient: 'horizontal', bottom: 0, show: !compact, textStyle: { fontSize: 12, fontWeight: 'bold' } },
      series: [
        { name: '2024 年', type: 'pie', radius: compact ? ['36%', '58%'] : ['30%', '60%'], center: ['25%', compact ? '53%' : '55%'], data: pie('sales_2024'),
          label: { show: !compact, fontSize: 11, fontWeight: 'bold', formatter: p => `${p.name}\n${(p.value/10000).toFixed(0)}萬\n${p.percent.toFixed(1)}%` } },
        { name: '2025 年', type: 'pie', radius: compact ? ['36%', '58%'] : ['30%', '60%'], center: ['75%', compact ? '53%' : '55%'], data: pie('sales_2025'),
          label: { show: !compact, fontSize: 11, fontWeight: 'bold', formatter: p => `${p.name}\n${(p.value/10000).toFixed(0)}萬\n${p.percent.toFixed(1)}%` } }
      ]
    });
  }

  // ── 價格帶 ────────────────────────────────────────────
  function renderPriceRangeChart(chart, tableId, data) {
    if (!data || !data.length) return;
    const compact = isCompactViewport();
    const order = ['0-499','500-999','1,000-1,999','2,000-4,999','5,000-9,999','10,000+'];
    data.sort((a,b) => order.indexOf(a.range) - order.indexOf(b.range));
    const t24 = data.reduce((s, x) => s + (x.sales_2024 || 0), 0);
    const t25 = data.reduce((s, x) => s + (x.sales_2025 || 0), 0);

    chart.setOption({
      tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' },
        formatter: ps => ps[0].name + '<br/>' + ps.map(p => {
          const v = p.value || 0;
          const total = p.seriesName.includes('2024') ? t24 : t25;
          const pct = total > 0 ? (v/total*100).toFixed(1) + '%' : '0.0%';
          return `${p.marker} ${p.seriesName}: ${v.toLocaleString()} (${pct})`;
        }).join('<br/>')
      },
      legend: { data: ['2024 銷售', '2025 銷售'], bottom: 0, show: !compact, textStyle: { fontSize: 13, fontWeight: 'bold' } },
      grid: { left: compact ? '2%' : '3%', right: compact ? '2%' : '4%', bottom: compact ? '18%' : '12%', top: compact ? '8%' : '15%', containLabel: true },
      xAxis: { type: 'category', data: data.map(d => d.range), axisLabel: { interval: 0, rotate: compact ? 32 : 0, fontSize: compact ? 10 : 13, fontWeight: 'bold' } },
      yAxis: { type: 'value', name: compact ? '' : '銷售額', nameTextStyle: { fontSize: 12, fontWeight: 'bold' },
        axisLabel: { formatter: v => (v/10000).toFixed(0) + '萬', fontSize: compact ? 10 : 12 } },
      series: ['2024','2025'].map((y) => ({
        name: y + ' 銷售', type: 'bar', barWidth: compact ? 13 : 30,
        data: data.map(d => d['sales_' + y] || 0),
        label: { show: !compact, position: 'top', fontSize: 12, fontWeight: 'bold',
          formatter: p => {
            const v = p.value || 0;
            const total = y === '2024' ? t24 : t25;
            const pct = total > 0 ? (v/total*100).toFixed(1) + '%' : '';
            return pct + '\n' + (v/10000).toFixed(0) + '萬';
          }
        }
      }))
    });
    $(`#${tableId}`).parent().html('');
  }

  // ── BCG 矩陣（4 象限顯式配色） ───────────────────────
  function renderBCGMatrixChart(chart, data) {
    if (!data || !data.length) return;
    const compact = isCompactViewport();
    const C_STAR     = 'var(--momo-warm-olive, #6f7a4a)';
    const C_COW      = 'var(--momo-warm-honey, #c89043)';
    const C_QUESTION = 'var(--momo-warm-caramel, #c96442)';
    const C_DOG      = 'var(--momo-warm-mahogany, #7a3b2c)';
    chart.setOption({
      tooltip: { formatter: p => `<div style="font-weight:bold">${p.value[3]}</div><div>毛利率: ${p.value[0]}%</div><div>銷售額: $${p.value[1].toLocaleString()}</div><div>銷量: ${p.value[2].toLocaleString()}</div>` },
      grid: { left: compact ? '46' : '80', right: compact ? '16' : '50', top: compact ? '18' : '30', bottom: compact ? '34' : '30' },
      xAxis: { name: compact ? '' : '毛利率(%)', type: 'value', axisLabel: { fontSize: compact ? 10 : 12 }, splitLine: { lineStyle: { type: 'dashed' } } },
      yAxis: { name: compact ? '' : '業績($)',   type: 'value', axisLabel: { formatter: v => compact ? (v/10000).toFixed(0) + '萬' : v.toLocaleString(), fontSize: compact ? 10 : 12 }, splitLine: { lineStyle: { type: 'dashed' } } },
      series: [{
        type: 'scatter',
        data: data.map(d => [d.margin, d.sales, d.qty, d.name]),
        symbolSize: d => Math.min(compact ? 52 : 96, Math.max(compact ? 8 : 10, Math.sqrt(Math.max(d[2], 1)) * (compact ? 0.35 : 0.75))),
        itemStyle: {
          color: p => {
            if (p.value[0] >= 30 && p.value[1] >= 500000) return C_STAR;
            if (p.value[0] <  30 && p.value[1] >= 500000) return C_COW;
            if (p.value[0] >= 30 && p.value[1] <  500000) return C_QUESTION;
            return C_DOG;
          },
          opacity: 0.78, borderColor: '#fff8ef', borderWidth: 1
        },
        markLine: { silent: true, data: [
          { xAxis: 30, lineStyle: { color: '#999' }, label: { show: !compact, formatter: '高獲利線 (30%)' } },
          { yAxis: 500000, lineStyle: { color: '#999' }, label: { show: !compact, formatter: '高營收線 ($50萬)' } }
        ] }
      }]
    });
  }

  // ── 散佈圖（價/量） ──────────────────────────────────
  function renderScatterChart(chart, data) {
    if (!data || !data.length) return;
    const compact = isCompactViewport();
    const series = data.map(d => {
      const avg = d.qty > 0 ? Math.round(d.sales / d.qty) : 0;
      return [avg, d.qty, d.sales, d.name];
    });
    chart.setOption({
      tooltip: { formatter: p => `<div style="font-weight:bold">${p.value[3]}</div><div>均價: $${p.value[0]}</div><div>銷量: ${p.value[1].toLocaleString()}</div><div>業績: $${p.value[2].toLocaleString()}</div>` },
      grid: { left: compact ? '42' : '60', right: compact ? '16' : '50', top: compact ? '18' : '30', bottom: compact ? '32' : '30' },
      xAxis: { name: compact ? '' : '均價($)', type: 'value', axisLabel: { fontSize: compact ? 10 : 12 }, splitLine: { show: false } },
      yAxis: { name: compact ? '' : '銷量',     type: 'value', axisLabel: { fontSize: compact ? 10 : 12 }, splitLine: { lineStyle: { type: 'dashed' } } },
      series: [{ type: 'scatter', data: series, symbolSize: d => Math.min(compact ? 36 : 64, Math.max(compact ? 6 : 8, Math.log(Math.max(d[2],1)) * (compact ? 1.35 : 2))), itemStyle: { opacity: 0.65 } }]
    });
  }

  // ── 廠商排行 ──────────────────────────────────────────
  function renderVendorRankingChart(chart, tableId, data) {
    if (!data || !data.length) return;
    const compact = isCompactViewport();
    const cd = data.slice().reverse();
    chart.setOption({
      tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
      legend: { data: ['2024 銷售額', '2025 銷售額'], bottom: 0, show: !compact, textStyle: { fontSize: 15, fontWeight: 'bold' } },
      grid: { left: compact ? '86' : '160', right: compact ? '18' : '110', top: compact ? '10' : '20', bottom: compact ? '28' : '45' },
      xAxis: { type: 'value', axisLabel: { formatter: v => (v/10000).toFixed(0) + '萬', fontSize: compact ? 10 : 14, fontWeight: 'bold' } },
      yAxis: { type: 'category', data: cd.map(d => d.name), axisLabel: { width: compact ? 78 : 150, overflow: 'truncate', interval: 0, fontSize: compact ? 10 : 14, fontWeight: 'bold' } },
      series: [
        { name: '2024 銷售額', type: 'bar', data: cd.map(d => d.sales_2024 || 0), barWidth: compact ? 10 : 18, barGap: '0%', barCategoryGap: compact ? '70%' : '75%',
          label: { show: !compact, position: 'insideRight', fontSize: 13, fontWeight: 'bold', color: '#fff8ef', textShadowColor: 'rgba(42,37,32,0.5)', textShadowBlur: 2,
            formatter: p => p.value > 0 ? (p.value/10000).toFixed(0) + '萬' : '' } },
        { name: '2025 銷售額', type: 'bar', data: cd.map(d => d.sales_2025 || 0), barWidth: compact ? 10 : 18,
          label: { show: !compact, position: 'right', fontSize: 14, fontWeight: 'bold',
            formatter: p => p.value > 0 ? (p.value/10000).toFixed(0) + '萬' : '' } }
      ]
    });

    let html = `<thead class="table-light"><tr>
      <th>排名</th><th>廠商名稱</th><th class="text-end">總銷售額</th><th class="text-end">銷售額 YoY</th>
      <th class="text-end">2024 銷售額</th><th class="text-end">2025 銷售額</th>
      <th class="text-end">總毛利額</th><th class="text-end">毛利額 YoY</th>
      <th class="text-end">2024 毛利額</th><th class="text-end">2025 毛利額</th></tr></thead><tbody>`;
    data.forEach((d, i) => {
      const s24 = d.sales_2024 || 0, s25 = d.sales_2025 || 0, p24 = d.profit_2024 || 0, p25 = d.profit_2025 || 0;
      const sYoY = s24 > 0 ? ((s25-s24)/s24*100).toFixed(1)+'%' : '-';
      const pYoY = p24 > 0 ? ((p25-p24)/p24*100).toFixed(1)+'%' : '-';
      const sCls = s24 > 0 && (s25-s24) >= 0 ? 'text-danger' : (s24 > 0 ? 'text-success' : '');
      const pCls = p24 > 0 && (p25-p24) >= 0 ? 'text-danger' : (p24 > 0 ? 'text-success' : '');
      html += `<tr>
        <td>${i+1}</td>
        <td class="text-start text-truncate" style="max-width:200px;">${d.name}</td>
        <td class="text-end fw-bold">${d.sales.toLocaleString()}</td>
        <td class="text-end fw-bold ${sCls}">${sYoY}</td>
        <td class="text-end text-muted">${s24.toLocaleString()}</td>
        <td class="text-end text-primary fw-bold">${s25.toLocaleString()}</td>
        <td class="text-end fw-bold">${d.profit.toLocaleString()}</td>
        <td class="text-end fw-bold ${pCls}">${pYoY}</td>
        <td class="text-end text-muted">${p24.toLocaleString()}</td>
        <td class="text-end text-success fw-bold">${p25.toLocaleString()}</td></tr>`;
    });
    html += `</tbody>`;
    $(`#${tableId}`).parent().html(`<table class="table table-bordered table-hover table-sm text-center mb-0 small" style="white-space:nowrap;">${html}</table>`);
  }

  // ── 季節熱力圖 ────────────────────────────────────────
  function renderSeasonalityHeatmap(chart, data) {
    if (!data || !data.length) return;
    const compact = isCompactViewport();
    const months = ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'];
    const areaSales = {};
    data.forEach(d => { areaSales[d.category] = (areaSales[d.category] || 0) + d.sales; });
    const areas = Object.keys(areaSales).sort((a,b) => areaSales[b] - areaSales[a]);
    const yLabels = [];
    [2025, 2024].forEach(y => areas.forEach(a => yLabels.push(`${y} ${a}`)));
    const heatmap = [];
    data.forEach(d => {
      const xi = d.month - 1, yi = yLabels.indexOf(`${d.year} ${d.category}`);
      if (xi >= 0 && xi < 12 && yi >= 0) heatmap.push([xi, yi, d.sales]);
    });
    const max = Math.max(...data.map(d => d.sales), 1);
    chart.setOption({
      tooltip: { position: 'top',
        formatter: p => `<strong>${yLabels[p.value[1]]}</strong><br/>${months[p.value[0]]}<br/>業績: <strong>${(p.value[2]/10000).toFixed(0)}萬</strong>` },
      grid: { height: compact ? '72%' : '75%', top: compact ? '3%' : '5%', bottom: compact ? '20%' : '18%', left: compact ? '72' : '15%', right: compact ? '5' : '3%' },
      xAxis: { type: 'category', data: months, splitArea: { show: true }, axisLabel: { fontSize: compact ? 10 : 14, fontWeight: 'bold' } },
      yAxis: { type: 'category', data: yLabels, splitArea: { show: true }, axisLabel: { width: compact ? 66 : 120, overflow: 'truncate', fontSize: compact ? 10 : 14, fontWeight: 'bold' } },
      visualMap: { min: 0, max, calculable: true, orient: 'horizontal', left: 'center', bottom: '0%', textStyle: { fontSize: compact ? 10 : 12 },
        inRange: { color: ['#fef3c7', '#f5c98a', '#e3a560', '#c96442', '#7a3b2c'] } },
      series: [{ type: 'heatmap', data: heatmap,
        label: { show: !compact, fontSize: 12, fontWeight: 'bold', formatter: p => (p.value[2]/10000).toFixed(0) + '萬' },
        emphasis: { itemStyle: { shadowBlur: 10, shadowColor: 'rgba(0,0,0,0.45)' } } }]
    });
  }

  // ── 區域排行 ──────────────────────────────────────────
  function renderAreaRankingChart(chart, tableId, data) {
    if (!data || !data.length) return;
    const compact = isCompactViewport();
    data.sort((a,b) => b.sales - a.sales);
    chart.setOption({
      tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' },
        formatter: ps => ps[0].name + '<br/>' + ps.map(p => `${p.marker} ${p.seriesName}: ${(p.value || 0).toLocaleString()}`).join('<br/>') },
      legend: { data: ['2024 業績', '2025 業績'], bottom: 0, show: !compact, textStyle: { fontSize: 14 } },
      grid: { left: compact ? '2%' : '3%', right: compact ? '2%' : '4%', bottom: compact ? '20%' : '10%', top: compact ? '8%' : '10%', containLabel: true },
      xAxis: { type: 'category', data: data.map(d => d.name), axisLabel: { interval: 0, rotate: compact ? 28 : 0, fontSize: compact ? 10 : 14, fontWeight: 'bold' } },
      yAxis: { type: 'value', name: compact ? '' : '業績', axisLabel: { formatter: v => (v/10000).toFixed(0) + '萬', fontSize: compact ? 10 : 13 } },
      series: ['2024','2025'].map(y => ({
        name: y + ' 業績', type: 'bar', data: data.map(d => d['sales_' + y] || 0),
        label: { show: !compact, position: 'top', fontSize: 14, fontWeight: 'bold', formatter: p => (p.value/10000).toFixed(0) + '萬' }
      }))
    });
    let html = `<thead class="table-light"><tr><th>排名</th><th>區名稱</th><th>業績</th></tr></thead><tbody>`;
    data.forEach((d, i) => { html += `<tr><td>${i+1}</td><td class="text-start">${d.name}</td><td class="text-end fw-bold">$${d.sales.toLocaleString()}</td></tr>`; });
    html += `</tbody>`;
    $(`#${tableId}`).parent().html(`<table class="table table-bordered table-hover table-sm text-center mb-0 small">${html}</table>`);
  }

  // 公開 fetchData 給 onclick 使用
  window.fetchData = fetchData;
})();
