<?php
// csr_manager/dashboard.php — CSR Manager main dashboard
if (session_status() === PHP_SESSION_NONE) session_start();
require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../includes/app_helpers.php';
require_once __DIR__ . '/../includes/csr_report_helpers.php';

// Quick auth check (layout.php will do the full role check)
if (!isset($_SESSION['csr_id'])) { header('Location: ../login.php'); exit(); }

$db = (new Database())->getConnection();
ensureCsrRoleSchema($db);

$managerId = (int)$_SESSION['csr_id'];
$role = getCsrRoleForReport($db, $managerId);
if ($role !== 'csr_manager') { header('Location: ../csr/dashboard.php'); exit(); }

$title = 'CSR Dashboard';

$extra_styles = <<<'CSS'
<style>
/* ── Stat bar ─────────────────────────────────────────────── */
.cm-section-title {
  font-family:'Space Grotesk',system-ui,sans-serif;
  font-weight:900;
  font-size:1rem;
  margin: 4px 0 10px;
  color: var(--cm-text);
}
.cm-section-title small { color: var(--cm-muted); font-family:'Inter',system-ui,sans-serif; font-weight:700; margin-left:8px; }
.cm-stat-bar {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
  margin-bottom: 20px;
}

.cm-stat-tile {
  background: var(--cm-card);
  border: 1px solid var(--cm-border);
  border-radius: 14px;
  padding: 16px 10px 12px;
  text-align: center;
  transition: border-color .2s, transform .2s;
}
.cm-stat-tile:hover { border-color: var(--cm-border2); transform: translateY(-2px); }
.cm-stat-tile__icon { font-size: 18px; margin-bottom: 6px; color: var(--cm-muted); }
.cm-stat-tile__val  {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 1.9rem; font-weight: 800; line-height: 1; margin-bottom: 4px;
}
.cm-stat-tile__lbl  { font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--cm-muted); }

.cm-stat-tile--handled   .cm-stat-tile__val { color: var(--cm-cyan); }
.cm-stat-tile--assigned  .cm-stat-tile__val { color: var(--cm-blue); }
.cm-stat-tile--progress  .cm-stat-tile__val { color: var(--cm-purple); }
.cm-stat-tile--completed .cm-stat-tile__val { color: var(--cm-green); }
.cm-stat-tile--cancelled .cm-stat-tile__val { color: var(--cm-red); }
.cm-stat-tile--calls     .cm-stat-tile__val { color: var(--cm-text); }
.cm-stat-tile--scheduled .cm-stat-tile__val { color: var(--cm-cyan); }
.cm-stat-tile--connected .cm-stat-tile__val { color: var(--cm-green); }
.cm-stat-tile--missed    .cm-stat-tile__val { color: var(--cm-yellow); }
.cm-stat-tile--updates   .cm-stat-tile__val { color: var(--cm-purple); }
.cm-stat-tile--warn      .cm-stat-tile__val { color: var(--cm-yellow); }
.cm-stat-tile--mistakes  .cm-stat-tile__val { color: var(--cm-red); }

/* ── Quick-action bar ─────────────────────────────────────── */
.cm-quick-bar {
  display: flex;
  gap: 8px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

/* ── Charts row ───────────────────────────────────────────── */
.cm-charts-row {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 16px;
  margin-bottom: 16px;
}

/* ── Trend panel ──────────────────────────────────────────── */
.cm-trend-panel { margin-bottom: 16px; }

/* ── Bottom row ───────────────────────────────────────────── */
.cm-bottom-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 16px;
}

.cm-team-cards-area {
  grid-column: span 2;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

/* Team card */
.cm-team-card {
  background: var(--cm-card);
  border: 1px solid var(--cm-border);
  border-radius: 14px;
  padding: 14px 16px;
  cursor: pointer;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.cm-team-card:hover {
  transform: translateY(-2px);
  border-color: var(--cm-border2);
  box-shadow: 0 12px 28px rgba(0,0,0,.22);
}
.cm-team-card__hint { font-size:.65rem;color:var(--cm-muted);font-weight:700;margin-left:auto;text-transform:uppercase;letter-spacing:.05em; }
.cm-team-card__head {display:flex;align-items:center;gap:8px;margin-bottom:10px;}
.cm-team-card__name {
  font-size: .7rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .08em; margin:0;
}
.cm-team-grid { display:grid; grid-template-columns:1fr 1fr; gap:0 14px; }
.cm-tsr { display: flex; justify-content: space-between; padding: 4px 0; font-size: .76rem; border-bottom: 1px solid var(--cm-border); }
.cm-tsr:last-child { border-bottom: none; }
.cm-tsr__l { color: var(--cm-muted); }
.cm-tsr__v { font-weight: 700; }

/* Mistakes panel */
.cm-mistakes-panel {
  background: var(--cm-card);
  border: 1px solid var(--cm-border);
  border-radius: 14px;
  padding: 14px 16px;
}
.cm-mistakes-hdr {
  display: flex; align-items: center; gap: 8px; margin-bottom: 12px;
}
.cm-mistakes-title {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: .92rem; font-weight: 800; flex: 1;
}
.cm-mistake-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0; border-bottom: 1px solid var(--cm-border);
}
.cm-mistake-row:last-child { border-bottom: none; }
.cm-mistake-team { font-size: .62rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--cm-blue); display: block; }
.cm-mistake-name { font-size: .84rem; font-weight: 700; }
.cm-mistake-metric { font-size: .74rem; color: var(--cm-muted); }
.cm-mistake-badge {
  margin-left: auto;
  background: oklch(0.82 0.16 85 / 0.18);
  border: 1px solid oklch(0.82 0.16 85 / 0.45);
  color: var(--cm-yellow);
  font-size: .7rem; font-weight: 800; padding: 3px 8px; border-radius: 8px;
  white-space: nowrap; flex-shrink: 0;
}
.cm-mistake-badge.danger {
  background: oklch(0.68 0.22 27 / 0.18);
  border-color: oklch(0.68 0.22 27 / 0.45);
  color: var(--cm-red);
}

