/**
 * Admin Providers Dashboard - Provider Performance Analysis
 * Admin-only: provider comparison, success rates, volume analysis, failed transaction breakdown
 */
const { buildHeader, buildFooter, buildHead, getChartJsScript } = require('./ui-template');

function buildAdminProvidersHTML(user) {
  const role = user.role || 'admin';
  const pageScripts = getChartJsScript();

  const now = new Date();
  const today = now.toISOString().slice(0, 10);
  const thirtyDaysAgo = new Date(now.getTime() - 30 * 86400000).toISOString().slice(0, 10);

  const pageCSS = `
  /* Smooth scroll for anchor navigation */
  html { scroll-behavior: smooth; scroll-padding-top: 20px; }

  /* === TRADING CONSOLE: Light Mode (professional clean) === */
  body.trading-console {
    --tc-accent: #1E8E3E;
    --tc-accent-bg: rgba(30,142,62,0.08);
    --tc-accent-border: rgba(30,142,62,0.15);
    --tc-glass: rgba(255,255,255,0.85);
    --tc-grid: rgba(0,0,0,0.06);
    background: var(--bg);
    color: var(--text);
  }

  /* === TRADING CONSOLE: Dark Mode (Bloomberg terminal) === */
  [data-theme="dark"] body.trading-console {
    --bg: #0D1117;
    --card: #131A24;
    --text: #E2E8F0;
    --text-secondary: #94A3B8;
    --text-muted: #64748B;
    --border: rgba(0,255,136,0.1);
    --green: #00FF88;
    --green-bg: rgba(0,255,136,0.08);
    --blue: #58A6FF;
    --blue-bg: rgba(88,166,255,0.08);
    --orange: #F0883E;
    --orange-bg: rgba(240,136,62,0.08);
    --red: #FF4444;
    --red-bg: rgba(255,68,68,0.08);
    --purple: #BC8CFF;
    --purple-bg: rgba(188,140,255,0.08);
    --admin-accent: #00FF88;
    --admin-bg: rgba(0,255,136,0.05);
    --tc-accent: #00FF88;
    --tc-accent-bg: rgba(0,255,136,0.08);
    --tc-accent-border: rgba(0,255,136,0.15);
    --tc-glass: rgba(15,25,35,0.92);
    --tc-grid: rgba(0,255,136,0.06);
    background: #0A0F18 !important;
    color: var(--text);
    color-scheme: dark;
  }

  /* Console Cards - Light */
  body.trading-console .hero-card,
  body.trading-console .chart-card,
  body.trading-console .metric-card,
  body.trading-console .filter-bar {
    background: var(--card);
    border: 1px solid var(--border);
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  }
  /* Console Cards - Dark */
  [data-theme="dark"] body.trading-console .hero-card,
  [data-theme="dark"] body.trading-console .chart-card,
  [data-theme="dark"] body.trading-console .metric-card,
  [data-theme="dark"] body.trading-console .filter-bar {
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(0,255,136,0.1);
    box-shadow: 0 2px 12px rgba(0,0,0,0.3), inset 0 1px 0 rgba(0,255,136,0.05);
  }

  /* Console Values - Light: clean professional */
  body.trading-console .hero-value {
    font-variant-numeric: tabular-nums;
  }
  /* Console Values - Dark: monospace terminal */
  [data-theme="dark"] body.trading-console .hero-value {
    font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
    text-shadow: 0 0 8px rgba(226,232,240,0.15);
  }

  /* Console Section Titles - Light */
  body.trading-console .section-title {
    color: var(--text-secondary);
    letter-spacing: 1px;
  }
  body.trading-console .section-title .icon {
    background: var(--tc-accent-bg) !important;
    color: var(--tc-accent) !important;
  }
  /* Console Section Titles - Dark */
  [data-theme="dark"] body.trading-console .section-title {
    color: rgba(0,255,136,0.7);
    font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
    letter-spacing: 2px;
  }
  [data-theme="dark"] body.trading-console .section-title .icon {
    background: rgba(0,255,136,0.08) !important;
    color: #00FF88 !important;
  }

  /* Console Tables - Light */
  body.trading-console .data-table th {
    background: var(--bg);
    color: var(--text-muted);
  }
  /* Console Tables - Dark */
  [data-theme="dark"] body.trading-console .data-table th {
    background: rgba(0,255,136,0.03);
    color: rgba(0,255,136,0.6);
    font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
  }
  [data-theme="dark"] body.trading-console .data-table td {
    font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
    font-size: 12px;
    border-bottom-color: rgba(0,255,136,0.06);
  }
  [data-theme="dark"] body.trading-console .data-table tr:hover td {
    background: rgba(0,255,136,0.05);
  }

  /* Console Buttons - Dark only overrides */
  [data-theme="dark"] body.trading-console .preset-btn {
    background: rgba(255,255,255,0.03);
    color: var(--text-secondary);
    border-color: rgba(0,255,136,0.1);
  }
  [data-theme="dark"] body.trading-console .preset-btn:hover {
    border-color: #00FF88; color: #00FF88;
  }
  [data-theme="dark"] body.trading-console .preset-btn.active {
    background: rgba(0,255,136,0.15);
    color: #00FF88; border-color: rgba(0,255,136,0.3);
  }
  [data-theme="dark"] body.trading-console .date-inputs input[type="date"] {
    background: rgba(255,255,255,0.03);
    color: var(--text); border-color: rgba(0,255,136,0.1);
  }

  /* Console Loading - Dark */
  [data-theme="dark"] body.trading-console .loading-overlay { background: rgba(10,15,24,0.85); }

  /* Console Footer - Dark */
  [data-theme="dark"] body.trading-console .app-footer {
    background: #0A0F18; border-top-color: rgba(0,255,136,0.1); color: var(--text-muted);
  }

  /* Console Scrollbars - Dark */
  [data-theme="dark"] body.trading-console ::-webkit-scrollbar { width: 6px; height: 6px; }
  [data-theme="dark"] body.trading-console ::-webkit-scrollbar-track { background: rgba(0,0,0,0.2); }
  [data-theme="dark"] body.trading-console ::-webkit-scrollbar-thumb { background: rgba(0,255,136,0.2); border-radius: 3px; }
  [data-theme="dark"] body.trading-console ::-webkit-scrollbar-thumb:hover { background: rgba(0,255,136,0.35); }

  /* Filter Bar */
  .filter-bar {
    background: var(--card); border-radius: 16px; padding: 20px 24px;
    border: 1px solid var(--border); box-shadow: 0 2px 8px rgba(0,0,0,0.04);
    margin-bottom: 24px; display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  }
  .filter-bar-label { font-size: 13px; font-weight: 600; color: var(--text-secondary); }
  .filter-presets { display: flex; gap: 8px; }
  .preset-btn {
    padding: 8px 16px; border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg); font-size: 13px; font-weight: 600; cursor: pointer;
    color: var(--text-secondary); transition: all 0.15s; font-family: inherit;
  }
  .preset-btn:hover { border-color: var(--admin-accent); color: var(--admin-accent); }
  .preset-btn.active {
    background: var(--admin-accent); color: white; border-color: var(--admin-accent);
  }
  .filter-divider { width: 1px; height: 32px; background: var(--border); }
  .date-inputs { display: flex; align-items: center; gap: 8px; }
  .date-inputs label { font-size: 12px; font-weight: 600; color: var(--text-muted); }
  .date-inputs input[type="date"] {
    padding: 8px 12px; border: 1px solid var(--border); border-radius: 8px;
    font-size: 13px; font-family: inherit; background: var(--bg); color: var(--text);
  }
  .period-info {
    margin-left: auto; font-size: 12px; color: var(--text-muted);
    font-weight: 500; background: var(--bg); padding: 6px 12px; border-radius: 6px;
  }

  /* Export Button */
  .btn-export {
    padding: 8px 18px; border: 1px solid var(--border); border-radius: 8px;
    background: var(--bg); font-size: 13px; font-weight: 600; cursor: pointer;
    color: var(--text-secondary); transition: all 0.15s; font-family: inherit;
    display: inline-flex; align-items: center; gap: 6px;
  }
  .btn-export:hover { border-color: var(--admin-accent); color: var(--admin-accent); }
  [data-theme="dark"] body.trading-console .btn-export {
    background: rgba(255,255,255,0.03);
    color: var(--text-secondary);
    border-color: rgba(0,255,136,0.1);
  }
  [data-theme="dark"] body.trading-console .btn-export:hover {
    border-color: #00FF88; color: #00FF88;
  }

  /* Hero KPI Cards */
  .hero-grid {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 28px;
  }
  .hero-card {
    background: var(--card); border-radius: 16px; padding: 20px 18px;
    border: 1px solid var(--border); box-shadow: 0 2px 8px rgba(0,0,0,0.04);
    position: relative; overflow: hidden;
    min-width: 0;
  }
  .hero-card::before {
    content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  }
  .hero-card.providers-count::before { background: linear-gradient(90deg, var(--purple), #AB47BC); }
  .hero-card.success-rate::before { background: linear-gradient(90deg, var(--green), #4CAF50); }
  .hero-card.total-volume::before { background: linear-gradient(90deg, var(--blue), #42A5F5); }
  .hero-card.settlement::before { background: linear-gradient(90deg, var(--orange), #FFA726); }
  .hero-label {
    font-size: 11px; font-weight: 700; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px;
  }
  .hero-value {
    font-size: clamp(14px, 1.6vw, 26px); font-weight: 800; color: var(--text); margin-bottom: 4px;
    font-variant-numeric: tabular-nums;
    word-break: break-word; overflow-wrap: break-word;
    min-width: 0; line-height: 1.2;
  }
  .hero-sub { font-size: 12px; color: var(--text-muted); margin-top: 6px; }

  /* Section Headers */
  .section-title {
    font-size: 14px; font-weight: 700; color: var(--text-secondary);
    text-transform: uppercase; letter-spacing: 1px; margin-bottom: 16px;
    display: flex; align-items: center; gap: 8px;
  }
  .section-title .icon {
    width: 28px; height: 28px; border-radius: 8px; display: flex;
    align-items: center; justify-content: center; font-size: 14px;
  }

  /* Charts Grid */
  .charts-row {
    display: grid; grid-template-columns: 1fr 2fr; gap: 20px; margin-bottom: 28px;
  }
  .charts-row.equal { grid-template-columns: 1fr 1fr; }
  .charts-row.triple { grid-template-columns: 1fr 1fr 1fr; }
  .chart-card {
    background: var(--card); border-radius: 16px; padding: 24px;
    border: 1px solid var(--border); box-shadow: 0 2px 8px rgba(0,0,0,0.04);
  }
  .chart-card h3 {
    font-size: 14px; font-weight: 700; color: var(--text); margin-bottom: 16px;
    display: flex; align-items: center; gap: 8px;
  }
  .chart-card h3 .badge {
    font-size: 10px; padding: 3px 8px; border-radius: 10px;
    font-weight: 700; background: var(--bg); color: var(--text-muted);
  }
  .chart-wrap { position: relative; height: 280px; }
  .chart-wrap.short { height: 220px; }

  /* Data Tables */
  .data-table {
    width: 100%; border-collapse: collapse; font-size: 13px;
  }
  .data-table th {
    text-align: left; padding: 10px 12px; font-weight: 700; font-size: 11px;
    text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted);
    border-bottom: 2px solid var(--border);
    cursor: pointer; user-select: none; white-space: nowrap;
  }
  .data-table th:hover { color: var(--tc-accent); }
  .data-table th .sort-arrow { font-size: 9px; margin-left: 4px; opacity: 0.5; }
  .data-table th.sorted .sort-arrow { opacity: 1; }
  .data-table td {
    padding: 10px 12px; border-bottom: 1px solid var(--border);
    color: var(--text); font-variant-numeric: tabular-nums;
  }
  .data-table tr:last-child td { border-bottom: none; }
  .data-table tr:hover td { background: var(--bg); }

  /* Status badges */
  .status-badge {
    display: inline-block; font-size: 11px; font-weight: 700; padding: 3px 10px;
    border-radius: 12px;
  }
  .status-badge.good { background: var(--green-bg); color: var(--green); }
  .status-badge.warning { background: var(--orange-bg); color: var(--orange); }
  .status-badge.bad { background: var(--red-bg); color: var(--red); }

  /* Loading */
  .loading-overlay {
    position: absolute; inset: 0; background: rgba(255,255,255,0.8);
    display: flex; align-items: center; justify-content: center;
    border-radius: 16px; z-index: 10; font-size: 13px; color: var(--text-muted);
  }

  /* Responsive - Small Desktop */
  @media (max-width: 1200px) {
    .hero-grid { grid-template-columns: repeat(2, 1fr); }
    .hero-value { font-size: clamp(15px, 2.4vw, 22px); }
    .charts-row.triple { grid-template-columns: 1fr 1fr; }
    .charts-row.triple > :last-child { grid-column: span 2; }
  }

  /* Responsive - Tablet */
  @media (max-width: 900px) {
    .charts-row { grid-template-columns: 1fr; }
    .charts-row.equal { grid-template-columns: 1fr; }
    .charts-row.triple { grid-template-columns: 1fr; }
    .charts-row.triple > :last-child { grid-column: span 1; }
    .filter-divider { display: none; }
    .filter-bar { gap: 10px; }
  }

  /* Responsive - Mobile */
  @media (max-width: 768px) {
    /* Filter bar - stack vertically */
    .filter-bar {
      padding: 14px 16px; gap: 10px;
      flex-direction: column; align-items: stretch;
    }
    .filter-bar-label { text-align: center; }
    .filter-presets { flex-wrap: wrap; justify-content: center; }
    .preset-btn { padding: 10px 14px; min-height: 44px; font-size: 13px; flex: 1; min-width: 70px; text-align: center; }
    .date-inputs {
      flex-wrap: wrap; justify-content: center; gap: 6px;
    }
    .date-inputs input[type="date"] { flex: 1; min-width: 130px; min-height: 44px; }
    .period-info { margin-left: 0; width: 100%; text-align: center; }

    /* Hero KPIs */
    .hero-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
    .hero-card { padding: 16px 18px; border-radius: 12px; }
    .hero-value { font-size: 22px; }
    .hero-label { font-size: 10px; }
    .hero-sub { font-size: 11px; }

    /* Charts - single column */
    .charts-row, .charts-row.equal, .charts-row.triple { grid-template-columns: 1fr; }
    .chart-card { padding: 18px; border-radius: 12px; }
    .chart-wrap { height: 250px; }

    /* Tables - horizontal scroll */
    .chart-card:has(.data-table) { padding: 18px 0; }
    .chart-card:has(.data-table) > h3 { padding: 0 18px; }
    .data-table { font-size: 12px; }
    .data-table th { padding: 10px 10px; font-size: 10px; white-space: nowrap; }
    .data-table td { padding: 10px 10px; white-space: nowrap; }
    [style*="overflow-x:auto"], [style*="overflow:auto"] {
      -webkit-overflow-scrolling: touch;
      scrollbar-width: thin;
    }

    /* Section titles */
    .section-title { font-size: 13px; margin-bottom: 12px; }
  }

  /* Responsive - Small Mobile */
  @media (max-width: 480px) {
    /* Filter compact */
    .filter-bar { padding: 12px; }
    .preset-btn { padding: 8px 10px; font-size: 12px; min-height: 40px; }
    .date-inputs input[type="date"] { font-size: 12px; padding: 8px 10px; min-height: 40px; }

    /* Hero - single column */
    .hero-grid { grid-template-columns: 1fr; gap: 10px; }
    .hero-card { padding: 14px 16px; }
    .hero-value { font-size: 20px; }

    /* Charts compact */
    .chart-card { padding: 14px; }
    .chart-wrap { height: 200px; }
    .chart-wrap.short { height: 160px; }
    .chart-card h3 { font-size: 13px; }

    /* Tables even more compact */
    .data-table { font-size: 11px; }
    .data-table th { padding: 8px 6px; font-size: 9px; }
    .data-table td { padding: 8px 6px; }

    /* Section titles */
    .section-title { font-size: 12px; letter-spacing: 0.5px; }
    .section-title .icon { width: 24px; height: 24px; font-size: 12px; }
  }

  /* Dark Mode overrides */
  [data-theme="dark"] .loading-overlay { background: rgba(13,17,23,0.85); }
  [data-theme="dark"] .preset-btn { background: var(--card); color: var(--text-secondary); border-color: var(--border); }
  [data-theme="dark"] .preset-btn:hover { border-color: var(--admin-accent); color: var(--green); }
  [data-theme="dark"] .date-inputs input[type="date"] { background: var(--card); color: var(--text); border-color: var(--border); }
  [data-theme="dark"] .data-table tr:hover td { background: rgba(255,255,255,0.03); }
  `;

  return `<!DOCTYPE html>
<html lang="pt-BR">
<head>
${buildHead('Provider Performance', pageCSS, pageScripts)}
</head>
<body class="trading-console">

${buildHeader({ role: role, userName: user.nome, activePage: 'providers', permissions: user.permissions || [] })}

<div class="app-container">

  <!-- Filter Bar -->
  <div class="filter-bar" id="filterBar">
    <span class="filter-bar-label">Periodo:</span>
    <div class="filter-presets">
      <button class="preset-btn" data-preset="7d">7 Dias</button>
      <button class="preset-btn active" data-preset="30d">30 Dias</button>
      <button class="preset-btn" data-preset="90d">90 Dias</button>
      <button class="preset-btn" data-preset="mtd">Este Mes</button>
      <button class="preset-btn" data-preset="ytd">Este Ano</button>
    </div>
    <div class="filter-divider"></div>
    <div class="date-inputs">
      <label>De:</label>
      <input type="date" id="dateStart" value="${thirtyDaysAgo}">
      <label>Ate:</label>
      <input type="date" id="dateEnd" value="${today}">
    </div>
    <button class="btn-export" id="btnExport" title="Exportar para Excel">
      &#x1F4E5; Export Excel
    </button>
    <span class="period-info" id="periodInfo">Carregando...</span>
  </div>

  <!-- Hero KPI Cards -->
  <div class="hero-grid" id="heroGrid">
    <div class="hero-card providers-count">
      <div class="hero-label">Total Providers</div>
      <div class="hero-value" id="kpiProviders">--</div>
      <div class="hero-sub">provedores ativos</div>
    </div>
    <div class="hero-card success-rate">
      <div class="hero-label">Success Rate</div>
      <div class="hero-value" id="kpiSuccessRate">--</div>
      <div class="hero-sub">taxa geral de sucesso</div>
    </div>
    <div class="hero-card total-volume">
      <div class="hero-label">Volume Total</div>
      <div class="hero-value" id="kpiVolume">--</div>
      <div class="hero-sub">USD processado no periodo</div>
    </div>
    <div class="hero-card settlement">
      <div class="hero-label">Avg Settlement</div>
      <div class="hero-value" id="kpiSettlement">--</div>
      <div class="hero-sub">tempo medio de liquidacao</div>
    </div>
  </div>

  <!-- Section: Provider Comparison Table -->
  <div class="section-title" id="sectionTable">
    <span class="icon">&#x1F3E6;</span>
    Provider Comparison
  </div>
  <div class="chart-card" style="margin-bottom:28px;">
    <h3>Performance por Provider <span class="badge" id="providerCount">--</span></h3>
    <div style="overflow-x:auto;-webkit-overflow-scrolling:touch;">
      <table class="data-table" id="providerTable">
        <thead>
          <tr>
            <th data-sort="provider">Provider <span class="sort-arrow">&#x25B2;</span></th>
            <th data-sort="flow">Flow <span class="sort-arrow">&#x25B2;</span></th>
            <th data-sort="total_tx">Tx Total <span class="sort-arrow">&#x25B2;</span></th>
            <th data-sort="success_rate">Success Rate <span class="sort-arrow">&#x25B2;</span></th>
            <th data-sort="vol_usd">Volume USD <span class="sort-arrow">&#x25B2;</span></th>
            <th data-sort="avg_ticket">Avg Ticket <span class="sort-arrow">&#x25B2;</span></th>
            <th data-sort="avg_spread_pct">Spread % <span class="sort-arrow">&#x25B2;</span></th>
            <th data-sort="avg_settlement_hours">Settlement (h) <span class="sort-arrow">&#x25B2;</span></th>
          </tr>
        </thead>
        <tbody id="providerTableBody">
          <tr><td colspan="8" style="text-align:center;color:var(--text-muted);">Carregando...</td></tr>
        </tbody>
      </table>
    </div>
  </div>

  <!-- Section: Failed Transactions -->
  <div class="section-title" id="sectionFailed">
    <span class="icon">&#x26A0;</span>
    Failed Transactions Breakdown
  </div>
  <div class="charts-row equal" style="margin-bottom:28px;">
    <div class="chart-card">
      <h3>By Provider <span class="badge" id="failedTotal">--</span></h3>
      <div style="overflow-x:auto;-webkit-overflow-scrolling:touch;">
        <table class="data-table" id="failedByProviderTable">
          <thead>
            <tr><th>Provider</th><th>Failed Tx</th><th>Volume Lost</th><th>Failure Rate</th></tr>
          </thead>
          <tbody id="failedByProviderBody">
            <tr><td colspan="4" style="text-align:center;color:var(--text-muted);">Carregando...</td></tr>
          </tbody>
        </table>
      </div>
    </div>
    <div class="chart-card">
      <h3>By Status</h3>
      <div style="overflow-x:auto;-webkit-overflow-scrolling:touch;">
        <table class="data-table" id="failedByStatusTable">
          <thead>
            <tr><th>Status</th><th>Count</th><th>Volume</th></tr>
          </thead>
          <tbody id="failedByStatusBody">
            <tr><td colspan="3" style="text-align:center;color:var(--text-muted);">Carregando...</td></tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>

  <!-- Section: Charts -->
  <div class="section-title" id="sectionCharts">
    <span class="icon">&#x1F4CA;</span>
    Provider Analytics
  </div>
  <div class="charts-row equal">
    <div class="chart-card">
      <h3>Volume por Provider</h3>
      <div class="chart-wrap"><canvas id="chartVolume"></canvas></div>
    </div>
    <div class="chart-card">
      <h3>Success Rate por Provider</h3>
      <div class="chart-wrap"><canvas id="chartSuccess"></canvas></div>
    </div>
  </div>
  <div class="chart-card" style="margin-bottom:28px;">
    <h3>Volume Trend por Provider <span class="badge">diario</span></h3>
    <div class="chart-wrap"><canvas id="chartTrend"></canvas></div>
  </div>

</div>

${buildFooter()}

<script>
// Global error handler
window.onerror = function(msg, url, line, col, err) {
  var d = document.createElement('div');
  d.style.cssText = 'position:fixed;top:0;left:0;right:0;padding:12px 16px;background:#FF4444;color:white;font-size:13px;z-index:99999;font-family:monospace;word-break:break-all;';
  d.textContent = 'JS ERROR: ' + msg + ' (line ' + line + ')';
  document.body.appendChild(d);
};
<\/script>

<script>
// === Formatters ===
var fmtUSD = function(v) { return '$' + Number(v||0).toLocaleString('en-US', {minimumFractionDigits:0, maximumFractionDigits:0}); };
var fmtNum = function(v) { return Number(v||0).toLocaleString('pt-BR'); };
var fmtPct = function(v) { return Number(v||0).toFixed(1) + '%'; };
var fmtHrs = function(v) { return Number(v||0).toFixed(1) + 'h'; };

// === Date & Filter Logic ===
var currentStart = '${thirtyDaysAgo}';
var currentEnd = '${today}';

function setPreset(preset) {
  var now = new Date();
  var today = now.toISOString().slice(0, 10);
  var start;
  switch(preset) {
    case '7d':
      start = new Date(now.getTime() - 7 * 86400000).toISOString().slice(0, 10); break;
    case '30d':
      start = new Date(now.getTime() - 30 * 86400000).toISOString().slice(0, 10); break;
    case '90d':
      start = new Date(now.getTime() - 90 * 86400000).toISOString().slice(0, 10); break;
    case 'mtd':
      start = new Date(now.getFullYear(), now.getMonth(), 1).toISOString().slice(0, 10); break;
    case 'ytd':
      start = new Date(now.getFullYear(), 0, 1).toISOString().slice(0, 10); break;
    default:
      start = new Date(now.getTime() - 30 * 86400000).toISOString().slice(0, 10);
  }
  document.getElementById('dateStart').value = start;
  document.getElementById('dateEnd').value = today;
  document.querySelectorAll('.filter-presets .preset-btn').forEach(function(b) { b.classList.remove('active'); });
  var activeBtn = document.querySelector('[data-preset="'+preset+'"]');
  if (activeBtn) activeBtn.classList.add('active');
  currentStart = start; currentEnd = today;
  loadAll();
}

function loadAll() {
  loadProviders();
  loadFailed();
  loadTrend();
}

document.querySelectorAll('.filter-presets .preset-btn').forEach(function(btn) {
  btn.addEventListener('click', function() { setPreset(btn.dataset.preset); });
});
document.getElementById('dateStart').addEventListener('change', function() {
  currentStart = document.getElementById('dateStart').value;
  document.querySelectorAll('.filter-presets .preset-btn').forEach(function(b) { b.classList.remove('active'); });
  loadAll();
});
document.getElementById('dateEnd').addEventListener('change', function() {
  currentEnd = document.getElementById('dateEnd').value;
  document.querySelectorAll('.filter-presets .preset-btn').forEach(function(b) { b.classList.remove('active'); });
  loadAll();
});

// === Theme-aware Chart.js ===
function getChartTheme() {
  var isDark = document.documentElement.getAttribute('data-theme') === 'dark';
  return {
    text: isDark ? '#E2E8F0' : '#1A1D23',
    grid: isDark ? 'rgba(0,255,136,0.08)' : 'rgba(0,0,0,0.06)',
    green: isDark ? '#00FF88' : '#1E8E3E',
    blue: isDark ? '#58A6FF' : '#1A73E8',
    orange: isDark ? '#F0883E' : '#E8710A',
    red: isDark ? '#FF4444' : '#D93025',
    purple: isDark ? '#BC8CFF' : '#7B1FA2',
    bg: isDark ? '#131A24' : '#FFFFFF',
    tooltipBg: isDark ? '#1A2332' : '#FFFFFF',
    tooltipTitle: isDark ? '#E2E8F0' : '#1A1D23',
    tooltipBody: isDark ? '#94A3B8' : '#5F6368',
    tooltipBorder: isDark ? 'rgba(0,255,136,0.15)' : 'rgba(0,0,0,0.1)',
    palette: isDark
      ? ['#00FF88','#58A6FF','#BC8CFF','#F0883E','#FF4444','#F9A825','#00BFA5','#FF6B9D','#7C8CFF','#A1887F']
      : ['#1E8E3E','#1A73E8','#7B1FA2','#E8710A','#D93025','#F57C00','#00897B','#D81B60','#3F51B5','#6D4C41']
  };
}

function applyChartDefaults(t) {
  if (typeof Chart === 'undefined') return;
  Chart.defaults.color = t.text;
  Chart.defaults.borderColor = t.grid;
  Chart.defaults.plugins.legend.labels.color = t.text;
  Chart.defaults.plugins.tooltip.backgroundColor = t.tooltipBg;
  Chart.defaults.plugins.tooltip.titleColor = t.tooltipTitle;
  Chart.defaults.plugins.tooltip.bodyColor = t.tooltipBody;
  Chart.defaults.plugins.tooltip.borderColor = t.tooltipBorder;
  Chart.defaults.plugins.tooltip.borderWidth = 1;
}

// === Chart instances ===
var chartVolume, chartSuccess, chartTrend;

// === Cached data for theme re-render ===
var _providerData = null;
var _trendData = null;

// Sort state
var _sortCol = 'vol_usd';
var _sortAsc = false;

function destroyCharts() {
  [chartVolume, chartSuccess, chartTrend].forEach(function(c) { if (c) c.destroy(); });
  chartVolume = null; chartSuccess = null; chartTrend = null;
}

// === Sortable Table Logic ===
function sortProviderData(data, col, asc) {
  return data.slice().sort(function(a, b) {
    var va = a[col], vb = b[col];
    if (typeof va === 'string') {
      va = va.toLowerCase(); vb = (vb || '').toLowerCase();
      return asc ? va.localeCompare(vb) : vb.localeCompare(va);
    }
    va = Number(va) || 0; vb = Number(vb) || 0;
    return asc ? va - vb : vb - va;
  });
}

function renderProviderTable(providers) {
  var sorted = sortProviderData(providers, _sortCol, _sortAsc);
  var tbody = document.getElementById('providerTableBody');
  if (!sorted.length) {
    tbody.innerHTML = '<tr><td colspan="8" style="text-align:center;color:var(--text-muted);">Nenhum dado encontrado</td></tr>';
    return;
  }
  tbody.innerHTML = sorted.map(function(p) {
    var rateClass = p.success_rate >= 95 ? 'good' : p.success_rate >= 80 ? 'warning' : 'bad';
    return '<tr>'
      + '<td style="font-weight:700;">' + (p.provider || 'N/A') + '</td>'
      + '<td>' + (p.flow || '--') + '</td>'
      + '<td>' + fmtNum(p.total_tx) + '</td>'
      + '<td><span class="status-badge ' + rateClass + '">' + fmtPct(p.success_rate) + '</span></td>'
      + '<td>' + fmtUSD(p.vol_usd) + '</td>'
      + '<td>' + fmtUSD(p.avg_ticket) + '</td>'
      + '<td>' + (Number(p.avg_spread_pct)||0).toFixed(2) + '%</td>'
      + '<td>' + fmtHrs(p.avg_settlement_hours) + '</td>'
      + '</tr>';
  }).join('');

  // Update sort arrows
  document.querySelectorAll('#providerTable th').forEach(function(th) {
    var col = th.getAttribute('data-sort');
    th.classList.toggle('sorted', col === _sortCol);
    var arrow = th.querySelector('.sort-arrow');
    if (arrow && col === _sortCol) {
      arrow.innerHTML = _sortAsc ? '&#x25B2;' : '&#x25BC;';
    } else if (arrow) {
      arrow.innerHTML = '&#x25B2;';
    }
  });
}

// Attach sort handlers
document.querySelectorAll('#providerTable th[data-sort]').forEach(function(th) {
  th.addEventListener('click', function() {
    var col = th.getAttribute('data-sort');
    if (_sortCol === col) {
      _sortAsc = !_sortAsc;
    } else {
      _sortCol = col;
      _sortAsc = col === 'provider' || col === 'flow';
    }
    if (_providerData && _providerData.providers) {
      renderProviderTable(_providerData.providers);
    }
  });
});

// === Render Charts ===
function renderProviderCharts(providers) {
  if (typeof Chart === 'undefined') return;
  var t = getChartTheme();
  applyChartDefaults(t);

  try { destroyCharts(); } catch(e) {}

  // Aggregate by provider name for charts
  var provMap = {};
  providers.forEach(function(p) {
    var name = p.provider || 'N/A';
    if (!provMap[name]) {
      provMap[name] = { vol: 0, successTx: 0, totalTx: 0 };
    }
    provMap[name].vol += Number(p.vol_usd) || 0;
    provMap[name].successTx += Number(p.success_tx) || 0;
    provMap[name].totalTx += Number(p.total_tx) || 0;
  });

  var names = Object.keys(provMap).sort(function(a,b) { return provMap[b].vol - provMap[a].vol; });
  var volumes = names.map(function(n) { return provMap[n].vol; });
  var rates = names.map(function(n) {
    return provMap[n].totalTx > 0 ? (provMap[n].successTx / provMap[n].totalTx * 100) : 0;
  });

  var bgColors = names.map(function(_, i) { return t.palette[i % t.palette.length]; });
  var bgColorsAlpha = names.map(function(_, i) {
    var c = t.palette[i % t.palette.length];
    return c + '33';
  });

  // Volume Comparison - horizontal bar
  try {
    chartVolume = new Chart(document.getElementById('chartVolume'), {
      type: 'bar',
      data: {
        labels: names,
        datasets: [{
          label: 'Volume USD',
          data: volumes,
          backgroundColor: bgColorsAlpha,
          borderColor: bgColors,
          borderWidth: 1,
          borderRadius: 4
        }]
      },
      options: {
        indexAxis: 'y',
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: { display: false },
          tooltip: {
            callbacks: {
              label: function(ctx) { return 'Volume: ' + fmtUSD(ctx.raw); }
            }
          }
        },
        scales: {
          x: { grid: { color: t.grid }, ticks: { callback: function(v) { return fmtUSD(v); }, font: { size: 10 } } },
          y: { grid: { display: false }, ticks: { font: { size: 11, weight: 600 } } }
        }
      }
    });
  } catch(e) { console.warn('Chart volume:', e.message); }

  // Success Rate - vertical bar
  try {
    var barColors = rates.map(function(r) {
      return r >= 95 ? t.green : r >= 80 ? t.orange : t.red;
    });
    var barColorsAlpha = rates.map(function(r) {
      var base = r >= 95 ? t.green : r >= 80 ? t.orange : t.red;
      return base + '44';
    });

    chartSuccess = new Chart(document.getElementById('chartSuccess'), {
      type: 'bar',
      data: {
        labels: names,
        datasets: [{
          label: 'Success Rate %',
          data: rates,
          backgroundColor: barColorsAlpha,
          borderColor: barColors,
          borderWidth: 1,
          borderRadius: 4
        }]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: { display: false },
          tooltip: {
            callbacks: {
              label: function(ctx) { return 'Success: ' + ctx.raw.toFixed(1) + '%'; }
            }
          }
        },
        scales: {
          y: {
            grid: { color: t.grid },
            min: 0, max: 100,
            ticks: { callback: function(v) { return v + '%'; }, font: { size: 10 } }
          },
          x: { grid: { display: false }, ticks: { font: { size: 11, weight: 600 }, maxRotation: 45 } }
        }
      }
    });
  } catch(e) { console.warn('Chart success:', e.message); }
}

function renderTrendChart(trendData) {
  if (typeof Chart === 'undefined') return;
  if (chartTrend) { chartTrend.destroy(); chartTrend = null; }
  var t = getChartTheme();
  applyChartDefaults(t);

  if (!trendData || !trendData.length) return;

  // Collect all unique days and providers
  var daySet = {};
  var provSet = {};
  trendData.forEach(function(r) {
    daySet[r.dia] = true;
    provSet[r.provider || 'N/A'] = true;
  });
  var days = Object.keys(daySet).sort();
  var provNames = Object.keys(provSet);

  // Build data per provider
  var lookup = {};
  trendData.forEach(function(r) {
    var key = (r.provider || 'N/A') + '|' + r.dia;
    lookup[key] = Number(r.vol_usd) || 0;
  });

  var labels = days.map(function(d) { var p = d.split('-'); return p[2] + '/' + p[1]; });

  var datasets = provNames.map(function(prov, i) {
    var color = t.palette[i % t.palette.length];
    return {
      label: prov,
      data: days.map(function(day) { return lookup[prov + '|' + day] || 0; }),
      borderColor: color,
      backgroundColor: color + '15',
      borderWidth: 2,
      pointRadius: 1,
      pointHoverRadius: 5,
      fill: false,
      tension: 0.3
    };
  });

  try {
    chartTrend = new Chart(document.getElementById('chartTrend'), {
      type: 'line',
      data: { labels: labels, datasets: datasets },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        interaction: { mode: 'index', intersect: false },
        plugins: {
          legend: {
            position: 'top',
            labels: { font: { size: 11, weight: 600 }, padding: 12, usePointStyle: true, pointStyle: 'circle' }
          },
          tooltip: {
            callbacks: {
              label: function(ctx) { return ctx.dataset.label + ': ' + fmtUSD(ctx.raw); }
            }
          }
        },
        scales: {
          y: { grid: { color: t.grid }, ticks: { callback: function(v) { return fmtUSD(v); }, font: { size: 10 } } },
          x: { grid: { display: false }, ticks: { font: { size: 10 }, maxRotation: 45, maxTicksLimit: 20 } }
        }
      }
    });
  } catch(e) { console.warn('Chart trend:', e.message); }
}

// === API Loaders ===
async function loadProviders() {
  document.getElementById('periodInfo').textContent = 'Carregando providers...';
  try {
    var resp = await fetch('/admin/api/providers?start=' + currentStart + '&end=' + currentEnd);
    if (!resp.ok) { document.getElementById('periodInfo').textContent = 'Erro HTTP ' + resp.status; return; }
    var d = await resp.json();
    if (d.error) { document.getElementById('periodInfo').textContent = 'Erro: ' + d.error; return; }
    _providerData = d;

    // Hero KPIs
    var s = d.summary || {};
    document.getElementById('kpiProviders').textContent = fmtNum(s.total_providers || 0);
    document.getElementById('kpiSuccessRate').textContent = fmtPct(s.overall_success_rate);
    document.getElementById('kpiVolume').textContent = fmtUSD(s.total_volume);
    document.getElementById('kpiSettlement').textContent = fmtHrs(s.avg_settlement_hours);

    // Success rate color
    var srEl = document.getElementById('kpiSuccessRate');
    var sr = Number(s.overall_success_rate) || 0;
    srEl.style.color = sr >= 95 ? 'var(--green)' : sr >= 80 ? 'var(--orange)' : 'var(--red)';

    // Badge
    document.getElementById('providerCount').textContent = (d.providers || []).length + ' providers';

    // Table
    renderProviderTable(d.providers || []);

    // Charts
    renderProviderCharts(d.providers || []);

    // Period info
    var periodDays = Math.round((new Date(currentEnd) - new Date(currentStart)) / 86400000) + 1;
    document.getElementById('periodInfo').textContent = periodDays + ' dias | ' + fmtNum((d.providers||[]).length) + ' providers';

  } catch(e) {
    console.error('loadProviders error:', e);
    document.getElementById('periodInfo').textContent = 'Erro: ' + e.message;
  }
}

async function loadFailed() {
  try {
    var resp = await fetch('/admin/api/providers/failed?start=' + currentStart + '&end=' + currentEnd);
    if (!resp.ok) return;
    var d = await resp.json();
    if (d.error) return;

    // Total failed badge
    document.getElementById('failedTotal').textContent = fmtNum(d.total_failed || 0) + ' falhas | ' + fmtUSD(d.total_vol_failed);

    // By Provider
    var provBody = document.getElementById('failedByProviderBody');
    if (d.byProvider && d.byProvider.length) {
      provBody.innerHTML = d.byProvider.map(function(p) {
        var rate = Number(p.failure_rate || p.fail_rate || 0);
        var rateClass = rate <= 5 ? 'good' : rate <= 20 ? 'warning' : 'bad';
        return '<tr>'
          + '<td style="font-weight:700;">' + (p.provider || 'N/A') + '</td>'
          + '<td>' + fmtNum(p.failed_tx || p.qtd || 0) + '</td>'
          + '<td>' + fmtUSD(p.vol_failed || p.vol_usd || 0) + '</td>'
          + '<td><span class="status-badge ' + rateClass + '">' + rate.toFixed(1) + '%</span></td>'
          + '</tr>';
      }).join('');
    } else {
      provBody.innerHTML = '<tr><td colspan="4" style="text-align:center;color:var(--text-muted);">Nenhuma falha no periodo</td></tr>';
    }

    // By Status
    var statusBody = document.getElementById('failedByStatusBody');
    if (d.byStatus && d.byStatus.length) {
      statusBody.innerHTML = d.byStatus.map(function(s) {
        return '<tr>'
          + '<td style="font-weight:700;">' + (s.status || 'N/A') + '</td>'
          + '<td>' + fmtNum(s.qtd || s.count || 0) + '</td>'
          + '<td>' + fmtUSD(s.vol_usd || s.volume || 0) + '</td>'
          + '</tr>';
      }).join('');
    } else {
      statusBody.innerHTML = '<tr><td colspan="3" style="text-align:center;color:var(--text-muted);">Nenhuma falha no periodo</td></tr>';
    }

  } catch(e) {
    console.error('loadFailed error:', e);
  }
}

async function loadTrend() {
  try {
    var resp = await fetch('/admin/api/providers/trend?start=' + currentStart + '&end=' + currentEnd);
    if (!resp.ok) return;
    var d = await resp.json();
    if (d.error) return;
    _trendData = d;
    renderTrendChart(d);
  } catch(e) {
    console.error('loadTrend error:', e);
  }
}

// === Export to Excel (CSV) ===
document.getElementById('btnExport').addEventListener('click', function() {
  if (!_providerData || !_providerData.providers || !_providerData.providers.length) {
    alert('Nenhum dado para exportar.');
    return;
  }
  var rows = [['Provider','Flow','Total Tx','Success Tx','Success Rate %','Volume USD','Avg Ticket','Spread %','Settlement Hours']];
  _providerData.providers.forEach(function(p) {
    rows.push([
      p.provider || '', p.flow || '', p.total_tx || 0, p.success_tx || 0,
      (Number(p.success_rate)||0).toFixed(1), (Number(p.vol_usd)||0).toFixed(2),
      (Number(p.avg_ticket)||0).toFixed(2), (Number(p.avg_spread_pct)||0).toFixed(2),
      (Number(p.avg_settlement_hours)||0).toFixed(1)
    ]);
  });
  var csv = rows.map(function(r) {
    return r.map(function(v) {
      var s = String(v);
      return s.indexOf(',') >= 0 || s.indexOf('"') >= 0 ? '"' + s.replace(/"/g, '""') + '"' : s;
    }).join(',');
  }).join('\\n');

  var blob = new Blob(['\\uFEFF' + csv], { type: 'text/csv;charset=utf-8;' });
  var url = URL.createObjectURL(blob);
  var a = document.createElement('a');
  a.href = url;
  a.download = 'providers_' + currentStart + '_' + currentEnd + '.csv';
  a.click();
  URL.revokeObjectURL(url);
});

// === Theme Change Handler ===
window.addEventListener('themechange', function() {
  if (_providerData && _providerData.providers) {
    renderProviderCharts(_providerData.providers);
  }
  if (_trendData) {
    renderTrendChart(_trendData);
  }
});

// === Init ===
function _startProviders() {
  try {
    if (typeof Chart !== 'undefined') {
      var t = getChartTheme();
      applyChartDefaults(t);
    }
    loadAll();
  } catch(e) {
    console.error('Init error:', e);
    document.getElementById('periodInfo').textContent = 'Init erro: ' + e.message;
  }
}
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', _startProviders);
} else {
  _startProviders();
}
<\/script>
</body>
</html>`;
}

module.exports = { buildAdminProvidersHTML };
