import type { CommandBus } from '@application/handlers/CommandBus';
import type { QueryBus } from '@application/handlers/QueryBus';
import type { UIState } from '@presentation/state/UIState';
import type { DashboardResult } from '@application/queries/GetDashboard';
import type { Enclos } from '@domain/entities/Enclos';
import { MAX_DD } from '@domain/entities/Enclos';
import { GAUGE_DEFS } from '@domain/value-objects/GaugeType';
import { raceColor } from '@domain/value-objects/Race';
import { enclosGlobalState, enclosGaugeCurGl } from '@presentation/helpers/gauge-live';
import { esc, fmtClock } from '@presentation/helpers/format';
import { Toast } from './Toast';
import { ConfirmModal } from './ConfirmModal';
import { UndoManager } from '@presentation/services/UndoManager';

export class Dashboard {
  private el: HTMLElement | null = null;
  private lastRenderTime = 0;

  constructor(
    private commandBus: CommandBus,
    private queryBus: QueryBus,
    private uiState: UIState,
  ) {}

  render(container: HTMLElement): void {
    this.el = document.createElement('div');
    this.el.className = 'dash-new';
    container.appendChild(this.el);
    this.renderAll();
  }

  private getData(): DashboardResult {
    return this.queryBus.execute<DashboardResult>({ type: 'get-dashboard' });
  }

  private renderAll(): void {
    if (!this.el) return;
    const data = this.getData();

    // ── KPI Section ──────────────────────────────────────────────
    const activeDD = data.enclosSummaries.reduce((s, e) => s + e.ddCount, 0);
    const racesObtained = Object.keys(data.raceBreakdown).length;
    const kpis = [
      { label: 'Total Bébés',         value: String(data.totalBabies) },
      { label: 'Dragodindes Actives',  value: String(activeDD) },
      { label: 'Couples Formés',       value: String(data.totalCouples) },
      { label: 'Taux de Réussite',     value: `${data.successRate}%` },
      { label: 'Races Obtenues',       value: String(racesObtained) },
    ];

    let kpiHtml = `
      <section>
        <div class="dash-section-hd">
          <span class="dash-section-lbl">Statistiques Globales</span>
          <button class="dash-reset-btn-new" id="dash-reset-btn">
            <span class="material-symbols-outlined">restart_alt</span>
            Réinitialiser
          </button>
        </div>
        <div class="dash-kpi-grid-new">
    `;
    for (const kpi of kpis) {
      kpiHtml += `
        <div class="dash-kpi-card">
          <p class="dash-kpi-lbl">${esc(kpi.label)}</p>
          <span class="dash-kpi-val">${esc(kpi.value)}</span>
        </div>
      `;
    }
    kpiHtml += `</div></section>`;

    // ── Two-column section ───────────────────────────────────────
    let enclosHtml = `
      <section>
        <div class="dash-section-hd">
          <span class="dash-section-lbl">Aperçu — Tous les enclos</span>
        </div>
        <div class="dash-enc-grid">
    `;

    for (const summary of data.enclosSummaries) {
      const enc = this.queryBus.execute<Enclos | null>({ type: 'get-enclos-detail', enclosId: summary.id });
      const gs = enc ? enclosGlobalState(enc) : null;
      const started = !!enc?.timer.startTime;
      const running = !!enc?.timer.running;
      const allDone = !!gs?.allDone && started;

      // Status
      let statusClass = 'idle';
      let statusLabel = 'Inactif';
      if (running) { statusClass = 'running'; statusLabel = 'Actif'; }
      else if (started) { statusClass = 'paused'; statusLabel = 'Pause'; }

      const cardClass = `dash-enc-card${running ? ' running' : ''}${allDone ? ' done-enc' : ''}`;

      // Gauge tags — détecte les jauges vides en cours de session
      const gaugeTags = summary.activeGauges.map(gid => {
        const def = GAUGE_DEFS[gid as keyof typeof GAUGE_DEFS];
        if (!def) return '';
        const cssVar = `var(${def.cssVar})`;
        const curGl = (enc && started) ? enclosGaugeCurGl(enc, gid as any) : (enc?.gaugeLevels[gid as keyof typeof enc.gaugeLevels] ?? 0);
        const isEmpty = curGl <= 0 && started;
        if (isEmpty) {
          return `<span class="dash-enc-gauge-tag dash-gauge-empty"
            style="background:rgba(234,179,8,0.12);border-color:rgba(234,179,8,0.3);color:#eab308">
            ⚠ ${esc(def.label)}
          </span>`;
        }
        return `<span class="dash-enc-gauge-tag"
          style="background:color-mix(in srgb, ${cssVar} 10%, transparent);border-color:color-mix(in srgb, ${cssVar} 30%, transparent);color:${cssVar}">
          ${def.icon} ${esc(def.label)}
        </span>`;
      }).join('');
      const gaugesRow = summary.activeGauges.length > 0
        ? `<div class="dash-enc-gauges-row">${gaugeTags}</div>`
        : `<div class="dash-enc-gauges-row"><span class="dash-enc-no-gauge">Aucune jauge active</span></div>`;

      // Sous-label capacité max (uniquement quand l'enclos est plein)
      const capaciteLabel = summary.ddCount >= MAX_DD ? 'Capacit\u00e9 max' : '';
      const cdText = started && gs ? (gs.allDone ? '✅' : (!isFinite(gs.globalMax) ? '∞' : fmtClock(gs.globalMax))) : '--:--:--';
      const elText = started && gs ? fmtClock(gs.el) : '--:--:--';

      // Button style: active = primary button if running and approaching end
      const btnClass = allDone ? 'dash-enc-btn btn-active' : 'dash-enc-btn';

      enclosHtml += `
        <div class="${cardClass}" id="dash-enc-${summary.id}" data-enc-id="${summary.id}">
          <div class="dash-enc-header-row">
            <span class="dash-enc-name-new">${esc(summary.name.toUpperCase())}</span>
            <div class="dash-enc-status-badge ${statusClass}">
              <span class="dash-enc-dot ${statusClass}"></span>
              ${esc(statusLabel)}
            </div>
          </div>

          <div class="dash-enc-meta-row">
            <div class="dash-enc-dd-block">
              <div class="dd-count-big">${summary.ddCount} <span style="font-family:'Inter',sans-serif;font-size:14px;color:rgba(176,168,182,0.6);font-weight:500;margin-left:4px">DD</span></div>
              ${capaciteLabel ? `<div class="dd-count-sub">${capaciteLabel}</div>` : ''}
            </div>
            <div class="dash-enc-times">
              <div class="dash-enc-time-row primary">
                <span class="material-symbols-outlined">hourglass_top</span>
                Restant : <span id="dash-cd-${summary.id}">${cdText}</span>
              </div>
              <div class="dash-enc-time-row muted">
                <span class="material-symbols-outlined">schedule</span>
                Écoulé : <span id="dash-el-${summary.id}">${elText}</span>
              </div>
            </div>
          </div>

          ${gaugesRow}

          <button class="${btnClass}" data-enc-id="${summary.id}">
            Gérer cet enclos
            <span class="material-symbols-outlined">arrow_forward</span>
          </button>
        </div>
      `;
    }

    enclosHtml += `</div></section>`;

    // ── Race progression panel (right col) ───────────────────────
    const raceEntries = Object.entries(data.raceBreakdown).sort((a, b) => b[1] - a[1]);
    const maxCount = raceEntries.length > 0 ? raceEntries[0][1] : 1;

    let raceHtml = `
      <div>
        <div class="dash-section-hd">
          <span class="dash-section-lbl">Progression des races</span>
        </div>
        <div class="dash-race-panel">
    `;

    if (raceEntries.length === 0) {
      raceHtml += `<p class="dash-race-empty">Aucune race enregistrée</p>`;
    } else {
      for (const [race, count] of raceEntries) {
        const pct = maxCount > 0 ? (count / maxCount) * 100 : 0;
        const col = raceColor(race);
        raceHtml += `
          <div class="dash-race-row">
            <div class="dash-race-row-hd">
              <span style="color:${col}">${esc(race)}</span>
              <span style="color:rgba(176,168,182,0.7)">${count}</span>
            </div>
            <div class="dash-race-bar-bg">
              <div class="dash-race-bar-fill" style="width:${pct}%;background:${col}"></div>
            </div>
          </div>
        `;
      }
    }
    raceHtml += `</div></div>`;

    // ── Assemble ──────────────────────────────────────────────────
    this.el.innerHTML =
      kpiHtml +
      `<div class="dash-two-col">` +
        `<div>${enclosHtml}</div>` +
        raceHtml +
      `</div>`;

    this.bindEvents();
  }