@media (max-width: 960px) {
  .cm-stat-bar { grid-template-columns: repeat(4, 1fr); }
  .cm-charts-row { grid-template-columns: 1fr; }
  .cm-bottom-row { grid-template-columns: 1fr; }
  .cm-team-cards-area { grid-column: span 1; grid-template-columns: 1fr; }
}
@media (max-width: 540px) {
  .cm-stat-bar { grid-template-columns: repeat(2, 1fr); }
}

.cm-team-card.is-clickable,
.cm-mistake-row.is-clickable { cursor:pointer; }
.cm-team-card.is-clickable:hover,
.cm-mistake-row.is-clickable:hover { background:oklch(0.98 0.005 250 / 0.045); }
.cm-detail-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.62);display:none;align-items:center;justify-content:center;z-index:9999;padding:18px;}
.cm-detail-backdrop.is-open{display:flex;}
.cm-detail-modal{width:min(760px,96vw);max-height:86vh;overflow:auto;background:var(--cm-card);border:1px solid var(--cm-border2);border-radius:18px;box-shadow:0 22px 80px rgba(0,0,0,.5);}
.cm-detail-head{display:flex;align-items:flex-start;gap:12px;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--cm-border);}
.cm-detail-title{font-family:'Space Grotesk',system-ui,sans-serif;font-size:1.05rem;font-weight:900;margin:0;}
.cm-detail-sub{color:var(--cm-muted);font-size:.78rem;font-weight:700;margin-top:3px;}
.cm-detail-close{border:1px solid var(--cm-border);background:transparent;color:var(--cm-text)!important;border-radius:10px;width:34px;height:34px;font-weight:900;}
.cm-detail-body{padding:16px 18px;}
.cm-detail-item{border:1px solid var(--cm-border);border-radius:13px;padding:12px;margin-bottom:10px;background:oklch(0.98 0.005 250 / 0.028);}
.cm-detail-item:last-child{margin-bottom:0;}
.cm-detail-line{display:flex;gap:10px;justify-content:space-between;align-items:center;margin-bottom:6px;}
.cm-detail-item-title{font-weight:900;font-size:.9rem;}
.cm-detail-pill{font-size:.65rem;font-weight:900;text-transform:uppercase;border-radius:999px;padding:3px 8px;border:1px solid var(--cm-border2);color:var(--cm-yellow);}
.cm-detail-message{color:var(--cm-text);font-size:.84rem;line-height:1.45;white-space:pre-wrap;}
.cm-detail-meta{color:var(--cm-muted);font-size:.72rem;font-weight:700;margin-top:8px;}
.cm-detail-table{width:100%;border-collapse:collapse;font-size:.82rem;}
.cm-detail-table td{border-bottom:1px solid var(--cm-border);padding:7px 4px;}
.cm-detail-table td:last-child{text-align:right;font-weight:900;}

