import { formatNumber, formatMoneyCompact, fetchJson, buildQuery } from '../helpers';
import { dayDiff, shiftDate, fmtDate, enCaDate } from '../utils/date';
import { renderSunburst } from '../utils/charts';

const TYPE_COLORS = { cast: '#e63946', sample: '#f4a100', ship: '#2ec4b6' };
const TYPE_LABELS = { cast: 'Cast', sample: 'Mẫu', ship: 'Ship' };
const ACTION_LABEL_MAP = {
  'KOC thêm mới': ['invited', 'invited'],
  'Đã liên hệ': ['contacted', 'contacted'],
  'Đã gửi hàng': ['sent', 'sent'],
  'Video thực tế': ['videos', 'videos'],
  'KOC booking': ['booked', 'booked'],
};

export function registerDashboardPage(Alpine) {
  Alpine.data('dashboardPage', () => ({
    loading: false,
    errorMessage: '',
    rangeMode: 'range',
    activePreset: '7days',
    dashboardUrl: '/api/dashboard/data',
    filters: {
      startDate: '',
      endDate: '',
      month: '',
      year: '',
    },
    campaignMetrics: {
      total_campaigns: 0,
      running_campaigns: 0,
      total_kocs: 0,
      total_cast_cost: 0,
      total_sample_cost: 0,
      total_shipping_cost: 0,
      total_all_costs: 0,
    },
    videoMetrics: {
      total_kocs: 0,
      total_videos: 0,
      published: 0,
      pending: 0,
      missing: 0,
    },
    activityData: { invited: 0, contacted: 0, sent: 0, videos: 0, booked: 0 },
    activityDataPrev: { invited: 0, contacted: 0, sent: 0, videos: 0, booked: 0 },
    statusChart: [],
    costChart: { segments: [], type_totals: { cast: 0, sample: 0, ship: 0 }, grand_total: 0, empty: true },
    campaignTableData: [],

    init() {
      const root = this.$el;
      if (root?.dataset?.dashboardUrl) {
        this.dashboardUrl = root.dataset.dashboardUrl;
      }
      this.setDefaultDates();
      this._syncDom();
      this.load();
    },

    setDefaultDates() {
      const today = new Date();
      this.filters.month = String(today.getMonth() + 1).padStart(2, '0');
      this.filters.year = String(today.getFullYear());
      const end = enCaDate(today);
      const startDate = new Date(today);
      startDate.setDate(startDate.getDate() - 6);
      this.filters.startDate = enCaDate(startDate);
      this.filters.endDate = end;
    },

    // Đồng bộ DOM: điền option năm + đồng bộ giá trị các select/input
    _syncDom() {
      this.$nextTick(() => {
        const yearSel = document.getElementById('dashboard-selected-year');
        if (yearSel) {
          const nowYear = new Date().getFullYear();
          yearSel.innerHTML = Array.from({ length: 7 }, (_, i) => nowYear + 2 - i)
            .map(y => `<option value="${y}">${y}</option>`).join('');
          yearSel.value = String(this.filters.year);
        }
        const monthSel = document.getElementById('dashboard-selected-month');
        if (monthSel) monthSel.value = String(this.filters.month);
        const startInput = document.getElementById('dashboard-start-date');
        const endInput = document.getElementById('dashboard-end-date');
        if (startInput) startInput.value = String(this.filters.startDate);
        if (endInput) endInput.value = String(this.filters.endDate);
      });
    },

    /**
     * 1 request duy nhất — thay thế 4 request cũ (campaignMetrics, videoMetrics, activity, campaignTable)
     * Server cache 60s giúp giảm tải DB tối đa.
     */
    async load() {
      this.loading = true;
      this.errorMessage = '';
      try {
        const params = buildQuery({
          start_date: this.filters.startDate,
          end_date: this.filters.endDate,
          month: this.filters.month || '',
          year: this.filters.year || '',
          range_mode: this.rangeMode,
        });
        const data = await fetchJson(this.dashboardUrl + '?' + params);

        if (data.campaign_metrics) Object.assign(this.campaignMetrics, data.campaign_metrics);
        if (data.video_metrics) Object.assign(this.videoMetrics, data.video_metrics);
        if (data.activity_data) Object.assign(this.activityData, data.activity_data);
        if (data.activity_prev) Object.assign(this.activityDataPrev, data.activity_prev);
        if (data.status_chart) this.statusChart = data.status_chart;
        if (data.cost_chart) this.costChart = data.cost_chart;
        if (data.campaign_table) this.campaignTableData = data.campaign_table;
      } catch (e) {
        this.errorMessage = 'Không thể tải dữ liệu dashboard. Vui lòng thử lại.';
      } finally {
        this.loading = false;
        this.$nextTick(() => {
          this.buildCharts();
          this.renderCampaignTable();
        });
      }
    },

    onDateChange() {
      this.activePreset = 'custom';
      this.$nextTick(() => this.load());
    },

    onMonthChange() {
      this.$nextTick(() => this.load());
    },

    async applyPreset(preset) {
      const today = new Date();
      let start = new Date(today);
      let end = new Date(today);

      if (preset === 'custom') {
        this.activePreset = preset;
        return;
      }

      if (preset === 'today') {
        start = new Date(today);
      } else if (preset === '7days') {
        start.setDate(end.getDate() - 6);
      } else if (preset === '30days') {
        start.setDate(end.getDate() - 29);
      } else if (preset === 'thisMonth') {
        start = new Date(today.getFullYear(), today.getMonth(), 1);
        end = new Date(today.getFullYear(), today.getMonth() + 1, 0);
      }

      this.activePreset = preset;
      this.filters.startDate = enCaDate(start);
      this.filters.endDate = enCaDate(end);
      this.filters.month = String(today.getMonth() + 1).padStart(2, '0');
      this.filters.year = String(today.getFullYear());

      this._syncDom();
      await this.load();
    },

    toggleMode(mode) {
      this.rangeMode = mode;
      this.$nextTick(() => this.load());
    },

    get rangeSummary() {
      const mode = this.rangeMode === 'month' ? 'month' : 'range';
      return this.buildRangeStripHtml(mode);
    },

    buildRangeStripHtml(mode) {
      const s = fmtDate(this.filters.startDate);
      const e = fmtDate(this.filters.endDate);
      const prevEnd = shiftDate(this.filters.startDate, -1);
      const prevStart = shiftDate(prevEnd, -(dayDiff(this.filters.startDate, this.filters.endDate) - 1));
      const ml = `T${this.filters.month}/${this.filters.year}`;
      return `
        <div class="db-range-item"><span class="db-rdot db-rdot--blue"></span>Đang xem: <strong>${s} → ${e}</strong></div>
        <span class="db-range-sep">|</span>
        <div class="db-range-item"><span class="db-rdot db-rdot--light"></span>So sánh: <strong>${fmtDate(prevStart)} → ${fmtDate(prevEnd)}</strong></div>
        <span class="db-range-sep">|</span>
        <div class="db-range-item"><span class="db-rdot db-rdot--teal"></span>KPI tháng: <strong>${ml}</strong></div>`;
    },

    // ───── Formatters ─────
    formatNumber(value) {
      return formatNumber(value || 0);
    },

    formatMoneyCompact(value) {
      return formatMoneyCompact(value);
    },

    formatMoney(value) {
      return formatNumber(value || 0) + ' VND';
    },

    get formatRatio() {
      const bookings = Number(this.campaignMetrics.total_kocs || 0);
      const videos = Number(this.videoMetrics.total_videos || 0);
      if (!bookings) return '0%';
      return `${((videos / bookings) * 100).toFixed(1).replace(/\.0$/, '')}%`;
    },

    get formatRatioDetail() {
      const bookings = Number(this.campaignMetrics.total_kocs || 0);
      const videos = Number(this.videoMetrics.total_videos || 0);
      return `${this.formatNumber(videos)} / ${this.formatNumber(bookings)}`;
    },

    // ───── Charts ─────
    buildCharts() {
      this.updateBadges();
      this.renderStatusSunburst();
      this.renderCostSunburst();
    },

    renderStatusSunburst() {
      const segs = this.statusChart || [];
      const total = segs.reduce((s, d) => s + d.value, 0);
      renderSunburst('status-sunburst-svg', 'status-sunburst-legend', 'status-sunburst-tooltip', segs, {
        centerText: total || undefined,
        centerSub: total ? 'Chiến dịch' : undefined,
        emptyText: 'Không có dữ liệu',
        emptyLegend: 'Không có chiến dịch',
        legendTitle: total ? 'Trạng thái' : undefined,
      });
    },

    renderCostSunburst() {
      const chart = this.costChart;
      if (!chart || chart.empty || !chart.segments?.length) {
        renderSunburst('sunburst-svg', 'sunburst-legend', 'sunburst-tooltip', [], {
          emptyText: 'Không có dữ liệu',
          emptyLegend: 'Không có chi phí trong khoảng này',
        });
        this._clearCostTypes();
        return;
      }

      const fmtFull = v => (Number(v) || 0).toLocaleString('vi-VN');

      renderSunburst('sunburst-svg', 'sunburst-legend', 'sunburst-tooltip', chart.segments, {
        centerText: this.formatMoneyCompact(chart.grand_total),
        centerSub: 'TỔNG VND',
        emptyText: 'Không có dữ liệu',
        legendTitle: 'Chiến dịch',
        valueFormatter: v => formatNumber(v) + ' VND',
        tooltipHtml: (item, totalAll) => {
          const c = item._costs || {};
          let html = `<div class="db-tooltip-title">${item.label}</div>`;
          html += `<div class="db-tooltip-value">${fmtFull(item.value)} VND</div>`;
          html += `<div class="db-tooltip-pct">${((item.value / totalAll) * 100).toFixed(1)}%</div>`;
          const hasCost = ['cast', 'sample', 'ship'].some(k => c[k] > 0);
          if (hasCost) {
            html += `<div class="db-tooltip-costs">`;
            ['cast', 'sample', 'ship'].forEach(k => {
              if (c[k] > 0) {
                html += `<span class="db-tooltip-cost-row"><span class="db-cost-dot" style="background:${TYPE_COLORS[k]}"></span><span>${TYPE_LABELS[k]}: <strong>${fmtFull(c[k])} VND</strong></span></span>`;
              }
            });
            html += `</div>`;
          }
          return html;
        },
      });

      this._renderCostTypes(chart, fmtFull);
    },

    _clearCostTypes() {
      const el = document.getElementById('sunburst-cost-types');
      if (el) el.innerHTML = '';
    },

    _renderCostTypes(chart, fmtFull) {
      const el = document.getElementById('sunburst-cost-types');
      if (!el) return;
      const t = chart.type_totals || { cast: 0, sample: 0, ship: 0 };
      const grand = chart.grand_total || 0;
      const pct = (v, total) => total > 0 ? ((v / total) * 100).toFixed(1) + '%' : '0%';
      const items = ['cast', 'sample', 'ship'].map(k =>
        `<div class="db-cost-item"><div class="db-cost-item-header"><span class="db-cost-dot" style="background:${TYPE_COLORS[k]}"></span><span class="db-cost-item-label">${TYPE_LABELS[k]}</span></div><div class="db-cost-item-value">${fmtFull(t[k])} VND <span class="db-cost-item-pct">${pct(t[k], grand)}</span></div></div>`
      ).join('');
      el.innerHTML = `<div class="db-cost-section-title">Tổng loại chi phí</div><div class="db-cost-section-body">${items}</div>`;
    },

    // ───── Delta helpers ─────
    _subHtml(label) {
      const d = this.activityData;
      const p = this.activityDataPrev;
      const keys = ACTION_LABEL_MAP[label];
      if (!keys) return '';
      const [cur, prev] = [d[keys[0]] || 0, p[keys[1]] || 0];
      const sub = `vs ${this.formatNumber(prev)} kỳ trước`;
      if (this.rangeMode !== 'range') return `<span class="stat-sub">${sub}</span>`;
      const delta = Number(cur) - Number(prev);
      const cls = delta > 0 ? 'up' : delta < 0 ? 'down' : 'flat';
      const arrow = delta > 0 ? '▲' : delta < 0 ? '▼' : '—';
      const absDelta = Math.abs(delta).toLocaleString('vi-VN');
      return `<span class="stat-sub">${sub}</span><span class="stat-trend ${cls}">${arrow} ${absDelta}</span>`;
    },

    updateBadges() {
      const days = dayDiff(this.filters.startDate, this.filters.endDate);
      const ml = `T${this.filters.month}/${this.filters.year}`;
      const monthBadge = document.getElementById('db-camp-month-badge');
      const campBadge = document.getElementById('db-badge-campaign');
      const monthLbl = document.getElementById('db-month-lbl');
      if (monthBadge && (!monthBadge.textContent || monthBadge.textContent === '—')) {
        monthBadge.style.display = 'none';
      }
      if (campBadge) campBadge.textContent = `${days} ngày`;
      if (monthLbl) monthLbl.textContent = ml;
    },

    renderCampaignTable() {
      const el = document.getElementById('db-campaign-merged-body');
      if (!el) return;
      if (!this.campaignTableData.length) {
        el.innerHTML = '<tr><td colspan="14" class="db-empty-cell">Chưa có chiến dịch.</td></tr>';
        return;
      }
      el.innerHTML = this.campaignTableData.map(c => {
        const nm = c.campaign_name || '';
        const fmtN = v => Number(v || 0).toLocaleString('vi-VN');
        const pct = Math.min(100, Math.max(0, c.progress_percent || 0));
        const progressColor = pct >= 80 ? 'var(--green)' : pct >= 50 ? 'var(--amber)' : 'var(--red)';
        const progressHtml = `<div class="db-progress-wrap">
          <span class="db-progress-label">${fmtN(c.published_videos)}/${fmtN(c.expected_videos)}</span>
          <span class="db-progress-pct" style="color:${progressColor}">${pct.toFixed(1)}%</span>
        </div><div class="db-bar"><div class="db-bar-fill" style="width:${pct.toFixed(1)}%;background:${progressColor}"></div></div>`;
        return `<tr>
          <td class="db-col-campaign-cell"><span class="db-chip">🎯 ${nm}</span></td>
          <td class="r db-cell-month-first">${fmtN(c.month.invited)}</td>
          <td class="r db-cell-month">${fmtN(c.month.contacted)}</td>
          <td class="r db-cell-month">${fmtN(c.month.sent)}</td>
          <td class="r db-cell-video-first">${fmtN(c.bookings)}</td>
          <td class="r db-cell-video">${fmtN(c.expected_videos)}</td>
          <td class="r db-cell-video">${(c.booking_ratio || 0).toFixed(1)}%</td>
          <td class="db-cell-video" style="min-width:140px">${progressHtml}</td>
          <td class="r db-cell-compare-first">${fmtN(c.current.invited)}</td>
          <td class="r db-cell-compare">${this.deltaHtml(c.current.invited - c.prev.invited)}</td>
          <td class="r db-cell-compare">${fmtN(c.current.contacted)}</td>
          <td class="r db-cell-compare">${this.deltaHtml(c.current.contacted - c.prev.contacted)}</td>
          <td class="r db-cell-compare">${fmtN(c.current.sent)}</td>
          <td class="r db-cell-compare db-cell-compare-last">${this.deltaHtml(c.current.sent - c.prev.sent)}</td>
        </tr>`;
      }).join('');
    },

    deltaHtml(d) {
      const n = Number(d || 0);
      const cls = n > 0 ? 'up' : n < 0 ? 'down' : 'flat';
      const arrow = n > 0 ? '▲' : n < 0 ? '▼' : '—';
      return `<span class="db-delta ${cls}">${arrow} ${Math.abs(n).toLocaleString('vi-VN')}</span>`;
    },
  }));
}