/**
 * Results and Works Desk — UI aprovada (Spec 032 / Roger 2026-06-28)
 * KPI Overview + tabela operacional + alertas agentic.
 */
const TicketsWorkspace = {
  context: null,
  queueFilter: null,
  priorityFilter: null,
  _pageReady: false,
  _listFingerprint: '',

  async loadContext() {
    const [presence, funnel, summary] = await Promise.all([
      window.DeskLive?.enabled()
        ? api('/v1/live/presence').catch(() => ({ sessions: [] }))
        : Promise.resolve({ sessions: [] }),
      api('/v1/onboard/funnel?window_hours=48').catch(() => ({ active_sessions: [] })),
      api('/v1/desk/summary').catch(() => ({})),
    ]);
    const liveBySession = {};
    for (const s of presence.sessions || []) {
      if (s.session_id) liveBySession[s.session_id] = s;
    }
    const funnelBySession = {};
    for (const s of funnel.active_sessions || []) {
      if (s.session_id) funnelBySession[s.session_id] = s;
    }
    this.context = {
      liveBySession,
      funnelBySession,
      staleHours: summary.onboard_stale_hours ?? 24,
      summary,
    };
    return this.context;
  },

  stripEnrichment(t) {
    const out = { ...t };
    for (const k of Object.keys(out)) {
      if (k.startsWith('_')) delete out[k];
    }
    return out;
  },

  enrichTicket(t) {
    const ctx = this.context || { liveBySession: {}, funnelBySession: {}, staleHours: 24 };
    const sid = (t.session_id || '').trim();
    const funnel = sid ? ctx.funnelBySession[sid] : null;
    const isActive = ['open', 'escalated', 'assisting', 'resolved'].includes(t.status);
    const lastAt = funnel?.last_event_at || t.assisted_at || t.created_at;
    let idleHours = 0;
    if (lastAt) idleHours = (Date.now() - new Date(lastAt).getTime()) / 3600000;
    const ageHours = t.created_at
      ? (Date.now() - new Date(t.created_at).getTime()) / 3600000
      : 0;
    const stale = funnel?.stale || (isActive && idleHours >= ctx.staleHours);
    const sev = Number(t.severity);
    const isWazuh = t.source === 'wazuh' || t.event === 'wazuh.alert';
    let priority = 'info';
    if (sev >= 12 || (isWazuh && isActive && sev >= 10)) priority = 'critical';
    else if (sev >= 10 || t.status === 'escalated') priority = 'high';
    else if (sev >= 7 || stale) priority = 'warn';

    let voScore = 3;
    if (sev >= 12) voScore = 10;
    else if (sev >= 10) voScore = 8;
    else if (sev >= 7) voScore = 6;
    else if (stale) voScore = 5;
    else if (t.status === 'escalated') voScore = 7;
    else if (t.status === 'open') voScore = 4;

    const live = sid ? !!ctx.liveBySession[sid] : false;

    let base = {
      ...t,
      _idleHours: Math.round(idleHours),
      _ageHours: Math.round(ageHours),
      _stale: stale && isActive,
      _live: live,
      _lastEventAt: funnel?.last_event_at || null,
      _unassigned: isActive && !t.assigned_to && !t.assisted_by,
      _wazuh: isWazuh,
      _security: isWazuh || (t.subject || '').toLowerCase().includes('security'),
      _priority: priority,
      _voScore: voScore,
      _stageLabel: typeof FUNNEL_LABELS !== 'undefined'
        ? (FUNNEL_LABELS[funnel?.current_stage] || funnel?.current_stage || '')
        : '',
    };
    if (window.TicketsSla?.computePriority) {
      base = TicketsSla.computePriority(base);
    }
    return base;
  },

  formatMetric(val) {
    if (val === '—' || val == null || val === '') return '—';
    const n = parseFloat(val);
    return Number.isFinite(n) ? `${n.toFixed(1)}h` : String(val);
  },

  processTickets(tickets) {
    const enriched = tickets.map((t) => this.enrichTicket(this.stripEnrichment(t)));
    if (window.TicketsSla?.processList) return TicketsSla.processList(enriched);
    return enriched.sort((a, b) => (b._priorityScore || b._voScore || 0) - (a._priorityScore || a._voScore || 0));
  },

  computeMetrics(tickets) {
    const enriched = this.processTickets(tickets);
    let overview = null;
    if (window.TicketsSla?.computeOverview) {
      overview = TicketsSla.computeOverview(enriched);
    }
    const priorities = overview?.buckets || { critical: 0, high: 0, warn: 0, info: 0 };
    const mttrNum = overview ? (overview.mttr === '—' ? 0 : parseFloat(overview.mttr) || 0) : 0;
    const respNum = overview ? (overview.avgResponse === '—' ? 0 : parseFloat(overview.avgResponse) || 0) : 0;
    if (!overview) {
      for (const t of enriched) priorities[t._priorityBand || t._priority] = (priorities[t._priorityBand || t._priority] || 0) + 1;
    }
    return {
      enriched,
      slaPct: overview?.slaPct ?? 0,
      mttr: overview?.mttr ?? '0',
      resp: overview?.avgResponse ?? '0',
      mttrNum,
      respNum,
      priorities,
      criticalWaiting: overview?.criticalWaiting ?? priorities.critical ?? 0,
      maxPriority: Math.max(priorities.critical || 0, priorities.high || 0, priorities.warn || 0, priorities.info || 0, 1),
    };
  },

  gaugeHtml(pct) {
    const p = Math.max(0, Math.min(100, Number(pct) || 0));
    const r = 42;
    const circ = Math.PI * r;
    const filled = ((p / 100) * circ).toFixed(2);
    const uid = `rwdG${Math.random().toString(36).slice(2, 8)}`;
    return `
      <div class="rwd-gauge" role="img" aria-label="SLA ${p}% compliant">
        <svg viewBox="0 0 124 72" class="rwd-gauge__svg">
          <defs>
            <linearGradient id="${uid}" x1="0%" y1="0%" x2="100%" y2="0%">
              <stop offset="0%" stop-color="#1f4d45"/>
              <stop offset="50%" stop-color="#5a8f3c"/>
              <stop offset="100%" stop-color="#c9a227"/>
            </linearGradient>
          </defs>
          <path class="rwd-gauge__track" d="M 20 60 A 42 42 0 0 1 104 60" fill="none" stroke="#d8d2c8" stroke-width="11" stroke-linecap="round"/>
          ${p > 0 ? `<path class="rwd-gauge__fill" d="M 20 60 A 42 42 0 0 1 104 60" fill="none" stroke="url(#${uid})" stroke-width="11" stroke-linecap="round"
            stroke-dasharray="${filled} ${circ.toFixed(2)}" pathLength="${circ.toFixed(2)}"/>` : ''}
          <circle cx="20" cy="60" r="5" fill="#1f4d45"/>
          <circle cx="104" cy="60" r="5" fill="#c9a227"/>
        </svg>
        <span class="rwd-gauge__pct">${p}%</span>
      </div>`;
  },

  priorityBarsHtml(priorities, max) {
    const items = [
      { key: 'critical', label: 'Critical', count: priorities.critical || 0 },
      { key: 'high', label: 'High', count: priorities.high || 0 },
      { key: 'warn', label: 'Warn', count: priorities.warn || 0 },
      { key: 'info', label: 'Info', count: priorities.info || 0 },
    ];
    const maxVal = Math.max(15, max, ...items.map((i) => i.count), 1);
    return `
      <div class="rwd-vbars" role="img" aria-label="Tickets by priority">
        ${items.map((it) => {
          const h = it.count > 0 ? Math.max(16, Math.round((it.count / maxVal) * 100)) : 8;
          return `
          <div class="rwd-vbars__col">
            <span class="rwd-vbars__count">${it.count}</span>
            <div class="rwd-vbars__track">
              <div class="rwd-vbars__bar rwd-vbars__bar--${it.key}" style="height:${h}%"></div>
            </div>
            <span class="rwd-vbars__label">${it.label}</span>
          </div>`;
        }).join('')}
      </div>`;
  },

  kpiOverviewHtml(m) {
    return `
      <section class="rwd-kpi-section" aria-label="KPI Overview">
        <h3 class="rwd-kpi-section__title">KPI Overview</h3>
        <div class="rwd-kpi-grid">
          <article class="rwd-kpi-card rwd-kpi-card--gauge">
            <span class="rwd-kpi-card__label">% SLA Compliant (General)</span>
            <div class="rwd-kpi-card__body rwd-kpi-card__body--gauge">
              ${this.gaugeHtml(m.slaPct)}
            </div>
          </article>
          <article class="rwd-kpi-card rwd-kpi-card--metric">
            <span class="rwd-kpi-card__label">Avg. Resolution Time (MTTR)</span>
            <div class="rwd-kpi-card__body rwd-kpi-card__body--metric">
              <span class="rwd-kpi-card__value">${this.formatMetric(m.mttr)}</span>
            </div>
          </article>
          <article class="rwd-kpi-card rwd-kpi-card--metric">
            <span class="rwd-kpi-card__label">Avg. Response Time</span>
            <div class="rwd-kpi-card__body rwd-kpi-card__body--metric">
              <span class="rwd-kpi-card__value">${this.formatMetric(m.resp)}</span>
            </div>
          </article>
          <article class="rwd-kpi-card rwd-kpi-card--bars">
            <span class="rwd-kpi-card__label">Tickets by Priority</span>
            <div class="rwd-kpi-card__body rwd-kpi-card__body--bars">
              ${this.priorityBarsHtml(m.priorities, m.maxPriority)}
            </div>
          </article>
          <article class="rwd-kpi-card rwd-kpi-card--metric">
            <span class="rwd-kpi-card__label">Critical Waiting</span>
            <div class="rwd-kpi-card__body rwd-kpi-card__body--metric">
              <span class="rwd-kpi-card__value rwd-kpi-card__value--danger">${m.criticalWaiting}</span>
            </div>
          </article>
        </div>
      </section>`;
  },

  headerHtml() {
    return `
      <header class="rwd-header">
        <div class="rwd-header__copy">
          <p class="rwd-header__label">Sessão Tickets</p>
          <h2>Results and Works Desk</h2>
          <p class="rwd-header__sub">Operações Ligbox — onboarding, tickets e monitoramento</p>
        </div>
        <div class="rwd-header__actions">
          <button type="button" class="btn btn-ghost btn-sm" id="rwd-filter-toggle">Filter</button>
          <button type="button" class="btn btn-primary btn-sm" id="rwd-refresh">Atualizar</button>
        </div>
      </header>`;
  },

  tenantCell(t) {
    const name = t.domain || t.agent || (t.subject || '').slice(0, 32) || `Ticket #${t.id}`;
    const tags = [
      t._tenant === 'SECURITY' || t._security ? '<span class="rwd-tag rwd-tag--security">SECURITY</span>' : '',
      t._wazuh ? '<span class="rwd-tag rwd-tag--security">WAZUH</span>' : '',
      t._tenant === 'ONBOARD' || t.source === 'vm112-onboard' ? '<span class="rwd-tag rwd-tag--onboard">ONBOARD</span>' : '',
    ].filter(Boolean).join('');
    const resp = t._responseSla || (t.assisted_at ? 'OK' : (t._stale ? 'WARNING' : 'PENDING'));
    const res = t._resolutionSla || (t.status === 'closed' || t.status === 'resolved' ? 'OK' : (t._stale ? 'STALE (4h+)' : 'OPEN'));
    return `
      <div>${tags}<strong>${esc(name)}</strong></div>
      <div class="rwd-sla-line">Resp: ${resp} · Res: ${res}</div>`;
  },

  detailsCell(t) {
    const parts = [];
    if (t.agent) parts.push(esc(t.agent));
    parts.push(`ID: ${t.id}`);
    if (t.severity != null) parts.push(`Wazuh Lvl ${t.severity}`);
    else if (t._stageLabel) parts.push(esc(t._stageLabel));
    else if (t.event) parts.push(esc(String(t.event).replace('onboarding.', '')));
    return `
      <div class="rwd-detail-title">${esc(t.description || t.subject || parts[0] || '—')}</div>
      <div class="rwd-detail-sub">${parts.join(' · ')}</div>`;
  },

  scoreCell(t) {
    const stale = t._stale ? `<span class="rwd-status-pill rwd-status-pill--stale">PARADO ${t._idleHours}H</span>` : '';
    const st = t.status || 'open';
    const live = t._live
      ? '<span class="rwd-status-pill rwd-status-pill--live">LIVE</span>'
      : '<span class="rwd-status-pill rwd-status-pill--off">OFF</span>';
    const score = t._priorityScore ?? t._voScore ?? '—';
    return `
      <div class="rwd-score-col">
        <span class="rwd-status-pill rwd-status-pill--${st}">${esc(statusLabel(st))}</span>
        ${live}
        ${stale}
        <span class="rwd-vo-score" title="Priority Score v0">${score}</span>
        <span class="ticket-meta">V0 SCORE</span>
      </div>`;
  },

  tableHtml(tickets) {
    if (!tickets.length) {
      return '<p class="loading" style="padding:1rem">Nenhum ticket neste filtro</p>';
    }
    const rows = tickets.map((t) => {
      const sel = state.selectedTicketId === t.id ? ' selected' : '';
      return `
        <tr class="rwd-row${sel}" data-id="${t.id}"${t.session_id ? ` data-session="${esc(t.session_id)}"` : ''}>
          <td>${this.scoreCell(t)}</td>
          <td>${this.tenantCell(t)}</td>
          <td>${this.detailsCell(t)}</td>
          <td><span class="${t._idleHours >= 4 ? 'rwd-idle-warn' : ''}">${t._idleHours}h</span><br><span class="ticket-meta">Inativo</span></td>
          <td>${t._ageHours}h<br><span class="ticket-meta">Desde a abertura</span></td>
          <td>${t.assisted_by || t.assigned_to
            ? `<strong>${esc(t.assisted_by || t.assigned_to)}</strong>`
            : '<span class="rwd-agent-empty">Sem atribuição</span><br><span class="ticket-meta">AGENT</span>'}</td>
        </tr>`;
    }).join('');
    return `
      <div class="rwd-table-wrap">
        <table class="rwd-table">
          <thead>
            <tr>
              <th>Priority Score</th>
              <th>Tenant &amp; SLAs</th>
              <th>Details</th>
              <th>Idle (last event)</th>
              <th>Total Age</th>
              <th>Responsável</th>
            </tr>
          </thead>
          <tbody>${rows}</tbody>
        </table>
      </div>`;
  },

  applyFilters(tickets) {
    let list = tickets;
    const qf = state.ticketFilter || this.queueFilter || 'all';
    if (this.priorityFilter) {
      list = list.filter((t) => (t._priorityBand || t._priority) === this.priorityFilter);
    }
    if (qf === 'active') {
      list = list.filter((t) => ['open', 'escalated', 'assisting', 'resolved'].includes(t.status));
    } else if (qf && qf !== 'all') {
      list = list.filter((t) => t.status === qf);
    }
    if (state.sourceFilter && state.sourceFilter !== 'all') {
      list = list.filter((t) => t.source === state.sourceFilter);
    }
    return list;
  },

  async fetchAgenticAlerts() {
    try {
      const data = await api('/v1/agents/findings?open_only=true&limit=6');
      return (data.findings || []).map((f) => ({
        title: f.title || 'Finding',
        sub: `${f.severity || 'warn'} · ${f.category || 'agent'}`,
        id: f.id,
      }));
    } catch {
      return [];
    }
  },

  alertsHtml(items) {
    if (!items.length) return '';
    return `
      <aside class="rwd-alerts" aria-label="Agentic Alerts Active">
        <div class="rwd-alerts__head">Agentic Alerts Active</div>
        <ul class="rwd-alerts__list">
          ${items.map((a) => `
            <li data-goto-agentic="1">
              <strong>${esc(a.title)}</strong>
              <span>${esc(a.sub)} (open)</span>
            </li>`).join('')}
        </ul>
      </aside>`;
  },

  bindTable(root, tickets) {
    root.querySelectorAll('.rwd-row').forEach((row) => {
      row.addEventListener('click', async () => {
        state.selectedTicketId = Number(row.dataset.id);
        state.selectedSessionId = row.dataset.session || null;
        root.querySelectorAll('.rwd-row').forEach((r) => r.classList.remove('selected'));
        row.classList.add('selected');
        if (window.TicketsDetailPanel?.openDrawer) {
          await TicketsDetailPanel.openDrawer(state.selectedTicketId);
        } else if (typeof renderTicketDetail === 'function') {
          await renderTicketDetail();
        }
      });
    });
  },

  bindPage(root) {
    root.querySelector('#rwd-refresh')?.addEventListener('click', () => {
      this._pageReady = false;
      if (typeof refresh === 'function') refresh();
    });
    root.querySelector('#rwd-filter-toggle')?.addEventListener('click', () => {
      document.getElementById('view-tickets')?.classList.toggle('rwd-filters-open');
    });
    root.querySelector('[data-goto-agentic]')?.addEventListener('click', () => setView('agentic-ops'));
    root.querySelectorAll('[data-goto-agentic]').forEach((el) => {
      el.addEventListener('click', () => setView('agentic-ops'));
    });
  },

  syncPageTitle() {
    document.querySelector('.main')?.classList.add('main--rwd-tickets');
  },

  listFingerprint(tickets) {
    return tickets.map((t) => [t.id, t.status, t._idleHours, t._priority].join(':')).join('|');
  },

  renderShell(metrics, filtered, alerts) {
    return `
      <div class="rwd-page">
        ${this.headerHtml()}
        ${this.kpiOverviewHtml(metrics)}
        ${this.tableHtml(filtered)}
        ${this.alertsHtml(alerts)}
      </div>`;
  },

  mountRoot() {
    let root = document.getElementById('tickets-rwd-root');
    if (!root) {
      const view = document.getElementById('view-tickets');
      if (!view) return null;
      root = document.createElement('div');
      root.id = 'tickets-rwd-root';
      view.insertBefore(root, view.firstChild);
    }
    return root;
  },

  async renderListOnly() {
    const root = document.getElementById('tickets-rwd-root');
    if (!root || !state.tickets?.length) return;
    const metrics = this.computeMetrics(state.tickets.map((t) => this.stripEnrichment(t)));
    state.tickets = metrics.enriched;
    const filtered = this.applyFilters(metrics.enriched);
    const fp = this.listFingerprint(filtered);
    if (fp === this._listFingerprint && root.querySelector('.rwd-table')) return;
    this._listFingerprint = fp;
    const alerts = await this.fetchAgenticAlerts();
    root.innerHTML = this.renderShell({ ...metrics, enriched: metrics.enriched }, filtered, alerts);
    this.bindTable(root, filtered);
    this.bindPage(root);
  },

  async softRefresh() {
    if (!this._pageReady || state.view !== 'tickets') return;
    try {
      await this.loadContext();
      await this.renderListOnly();
    } catch { /* poll */ }
  },

  async renderPage({ listEl, detailEl, tickets }) {
    this.syncPageTitle();
    await this.loadContext();
    const metrics = this.computeMetrics(tickets);
    state.tickets = metrics.enriched;
    const filtered = this.applyFilters(metrics.enriched);
    this._listFingerprint = this.listFingerprint(filtered);
    const alerts = await this.fetchAgenticAlerts();
    const root = this.mountRoot();
    if (!root) return;
    root.innerHTML = this.renderShell(metrics, filtered, alerts);
    this.bindTable(root, filtered);
    this.bindPage(root);
    this._pageReady = true;

    if (listEl) listEl.innerHTML = '';
    if (detailEl && !state.selectedTicketId) {
      detailEl.innerHTML = '';
    }
  },
};

window.TicketsWorkspace = TicketsWorkspace;