.cm-disc-filter{display:flex;gap:8px;flex-wrap:wrap;margin:8px 0 10px;}
.cm-disc-filter select,.cm-disc-filter input{height:32px;border:1px solid var(--cm-border);border-radius:10px;background:oklch(0.18 0.04 262 / .92);color:var(--cm-text)!important;-webkit-text-fill-color:var(--cm-text)!important;font-size:.74rem;font-weight:800;padding:0 10px;outline:none;}
.cm-disc-filter input{min-width:150px;flex:1;}
.cm-disc-filter select:focus,.cm-disc-filter input:focus{border-color:var(--cm-cyan);box-shadow:0 0 0 2px rgba(34,211,238,.12);}
.cm-disc-filter select option{background:#0f172a;color:#e5e7eb;}
.cm-disc-empty{text-align:center;color:var(--cm-muted);font-size:.8rem;padding:16px 0;}

</style>
CSS;

ob_start();
?>

<!-- Quick-action bar (matches screenshot exactly) -->
<div class="cm-quick-bar">
  <button type="button" class="cm-btn" onclick="cmGoBack()"><i class="fas fa-arrow-left"></i> Back</button>
  <a href="tickets.php"       class="cm-btn"><i class="fas fa-clipboard-list"></i> Tickets</a>
  <a href="calls.php"         class="cm-btn"><i class="fas fa-phone-volume"></i> Calls</a>
  <a href="messages.php"      class="cm-btn"><i class="fas fa-comments"></i> Messages</a>
  <a href="manual_ticket.php" class="cm-btn"><i class="fas fa-ticket-alt"></i> Manual Ticket</a>
  <a href="mistake.php" class="cm-btn"><i class="fas fa-circle-exclamation"></i> Mistake</a>
  <a href="warning.php" class="cm-btn"><i class="fas fa-triangle-exclamation"></i> Warning</a>

  <div style="margin-left:auto;display:flex;gap:8px;flex-wrap:wrap;">
    <a href="report.php"  class="cm-btn cm-btn--active"><i class="fas fa-calendar-day"></i> CSR Daily Report</a>
    <a href="calls.php"   class="cm-btn"><i class="fas fa-phone-volume"></i> Call Tracker</a>
    <a href="tickets.php" class="cm-btn"><i class="fas fa-chart-bar"></i> Status Summary</a>
    <button class="cm-btn" id="cmDashRefreshBtn" onclick="cmDashLoad()">
      <i class="fas fa-sync-alt" id="cmRefreshIcon"></i> Refresh
    </button>
  </div>
</div>

<!-- Overall Total stat bar -->
<div class="cm-section-title"><i class="fas fa-layer-group me-1"></i> Overall Total <small>All teams · all available records</small></div>
<div class="cm-stat-bar">
  <div class="cm-stat-tile cm-stat-tile--handled">
    <div class="cm-stat-tile__icon"><i class="fas fa-clipboard-check"></i></div>
    <div class="cm-stat-tile__val" id="cmOHandledToday">—</div>
    <div class="cm-stat-tile__lbl">Total Handled</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--assigned">
    <div class="cm-stat-tile__icon"><i class="fas fa-ticket-alt"></i></div>
    <div class="cm-stat-tile__val" id="cmOAssignedTickets">—</div>
    <div class="cm-stat-tile__lbl">Assigned Tickets</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--progress">
    <div class="cm-stat-tile__icon"><i class="fas fa-spinner"></i></div>
    <div class="cm-stat-tile__val" id="cmOInProgress">—</div>
    <div class="cm-stat-tile__lbl">In Progress</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--completed">
    <div class="cm-stat-tile__icon"><i class="fas fa-circle-check"></i></div>
    <div class="cm-stat-tile__val" id="cmOCompletedToday">—</div>
    <div class="cm-stat-tile__lbl">Completed Tickets</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--cancelled">
    <div class="cm-stat-tile__icon"><i class="fas fa-ban"></i></div>
    <div class="cm-stat-tile__val" id="cmOCancelledToday">—</div>
    <div class="cm-stat-tile__lbl">Cancelled Tickets</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--calls">
    <div class="cm-stat-tile__icon"><i class="fas fa-phone-volume"></i></div>
    <div class="cm-stat-tile__val" id="cmOTotalCalls">—</div>
    <div class="cm-stat-tile__lbl">Total Calls</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--scheduled">
    <div class="cm-stat-tile__icon"><i class="fas fa-calendar-check"></i></div>
    <div class="cm-stat-tile__val" id="cmOCallsScheduled">—</div>
    <div class="cm-stat-tile__lbl">Calls Scheduled</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--connected">
    <div class="cm-stat-tile__icon"><i class="fas fa-headset"></i></div>
    <div class="cm-stat-tile__val" id="cmOConnected">—</div>
    <div class="cm-stat-tile__lbl">Connected</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--missed">
    <div class="cm-stat-tile__icon"><i class="fas fa-phone-slash"></i></div>
    <div class="cm-stat-tile__val" id="cmOMissedAbsent">—</div>
    <div class="cm-stat-tile__lbl">Missed / Absent</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--updates">
    <div class="cm-stat-tile__icon"><i class="fas fa-comment-dots"></i></div>
    <div class="cm-stat-tile__val" id="cmOUpdates">—</div>
    <div class="cm-stat-tile__lbl">Updates</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--warn">
    <div class="cm-stat-tile__icon"><i class="fas fa-triangle-exclamation"></i></div>
    <div class="cm-stat-tile__val" id="cmOWarnings">—</div>
    <div class="cm-stat-tile__lbl">Warnings</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--mistakes">
    <div class="cm-stat-tile__icon"><i class="fas fa-clock-rotate-left"></i></div>
    <div class="cm-stat-tile__val" id="cmOMistakes">—</div>
    <div class="cm-stat-tile__lbl">Mistakes</div>
  </div>
</div>

<!-- Today stat bar -->
<div class="cm-section-title"><i class="fas fa-calendar-day me-1"></i> Today <small>All teams · today only</small></div>
<div class="cm-stat-bar">
  <div class="cm-stat-tile cm-stat-tile--handled">
    <div class="cm-stat-tile__icon"><i class="fas fa-clipboard-check"></i></div>
    <div class="cm-stat-tile__val" id="cmSHandledToday">—</div>
    <div class="cm-stat-tile__lbl">Handled Today</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--assigned">
    <div class="cm-stat-tile__icon"><i class="fas fa-ticket-alt"></i></div>
    <div class="cm-stat-tile__val" id="cmSAssignedTickets">—</div>
    <div class="cm-stat-tile__lbl">Assigned Tickets</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--progress">
    <div class="cm-stat-tile__icon"><i class="fas fa-spinner"></i></div>
    <div class="cm-stat-tile__val" id="cmSInProgress">—</div>
    <div class="cm-stat-tile__lbl">In Progress</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--completed">
    <div class="cm-stat-tile__icon"><i class="fas fa-circle-check"></i></div>
    <div class="cm-stat-tile__val" id="cmSCompletedToday">—</div>
    <div class="cm-stat-tile__lbl">Completed Today</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--cancelled">
    <div class="cm-stat-tile__icon"><i class="fas fa-ban"></i></div>
    <div class="cm-stat-tile__val" id="cmSCancelledToday">—</div>
    <div class="cm-stat-tile__lbl">Cancelled Today</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--calls">
    <div class="cm-stat-tile__icon"><i class="fas fa-phone-volume"></i></div>
    <div class="cm-stat-tile__val" id="cmSTotalCalls">—</div>
    <div class="cm-stat-tile__lbl">Total Calls</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--scheduled">
    <div class="cm-stat-tile__icon"><i class="fas fa-calendar-check"></i></div>
    <div class="cm-stat-tile__val" id="cmSCallsScheduled">—</div>
    <div class="cm-stat-tile__lbl">Calls Scheduled</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--connected">
    <div class="cm-stat-tile__icon"><i class="fas fa-headset"></i></div>
    <div class="cm-stat-tile__val" id="cmSConnected">—</div>
    <div class="cm-stat-tile__lbl">Connected</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--missed">
    <div class="cm-stat-tile__icon"><i class="fas fa-phone-slash"></i></div>
    <div class="cm-stat-tile__val" id="cmSMissedAbsent">—</div>
    <div class="cm-stat-tile__lbl">Missed / Absent</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--updates">
    <div class="cm-stat-tile__icon"><i class="fas fa-comment-dots"></i></div>
    <div class="cm-stat-tile__val" id="cmSUpdates">—</div>
    <div class="cm-stat-tile__lbl">Updates</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--warn">
    <div class="cm-stat-tile__icon"><i class="fas fa-triangle-exclamation"></i></div>
    <div class="cm-stat-tile__val" id="cmSWarnings">—</div>
    <div class="cm-stat-tile__lbl">Warnings</div>
  </div>
  <div class="cm-stat-tile cm-stat-tile--mistakes">
    <div class="cm-stat-tile__icon"><i class="fas fa-clock-rotate-left"></i></div>
    <div class="cm-stat-tile__val" id="cmSMistakes">—</div>
    <div class="cm-stat-tile__lbl">Mistakes</div>
  </div>
</div>

<!-- Charts row -->
<div class="cm-charts-row">
  <div class="cm-card">
    <div class="cm-card__title">Team Performance</div>
    <div style="position:relative;height:220px;">
      <canvas id="cmTeamPerfChart"></canvas>
    </div>
  </div>
  <div class="cm-card">
    <div class="cm-card__title">Task Status</div>
    <div style="position:relative;height:220px;">
      <canvas id="cmTaskStatusChart"></canvas>
    </div>
  </div>
</div>


<!-- Bottom row: team cards + warnings + mistakes -->
<div class="cm-bottom-row">
  <div class="cm-team-cards-area" id="cmTeamCardsArea">
    <div class="cm-team-card cm-skeleton" style="height:160px;"></div>
    <div class="cm-team-card cm-skeleton" style="height:160px;"></div>
  </div>
  <div class="cm-mistakes-panel">
    <div class="cm-mistakes-hdr">
      <i class="fas fa-triangle-exclamation" style="color:var(--cm-yellow);"></i>
      <span class="cm-mistakes-title">Recent Warnings</span>
      <span id="cmWarningBadge" class="cm-badge cm-badge--yellow">0</span>
    </div>
    <div class="cm-disc-filter">
      <select id="cmWarningDateFilter" aria-label="Warning date filter">
        <option value="all">All dates</option>
        <option value="today">Today</option>
        <option value="7">Last 7 days</option>
        <option value="30">Last 30 days</option>
      </select>
      <input id="cmWarningSearchFilter" type="search" placeholder="Search team / name / title">
    </div>
    <div id="cmWarningsBoard">
      <div style="text-align:center;color:var(--cm-muted);font-size:.8rem;padding:20px 0;">Loading…</div>
    </div>
  </div>

  <div class="cm-mistakes-panel">
    <div class="cm-mistakes-hdr">
      <i class="fas fa-circle-exclamation" style="color:var(--cm-red);"></i>
      <span class="cm-mistakes-title">Recent Mistakes</span>
      <span id="cmMistakeBadge" class="cm-badge cm-badge--yellow">0</span>
    </div>
    <div class="cm-disc-filter">
      <select id="cmMistakeDateFilter" aria-label="Mistake date filter">
        <option value="all">All dates</option>
        <option value="today">Today</option>
        <option value="7">Last 7 days</option>
        <option value="30">Last 30 days</option>
      </select>
      <input id="cmMistakeSearchFilter" type="search" placeholder="Search team / name / title">
    </div>
    <div id="cmMistakesBoard">
      <div style="text-align:center;color:var(--cm-muted);font-size:.8rem;padding:20px 0;">Loading…</div>
    </div>
  </div>
</div>


<div class="cm-detail-backdrop" id="cmDetailModal" onclick="cmCloseDetailModal(event)">
  <div class="cm-detail-modal" onclick="event.stopPropagation()">
    <div class="cm-detail-head">
      <div>
        <h3 class="cm-detail-title" id="cmDetailTitle">Details</h3>
        <div class="cm-detail-sub" id="cmDetailSub"></div>
      </div>
      <button type="button" class="cm-detail-close" onclick="cmCloseDetailModal()">×</button>
    </div>
    <div class="cm-detail-body" id="cmDetailBody"></div>
  </div>
</div>


<script>
function cmGoBack() {
  if (window.history.length > 1) {
    window.history.back();
    return;
  }
  window.location.href = 'dashboard.php';
}
/* ============================================================
   Dashboard data + charts
   ============================================================ */
const CM = {
  gh:       'rgba(96,165,250,.85)',
  sched:    'rgba(52,211,153,.90)',
  attempt:  'rgba(167,139,250,.85)',
  mistake:  'rgba(248,113,113,.85)',
  grid:     'rgba(255,255,255,.05)',
  tick:     'rgba(255,255,255,.55)',
  fs:       11,
};

let _teamPerf = null, _taskStatus = null;
let _cmWarningRows = [], _cmMistakeRows = [];

function cmDashLoad() {
  const icon = document.getElementById('cmRefreshIcon');
  if (icon) icon.classList.add('fa-spin');

  $.ajax({
    url: '../csr/ajax/get_manager_dashboard.php',
    method: 'GET',
    dataType: 'json',
    success: function(res) {
      if (!res.success) { console.warn(res.message); return; }
      cmRenderOverallStats(res.summary_overall || res.summary || {});
      cmRenderStats(res.summary_today || res.summary || {});
      const teamsForDisplay = cmPickTeamRows(res.team_stats_overall, res.team_stats);
      cmRenderTeamPerf(teamsForDisplay);
      cmRenderTaskStatus(res.task_status);
      cmRenderTeamCards(teamsForDisplay);
      cmRenderWarnings(res.warning_records || []);
      cmRenderMistakes(res.mistakes || []);
      cmWireDisciplineFilters();
    },
    complete: function() {
      if (icon) icon.classList.remove('fa-spin');
    }
  });
}

function cmRenderOverallStats(s) {
  const map = {
    cmOHandledToday:    s.handled_today,
    cmOAssignedTickets: s.assigned_tickets,
    cmOInProgress:      s.in_progress,
    cmOCompletedToday:  s.completed_today,
    cmOCancelledToday:  s.cancelled_today,
    cmOTotalCalls:      s.total_calls,
    cmOCallsScheduled:  s.calls_scheduled,
    cmOConnected:       s.connected,
    cmOMissedAbsent:    s.missed_absent,
    cmOUpdates:         s.updates,
    cmOWarnings:        s.warnings,
    cmOMistakes:        s.mistakes
  };
  Object.entries(map).forEach(([id, val]) => cmAnimCount(id, val || 0));
}

function cmRenderStats(s) {
  const map = {
    cmSHandledToday:    s.handled_today,
    cmSAssignedTickets: s.assigned_tickets,
    cmSInProgress:      s.in_progress,
    cmSCompletedToday:  s.completed_today,
    cmSCancelledToday:  s.cancelled_today,
    cmSTotalCalls:      s.total_calls,
    cmSCallsScheduled:  s.calls_scheduled,
    cmSConnected:       s.connected,
    cmSMissedAbsent:    s.missed_absent,
    cmSUpdates:         s.updates,
    cmSWarnings:        s.warnings,
    cmSMistakes:        s.mistakes
  };
  Object.entries(map).forEach(([id, val]) => cmAnimCount(id, val || 0));
}

function cmAnimCount(id, target) {
  const el = document.getElementById(id);
  if (!el) return;
  const start = parseInt(el.textContent) || 0;
  const steps = 18; let i = 0;
  const step = () => { i++; el.textContent = Math.round(start + (target - start) * (i / steps)); if (i < steps) requestAnimationFrame(step); else el.textContent = target; };
  requestAnimationFrame(step);
}


function cmPickTeamRows(primary, fallback) {
  // Do not let an empty overall array hide valid team cards from the selected/today data.
  if (Array.isArray(primary) && primary.length) return primary;
  if (Array.isArray(fallback) && fallback.length) return fallback;
  return [];
}

function cmRenderTeamPerf(ts) {
  const canvas = document.getElementById('cmTeamPerfChart');
  if (!canvas) return;
  ts = Array.isArray(ts) ? ts : [];
  const ctx = canvas.getContext('2d');
  if (_teamPerf) _teamPerf.destroy();

  const cleanTeams = ts.map(t => ({
    team_name: String(t.team_name || 'Team').replace(/^(Team |TEAM )/i,''),
    handled_today: parseInt(t.handled_today, 10) || 0,
    assigned_tickets: parseInt(t.assigned_tickets, 10) || 0,
    completed_today: parseInt(t.completed_today, 10) || 0,
    calls_scheduled: parseInt(t.calls_scheduled, 10) || 0,
    connected: parseInt(t.connected, 10) || 0
  }));

  if (!cleanTeams.length) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    return;
  }

  _teamPerf = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: cleanTeams.map(t => t.team_name),
      datasets: [
        { label:'Handled', data: cleanTeams.map(t=>t.handled_today), backgroundColor: CM.gh, borderRadius:4, barPercentage:0.34 },
        { label:'Assigned', data: cleanTeams.map(t=>t.assigned_tickets), backgroundColor: 'rgba(59,130,246,.85)', borderRadius:4, barPercentage:0.34 },
        { label:'Completed', data: cleanTeams.map(t=>t.completed_today), backgroundColor: CM.sched, borderRadius:4, barPercentage:0.34 },
        { label:'Connected', data: cleanTeams.map(t=>t.connected), backgroundColor: CM.attempt, borderRadius:4, barPercentage:0.34 }
      ]
    },
    options: cmChartOpts()
  });
}