  private bindEvents(): void {
    if (!this.el) return;

    // "Gérer" buttons — navigate with stopPropagation
    this.el.querySelectorAll<HTMLElement>('button[data-enc-id]').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        const id = Number(btn.dataset['encId']);
        if (id) this.uiState.setActiveView(id);
      });
    });

    // Card click (excluding button area)
    this.el.querySelectorAll<HTMLElement>('.dash-enc-card[id^="dash-enc-"]').forEach(card => {
      card.addEventListener('click', (e) => {
        if ((e.target as HTMLElement).closest('button')) return;
        const id = Number(card.id.replace('dash-enc-', ''));
        if (id) this.uiState.setActiveView(id);
      });
    });

    // Reset stats
    this.el.querySelector('#dash-reset-btn')?.addEventListener('click', async () => {
      const ok = await ConfirmModal.show('Réinitialiser les statistiques', 'Toutes les statistiques seront effacées. Continuer ?');
      if (!ok) return;
      const hasSnap = await UndoManager.snapshotCurrent('Reset statistiques');
      this.commandBus.execute({ type: 'reset-stats' });
      Toast.show('success', 'Statistiques réinitialisées.', hasSnap ? { label: 'Annuler', callback: () => UndoManager.undo() } : undefined);
      this.renderAll();
    });
  }

  update(): void {
    if (!this.el) return;
    const now = Date.now();
    if (now - this.lastRenderTime >= 1000) {
      this.lastRenderTime = now;
      this.renderAll();
    }
  }

  destroy(): void {
    this.el?.remove();
    this.el = null;
  }
}