function cmRenderTaskStatus(ts) {
  if (!ts || !ts.length) return;
  const ctx = document.getElementById('cmTaskStatusChart').getContext('2d');
  if (_taskStatus) _taskStatus.destroy();
  _taskStatus = new Chart(ctx, {
    type: 'doughnut',
    data: {
      labels: ts.map(t => t.status_name),
      datasets: [{ data: ts.map(t => parseInt(t.cnt)||0), backgroundColor: ts.map(t => t.color_code||'#4fc3f7'), borderWidth:1, borderColor:'oklch(0.18 0.04 262)' }]
    },
    options: {
      responsive:true, maintainAspectRatio:false, cutout:'58%',
      plugins: {
        legend: { position:'right', labels:{ color:CM.tick, font:{size:CM.fs-1,family:'Inter'}, boxWidth:10, padding:6 } },
        tooltip: cmTooltipCfg()
      }
    }
  });
}


function cmCloseDetailModal(e){
  if (e && e.target && e.target.id !== 'cmDetailModal') return;
  const m = document.getElementById('cmDetailModal');
  if (m) m.classList.remove('is-open');
}
function cmOpenDetailModal(title, sub, body){
  const m = document.getElementById('cmDetailModal');
  if (!m) return;
  document.getElementById('cmDetailTitle').textContent = title || 'Details';
  document.getElementById('cmDetailSub').textContent = sub || '';
  document.getElementById('cmDetailBody').innerHTML = body || '<div style="color:var(--cm-muted);">No details available.</div>';
  m.classList.add('is-open');
}
function cmFmtDate(v){
  if (!v) return '';
  const d = new Date(String(v).replace(' ', 'T'));
  if (isNaN(d.getTime())) return String(v);
  return d.toLocaleString();
}
function cmOpenDisciplineDetails(kind, item){
  item = item || {};
  const count = parseInt(kind === 'warning' ? item.warnings : item.mistakes) || 0;
  const label = kind === 'warning' ? 'Warning' : 'Mistake';
  const details = Array.isArray(item.details) ? item.details : [];
  const body = details.length ? details.map(d => `
    <div class="cm-detail-item">
      <div class="cm-detail-line">
        <div class="cm-detail-item-title">${cmEsc(d.title || label)}</div>
        <span class="cm-detail-pill">${cmEsc(d.severity || 'normal')}</span>
      </div>
      <div class="cm-detail-message">${cmEsc(d.message || 'No message provided.')}</div>
      <div class="cm-detail-meta">Sent by ${cmEsc(d.sender || 'Unknown')} • ${cmEsc(cmFmtDate(d.created_at))}</div>
    </div>`).join('') : '<div style="color:var(--cm-muted);">No individual details found for this record.</div>';
  cmOpenDetailModal(`${label} Details — ${item.name || 'User'}`, `${item.team || 'No team'} • Total ${label.toLowerCase()}s: ${count}`, body);
}
function cmOpenTeamDetails(t){
  t = t || {};
  const rows = [
    ['Agents', t.agents], ['Total Handled', t.handled_today], ['Assigned Tickets', t.assigned_tickets], ['In Progress', t.in_progress],
    ['Completed Tickets', t.completed_today], ['Cancelled Tickets', t.cancelled_today], ['Total Calls', t.total_calls], ['Calls Scheduled', t.calls_scheduled],
    ['Connected', t.connected], ['Missed / Absent', t.missed_absent], ['Updates', t.updates], ['Warnings', t.warnings], ['Mistakes', t.mistakes]
  ];
  const body = `<table class="cm-detail-table">${rows.map(r => `<tr><td>${cmEsc(r[0])}</td><td>${r[1] ?? 0}</td></tr>`).join('')}</table>`;
  cmOpenDetailModal(`${t.team_name || 'Team'} Details`, 'Team summary breakdown', body);
}

function cmRenderTeamCards(ts) {
  const area = document.getElementById('cmTeamCardsArea');
  if (!ts || !ts.length) { area.innerHTML = '<div style="color:var(--cm-muted);">No teams found.</div>'; return; }
  const colors = ['var(--cm-cyan)','var(--cm-green)','var(--cm-purple)','var(--cm-yellow)'];
  area.style.gridTemplateColumns = ts.length === 1 ? '1fr' : '1fr 1fr';
  const row = (label, value, color = '') => `
    <div class="cm-tsr"><span class="cm-tsr__l">${label}</span><span class="cm-tsr__v" ${color ? `style="color:${color}"` : ''}>${value ?? 0}</span></div>`;
  area.innerHTML = ts.map((t,i) => `
    <div class="cm-team-card is-clickable" onclick='cmOpenTeamDetails(${cmAttr(t)})' title="Click to show team details">
      <div class="cm-team-card__head">
        <div class="cm-team-card__name" style="color:${colors[i%colors.length]}">${cmEsc(t.team_name)}</div>
        <div class="cm-team-card__hint">Click to filter</div>
      </div>
      <div class="cm-team-grid">
        ${row('Agents', t.agents)}
        ${row('Total Handled', t.handled_today, 'var(--cm-cyan)')}
        ${row('Assigned Tickets', t.assigned_tickets, 'var(--cm-blue)')}
        ${row('In Progress', t.in_progress, 'var(--cm-purple)')}
        ${row('Completed Tickets', t.completed_today, 'var(--cm-green)')}
        ${row('Cancelled Tickets', t.cancelled_today, 'var(--cm-red)')}
        ${row('Total Calls', t.total_calls)}
        ${row('Calls Scheduled', t.calls_scheduled, 'var(--cm-cyan)')}
        ${row('Connected', t.connected, 'var(--cm-green)')}
        ${row('Missed / Absent', t.missed_absent, 'var(--cm-yellow)')}
        ${row('Updates', t.updates, 'var(--cm-purple)')}
        ${row('Warnings', t.warnings, 'var(--cm-yellow)')}
        ${row('Mistakes', t.mistakes, 'var(--cm-red)')}
      </div>
    </div>`).join('');
}

function cmRenderWarnings(warnings) {
  _cmWarningRows = Array.isArray(warnings) ? warnings : [];
  cmRenderDisciplineBoard('warning');
}

function cmRenderMistakes(mistakes) {
  _cmMistakeRows = Array.isArray(mistakes) ? mistakes : [];
  cmRenderDisciplineBoard('mistake');
}

function cmGetDiscFilters(kind) {
  const prefix = kind === 'warning' ? 'Warning' : 'Mistake';
  return {
    date: (document.getElementById(`cm${prefix}DateFilter`) || {}).value || 'all',
    search: ((document.getElementById(`cm${prefix}SearchFilter`) || {}).value || '').trim().toLowerCase()
  };
}

function cmRecordDatePass(item, dateFilter) {
  if (!dateFilter || dateFilter === 'all') return true;
  const details = Array.isArray(item.details) ? item.details : [];
  const dates = details.map(d => d.created_at).filter(Boolean);
  if (!dates.length && item.last_record_at) dates.push(item.last_record_at);
  if (!dates.length) return true;
  const now = new Date();
  const startToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  return dates.some(v => {
    const d = new Date(String(v).replace(' ', 'T'));
    if (isNaN(d.getTime())) return false;
    if (dateFilter === 'today') return d >= startToday;
    const days = parseInt(dateFilter, 10) || 0;
    if (!days) return true;
    const start = new Date(startToday);
    start.setDate(start.getDate() - (days - 1));
    return d >= start;
  });
}

function cmRecordSearchPass(item, q) {
  if (!q) return true;
  const details = Array.isArray(item.details) ? item.details : [];
  const hay = [item.team, item.name, item.role, item.updates, item.total_calls]
    .concat(details.flatMap(d => [d.title, d.message, d.sender, d.severity, d.created_at]))
    .join(' ').toLowerCase();
  return hay.includes(q);
}

function cmFilterDisciplineRows(rows, kind) {
  const f = cmGetDiscFilters(kind);
  return rows.filter(item => cmRecordDatePass(item, f.date) && cmRecordSearchPass(item, f.search));
}

function cmRenderDisciplineBoard(kind) {
  const isWarning = kind === 'warning';
  const rows = isWarning ? _cmWarningRows : _cmMistakeRows;
  const filtered = cmFilterDisciplineRows(rows, kind);
  const board = document.getElementById(isWarning ? 'cmWarningsBoard' : 'cmMistakesBoard');
  const badge = document.getElementById(isWarning ? 'cmWarningBadge' : 'cmMistakeBadge');
  if (!board || !badge) return;
  const key = isWarning ? 'warnings' : 'mistakes';
  badge.textContent = filtered.reduce((s,m)=>s+(parseInt(m[key], 10)||0), 0);
  if (!filtered.length) {
    board.innerHTML = `<div class="cm-disc-empty">No ${isWarning ? 'warnings' : 'mistakes'} match this filter.</div>`;
    return;
  }
  board.innerHTML = filtered.map(m => `
    <div class="cm-mistake-row is-clickable" onclick='cmOpenDisciplineDetails("${kind}", ${cmAttr(m)})' title="Click to show ${kind} details">
      <div>
        <span class="cm-mistake-team">${cmEsc(m.team || 'No team')}</span>
        <span class="cm-mistake-name">${cmEsc(m.name)}</span>
        <span class="cm-mistake-metric">Updates: ${m.updates||0} • Calls: ${m.total_calls||0}</span>
      </div>
      <span class="cm-mistake-badge ${(parseInt(m[key], 10)||0)>=5?'danger':''}">
        <i class="fas ${isWarning ? 'fa-triangle-exclamation' : 'fa-circle-exclamation'} me-1"></i>${m[key]||0}
      </span>
    </div>`).join('');
}

function cmWireDisciplineFilters() {
  ['Warning','Mistake'].forEach(prefix => {
    ['DateFilter','SearchFilter'].forEach(suffix => {
      const el = document.getElementById(`cm${prefix}${suffix}`);
      if (el && !el.dataset.wired) {
        el.dataset.wired = '1';
        el.addEventListener('input', () => cmRenderDisciplineBoard(prefix === 'Warning' ? 'warning' : 'mistake'));
        el.addEventListener('change', () => cmRenderDisciplineBoard(prefix === 'Warning' ? 'warning' : 'mistake'));
      }
    });
  });
}

function cmAttr(obj) { return cmEsc(JSON.stringify(obj || {})); }

if (typeof window.cmEsc !== 'function') {
  window.cmEsc = function(str) {
    return String(str || '')
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#39;');
  };
}

/* Chart shared options */
function cmChartOpts() {
  return {
    responsive:true, maintainAspectRatio:false,
    plugins: { legend:{ labels:{color:CM.tick, font:{size:CM.fs,family:'Inter'}, boxWidth:10, padding:10} }, tooltip:cmTooltipCfg() },
    scales: {
      x:{ grid:{color:CM.grid}, ticks:{color:CM.tick, font:{size:CM.fs-1}} },
      y:{ beginAtZero:true, grid:{color:CM.grid}, ticks:{color:CM.tick, font:{size:CM.fs-1}} }
    }
  };
}

function cmTooltipCfg() {
  return { backgroundColor:'oklch(0.18 0.04 262)', borderColor:'oklch(0.98 0.005 250 / 0.18)', borderWidth:1, titleColor:'#fff', bodyColor:'rgba(255,255,255,.75)', padding:10, cornerRadius:10 };
}

$(document).ready(function () {
  cmDashLoad();
  setInterval(cmDashLoad, 60000);
});
</script>

<?php
$content = ob_get_clean();
include __DIR__ . '/layout.php';
?>
