<?php
/**
 * Coding home — role-aware dashboard: KPIs, auto-generated insights, a production
 * sparkline, and quick-action cards (the launcher for the deeper tools).
 */
require_once __DIR__ . '/../includes/config.php';
$user = require_login('internal');
if (!empty($_SESSION['must_change_pw'])) redirect('/change-password.php');

$pdo = db();
$uid = (int) $user['id'];
$isAud = can('coding.audit');
$isVal = can('coding.validate');
$isSup = can('coding.supervise');
$isCoder = can('coding.work');

$stat = function (string $sql, array $p = []) use ($pdo) {
    try { $s = $pdo->prepare($sql); $s->execute($p); return (int) $s->fetchColumn(); } catch (Throwable $e) { return null; }
};
$scalar = function (string $sql, array $p = []) use ($pdo) {
    try { $s = $pdo->prepare($sql); $s->execute($p); return $s->fetchColumn(); } catch (Throwable $e) { return null; }
};

/* ---- personal ---- */
$myOpen      = $stat("SELECT COUNT(*) FROM coding_inventory WHERE assigned_to=? AND status='pending'", [$uid]);
$myProg      = $stat("SELECT COUNT(*) FROM coding_inventory WHERE assigned_to=? AND status='in_progress'", [$uid]);
$myHold      = $stat("SELECT COUNT(*) FROM coding_inventory WHERE assigned_to=? AND status='hold'", [$uid]);
$myReturned  = $stat("SELECT COUNT(*) FROM coding_inventory WHERE assigned_to=? AND status IN ('pending','in_progress','hold') AND rto_at IS NOT NULL", [$uid]);   // sent back to me for rework
$myDoneToday = $stat("SELECT COUNT(*) FROM coding_inventory WHERE coder_id=? AND status='completed' AND DATE(submitted_at)=CURDATE()", [$uid]);
$myDone7     = $stat("SELECT COUNT(*) FROM coding_inventory WHERE coder_id=? AND status='completed' AND submitted_at >= NOW()-INTERVAL 7 DAY", [$uid]);
$myRebuttable= $stat("SELECT COUNT(*) FROM coding_inventory WHERE coder_id=? AND audit_result='error' AND rebuttal_status='none'", [$uid]);
$oldestOpen  = $scalar("SELECT MIN(uploaded_at) FROM coding_inventory WHERE assigned_to=? AND status='pending'", [$uid]);
try { $myAcc = coding_quality_pct($pdo, $uid, 21); $mySamp = coding_sampling_pct($pdo, $uid); $isNew = coding_coder_tenure_days($pdo, $uid) < CODING_NEW_CODER_DAYS; }
catch (Throwable $e) { $myAcc = null; $mySamp = null; $isNew = false; }

/* ---- auditor ---- */
$awaitAudit = $isAud ? $stat("SELECT COUNT(*) FROM coding_inventory WHERE status='completed' AND in_sample=1 AND audit_status IS NULL AND released_to_billing_at IS NULL") : null;
$rfiDisVal  = $isVal ? $stat("SELECT COUNT(*) FROM coding_inventory WHERE status IN ('rfi','disregard') AND audit_status IS NULL AND released_to_billing_at IS NULL") : null;   // coder-flagged → Validator's To-review (mirrors $REVIEW)
$myRebResolve=$isAud ? $stat("SELECT COUNT(*) FROM coding_inventory WHERE rebuttal_status='raised' AND auditor_id=?", [$uid]) : null;

/* ---- team (supervisor / manager) ---- */
$teamOpen   = $isSup ? $stat("SELECT COUNT(*) FROM coding_inventory WHERE status IN ('pending','in_progress','hold')") : null;
$teamDone   = $isSup ? $stat("SELECT COUNT(*) FROM coding_inventory WHERE status='completed' AND DATE(submitted_at)=CURDATE()") : null;
try { $teamAcc = $isSup ? (function() use ($pdo) {
        $r = $pdo->query("SELECT SUM(audit_opportunities) o, SUM(audit_defects) d FROM coding_inventory WHERE audit_opportunities IS NOT NULL AND audited_at >= NOW()-INTERVAL 21 DAY")->fetch();
        $o = (int)($r['o'] ?? 0); return $o ? round(100*($o-(int)$r['d'])/$o,1) : null; })() : null;
} catch (Throwable $e) { $teamAcc = null; }

/* ---- production sparkline (14d) ---- */
$days = [];
for ($i = 13; $i >= 0; $i--) $days[date('Y-m-d', strtotime("-$i days"))] = 0;
$dq = $isSup
    ? "SELECT DATE(submitted_at) d, COUNT(*) n FROM coding_inventory WHERE status='completed' AND submitted_at >= NOW()-INTERVAL 14 DAY GROUP BY DATE(submitted_at)"
    : "SELECT DATE(submitted_at) d, COUNT(*) n FROM coding_inventory WHERE status='completed' AND coder_id=$uid AND submitted_at >= NOW()-INTERVAL 14 DAY GROUP BY DATE(submitted_at)";
try { foreach ($pdo->query($dq)->fetchAll() as $r) if (isset($days[$r['d']])) $days[$r['d']] = (int) $r['n']; } catch (Throwable $e) {}

/* ---- team scope (supervisor = their team, manager = transitive, sysadmin = all) ---- */
$team = coding_team_scope($pdo, $uid);                       // null = all
$tIn  = $team === null ? '' : (' AND coder_id IN (' . implode(',', $team ?: [0]) . ')');
$tInA = $team === null ? '' : (' AND assigned_to IN (' . implode(',', $team ?: [0]) . ')');
if ($isSup) {   // re-scope the team KPIs to the user's reporting team
    $teamOpen = $stat("SELECT COUNT(*) FROM coding_inventory WHERE status IN ('pending','in_progress','hold') $tInA");
    $teamDone = $stat("SELECT COUNT(*) FROM coding_inventory WHERE status='completed' AND DATE(submitted_at)=CURDATE() $tIn");
    $teamDone7= $stat("SELECT COUNT(*) FROM coding_inventory WHERE status='completed' AND submitted_at>=NOW()-INTERVAL 7 DAY $tIn");
    try { $r = $pdo->query("SELECT SUM(audit_opportunities) o, SUM(audit_defects) d FROM coding_inventory WHERE audit_opportunities IS NOT NULL AND audited_at>=NOW()-INTERVAL 21 DAY $tIn")->fetch();
          $o=(int)($r['o']??0); $teamAcc=$o?round(100*($o-(int)$r['d'])/$o,1):null; } catch (Throwable $e) {}
}
$myDone30 = $stat("SELECT COUNT(*) FROM coding_inventory WHERE coder_id=? AND status='completed' AND submitted_at>=NOW()-INTERVAL 30 DAY", [$uid]);

/* ---- quality-accuracy trend (14d, scoped) ---- */
$qdays = []; for ($i=13;$i>=0;$i--) $qdays[date('Y-m-d', strtotime("-$i days"))] = ['o'=>0,'d'=>0];
$qScope = $isSup ? $tIn : ($isAud ? " AND auditor_id=$uid" : " AND coder_id=$uid");
try { foreach ($pdo->query("SELECT DATE(audited_at) d, SUM(audit_opportunities) o, SUM(audit_defects) df FROM coding_inventory
        WHERE audit_opportunities IS NOT NULL AND audited_at>=NOW()-INTERVAL 14 DAY $qScope GROUP BY DATE(audited_at)")->fetchAll() as $r)
    if (isset($qdays[$r['d']])) $qdays[$r['d']] = ['o'=>(int)$r['o'],'d'=>(int)$r['df']]; } catch (Throwable $e) {}
$accSeries = array_map(fn($v) => $v['o'] ? round(100*($v['o']-$v['d'])/$v['o'],1) : null, $qdays);

/* ---- status distribution (scoped) ---- */
$distScope = $isSup ? $tInA : " AND assigned_to=$uid";
$dist = ['pending'=>0,'in_progress'=>0,'hold'=>0,'completed'=>0,'rfi'=>0,'disregard'=>0];
try { foreach ($pdo->query("SELECT status, COUNT(*) n FROM coding_inventory WHERE 1 $distScope GROUP BY status")->fetchAll() as $r) if (isset($dist[$r['status']])) $dist[$r['status']]=(int)$r['n']; } catch (Throwable $e) {}

/* ---- "needs attention" actionable counts ---- */
$relPending    = ($isSup||$isAud) ? $stat("SELECT COUNT(*) FROM coding_inventory WHERE status='completed' AND COALESCE(audit_status,'') NOT IN ('rfi','disregard') AND released_to_billing_at IS NULL" . ($isSup?$tIn:'')) : null;
$clientPending = ($isSup||$isAud) ? $stat("SELECT COUNT(*) FROM coding_inventory WHERE (CASE WHEN audit_status IN ('rfi','disregard') THEN audit_status ELSE status END) IN ('rfi','disregard') AND client_sent_at IS NULL" . ($isSup?$tIn:'')) : null;

/* ---- team leaderboard (supervisor / manager): each coder's 30d output + accuracy + open ---- */
$leaders = [];
if ($isSup) {
    try { $leaders = $pdo->query("SELECT u.id, u.name,
            SUM(ci.status='completed' AND ci.submitted_at>=NOW()-INTERVAL 30 DAY) done30,
            SUM(ci.status IN ('pending','in_progress','hold')) open_n,
            SUM(CASE WHEN ci.audited_at>=NOW()-INTERVAL 21 DAY THEN ci.audit_opportunities END) opp,
            SUM(CASE WHEN ci.audited_at>=NOW()-INTERVAL 21 DAY THEN ci.audit_defects END) def
        FROM users u JOIN coding_inventory ci ON ci.coder_id=u.id
        WHERE 1=1 " . ($team===null?'':' AND u.id IN ('.implode(',',$team?:[0]).')') . "
        GROUP BY u.id ORDER BY done30 DESC, open_n DESC LIMIT 25")->fetchAll(); } catch (Throwable $e) { $leaders = []; }
}

/* ---- insights (auto narrative) ---- */
$ins = [];
if ($myReturned) $ins[] = ['i'=>'arrow-back-up','c'=>'red','t'=>"<strong>$myReturned</strong> chart".($myReturned>1?'s':'')." sent back to you for rework — clear these first."];
if ($myOpen) {
    $age = $oldestOpen ? floor((time() - strtotime($oldestOpen)) / 86400) : 0;
    $ins[] = ['i'=>'inbox','c'=>'blue','t'=>"<strong>$myOpen</strong> open chart" . ($myOpen>1?'s':'') . " in your queue" . ($age>0 ? " — oldest uploaded <strong>$age day".($age>1?'s':'')."</strong> ago. Code oldest first." : ".")];
}
if ($myProg || $myHold) $ins[] = ['i'=>'player-pause','c'=>'cyan','t'=>"<strong>$myProg</strong> in progress · <strong>$myHold</strong> on hold — finish or resume them from My inventory."];
if ($isCoder && $myAcc !== null) {
    $col = $myAcc>=95?'green':($myAcc>=90?'yellow':'red');
    $ins[] = ['i'=>'target','c'=>$col,'t'=>"Your 3-week DPO accuracy is <strong>$myAcc%</strong> → <strong>$mySamp%</strong> of your completed charts are audited."];
} elseif ($isCoder && $isNew) {
    $ins[] = ['i'=>'sparkles','c'=>'purple','t'=>"You're within your first month — <strong>100%</strong> of your completed charts are audited until you build 3 weeks of quality history."];
}
if ($myRebuttable) $ins[] = ['i'=>'message-report','c'=>'orange','t'=>"<strong>$myRebuttable</strong> audited chart".($myRebuttable>1?'s':'')." flagged with errors you can rebut."];
if ($isAud && $awaitAudit) $ins[] = ['i'=>'checklist','c'=>'orange','t'=>"<strong>$awaitAudit</strong> sampled chart".($awaitAudit>1?'s':'')." awaiting your audit."];
if ($isAud && $myRebResolve) $ins[] = ['i'=>'gavel','c'=>'yellow','t'=>"<strong>$myRebResolve</strong> rebuttal".($myRebResolve>1?'s':'')." waiting for your decision."];
if ($isVal && $rfiDisVal) $ins[] = ['i'=>'shield-check','c'=>'cyan','t'=>"<strong>$rfiDisVal</strong> coder-flagged RFI/Disregard chart".($rfiDisVal>1?'s':'')." to validate."];
if ($isSup && $teamAcc !== null) { $col=$teamAcc>=95?'green':($teamAcc>=90?'yellow':'red'); $ins[] = ['i'=>'users-group','c'=>$col,'t'=>"Team 3-week DPO accuracy: <strong>$teamAcc%</strong>."]; }
if (!$ins) $ins[] = ['i'=>'circle-check','c'=>'green','t'=>"You're all caught up. Upload inventory or pull the next chart to get going."];

/* ---- quick-action cards ---- */
$cards = [];
if (can('coding.upload'))      $cards[] = ['u'=>'/admin/coding-upload.php',   'i'=>'upload',         'c'=>'blue',   't'=>'Upload inventory',    'd'=>'Download a template, fill it, push today\'s charts into your queue.'];
if (can('coding.work'))        $cards[] = ['u'=>'/admin/coding-chart.php?next=1','i'=>'player-play',   'c'=>'green',  't'=>'Get next chart',      'd'=>'Resume your active chart or pull the oldest open one (FIFO).'];
if (can('coding.work'))        $cards[] = ['u'=>'/admin/coding-inventory.php','i'=>'list-check',     'c'=>'cyan',   't'=>'My inventory',        'd'=>'Every chart allocated to you, by status. Resume held charts here.'];
if (can('coding.work'))        $cards[] = ['u'=>'/admin/coding-rebuttals.php','i'=>'message-report', 'c'=>'pink',   't'=>'My rebuttals',        'd'=>'Review audit errors code-by-code and dispute what you disagree with.'];
if (can('coding.audit'))       $cards[] = ['u'=>'/admin/coding-audit.php',    'i'=>'checklist',      'c'=>'orange', 't'=>'Audit',               'd'=>'Code-level DPO audit, RFI / Disregard queues, rebuttals.'];
if (can('coding.supervise')||can('coding.audit')) $cards[] = ['u'=>'/admin/coding-deliverables.php','i'=>'package-export','c'=>'green','t'=>'Deliverables','d'=>'Lists + Excel export: charts sent to billing, and RFI / Disregard charts for the client.'];
if (can('coding.reports'))     $cards[] = ['u'=>'/admin/coding-reports.php',  'i'=>'chart-histogram','c'=>'purple', 't'=>'Reports',             'd'=>'Production and quality (DPO) analytics for you and your team.'];
if (can('coding.supervise'))   $cards[] = ['u'=>'/admin/coding-inventory.php?view=all','i'=>'stack','c'=>'blue','t'=>'All inventory',        'd'=>'See every coder\'s charts across the team.'];
if (can('coding.supervise'))   $cards[] = ['u'=>'/admin/coding-reassign.php', 'i'=>'arrows-exchange','c'=>'teal',   't'=>'Reassign & priority', 'd'=>'Move charts between coders and set TOP priority.'];
if (can('coding.validate'))    $cards[] = ['u'=>'/admin/coding-validate.php','i'=>'shield-check','c'=>'cyan','t'=>'Validate','d'=>'Validate RFI / Disregard charts and send them back to any coder in the coding vertical.'];
if (can('coding.supervise')||can('coding.audit')) $cards[] = ['u'=>'/admin/coding-rto.php','i'=>'rotate','c'=>'orange','t'=>'RTO — rework','d'=>'Send RFI / Disregard charts back to a coder after client clarification.'];
if (can('coding.access.manage'))$cards[]= ['u'=>'/admin/coding-access.php','i'=>'lock-cog','c'=>'indigo','t'=>'Coder access','d'=>'Align coders to a specific client » process » facility. Managers assign new clients; supervisors deepen within a client.'];
if (can('coding.cpt.manage'))  $cards[] = ['u'=>'/admin/coding-cpt.php',      'i'=>'list-numbers',   'c'=>'yellow', 't'=>'CPT validation',      'd'=>'Per-facility/provider CPT sets and coder-added codes.'];
if (can('coding.supervise'))   $cards[] = ['u'=>'/admin/coding-reasons.php',  'i'=>'list-details',   'c'=>'orange', 't'=>'Secondary reasons',    'd'=>'Add / edit / delete the RFI and Disregard reason lists used by coders and validators.'];
if (can('coding.supervise'))   $cards[] = ['u'=>'/admin/coding-modifiers.php','i'=>'adjustments-alt', 'c'=>'purple', 't'=>'CPT modifiers',         'd'=>'Add / edit / delete the modifier list coders attach to a CPT (25, 59, GT …).'];
if (can('coding.supervise'))   $cards[] = ['u'=>'/admin/coding-alf.php',      'i'=>'arrows-exchange','c'=>'azure',  't'=>'CPT → ALF map',        'd'=>'Add / edit / delete the CPT→ALF pairs billed as “CPT/ALF” (e.g. 99202/99341).'];
if (can('coding.supervise')||can('coding.reference')) $cards[] = ['u'=>'/admin/coding-hierarchy.php','i'=>'sitemap','c'=>'lime','t'=>'Hierarchy &amp; facilities','d'=>'Browse the tree; add facilities and link providers to them.'];
if (can('coding.supervise')||can('coding.reference')) $cards[] = ['u'=>'/admin/coding-providers.php','i'=>'user-plus','c'=>'teal','t'=>'Providers','d'=>'Add and edit providers (the master list used across facilities).'];
if (can('coding.reference'))   $cards[] = ['u'=>'/admin/coding-reference.php', 'i'=>'database',      'c'=>'red',    't'=>'Reference data',      'd'=>'ICD / CPT / modifier reference and bulk imports.'];

/* KPI tiles (role-aware) */
$accCol = fn($a) => $a===null?'secondary':($a>=95?'green':($a>=90?'yellow':'red'));
$tiles = [];
$tiles[] = ['l'=>'Open','v'=>$myOpen,'c'=>'blue','i'=>'inbox'];
$tiles[] = ['l'=>'In progress','v'=>$myProg,'c'=>'cyan','i'=>'player-play'];
$tiles[] = ['l'=>'On hold','v'=>$myHold,'c'=>'yellow','i'=>'player-pause'];
if ($isCoder) $tiles[] = ['l'=>'Sent back','v'=>$myReturned,'c'=>'red','i'=>'arrow-back-up'];
$tiles[] = ['l'=>'Completed today','v'=>$myDoneToday,'c'=>'green','i'=>'circle-check'];
if ($isCoder) $tiles[] = ['l'=>'Completed 7d','v'=>$myDone7,'c'=>'teal','i'=>'calendar-check'];
if ($isCoder) $tiles[] = ['l'=>'My accuracy (DPO)','v'=>($myAcc===null?'—':$myAcc.'%'),'c'=>$accCol($myAcc),'i'=>'target'];
if ($isAud)   $tiles[] = ['l'=>'Awaiting audit','v'=>$awaitAudit,'c'=>'orange','i'=>'checklist'];
if ($isSup)   $tiles[] = ['l'=>'Team open','v'=>$teamOpen,'c'=>'indigo','i'=>'users-group'];
if ($isSup)   $tiles[] = ['l'=>'Team done today','v'=>$teamDone,'c'=>'green','i'=>'users-check'];
if ($isSup)   $tiles[] = ['l'=>'Team accuracy (DPO)','v'=>($teamAcc===null?'—':$teamAcc.'%'),'c'=>$accCol($teamAcc),'i'=>'target-arrow'];
if (($isSup||$isAud) && $relPending !== null) $tiles[] = ['l'=>'To release (billing)','v'=>$relPending,'c'=>'azure','i'=>'send'];
if (($isSup||$isAud) && $clientPending !== null) $tiles[] = ['l'=>'To send (client)','v'=>$clientPending,'c'=>'orange','i'=>'mail-forward'];

$pageTitle = 'Coding';
require __DIR__ . '/../includes/header.php';
?>
<div class="container-xl">
    <div class="welcome-hero" style="background:linear-gradient(135deg,#0e7490 0%,#1e3a8a 50%,#4c1d95 100%);color:#fff;border-radius:14px;padding:22px 26px;margin:16px 0;position:relative;overflow:hidden">
        <div style="position:absolute;inset:0;background:radial-gradient(600px 200px at 0% 0%,rgba(56,189,248,.25),transparent 60%),radial-gradient(400px 200px at 100% 100%,rgba(168,85,247,.25),transparent 60%);pointer-events:none"></div>
        <div style="position:relative">
            <div style="font-size:1.5rem;font-weight:700">Medical Coding — welcome, <?= e(explode(' ', $user['name'])[0]) ?> 👋</div>
            <div style="color:rgba(255,255,255,.8);margin-top:4px">
                <i class="ti ti-shield-check"></i> <?= e(implode(', ', current_user_role_codes()) ?: 'coding') ?>
                &nbsp;·&nbsp; <i class="ti ti-clock"></i> <?= e(date('D, M j · H:i')) ?>
                <?php if ($isCoder && $mySamp !== null): ?>&nbsp;·&nbsp; <i class="ti ti-target"></i> sampling <?= (int)$mySamp ?>%<?php endif; ?>
            </div>
            <?php if (can('coding.work')): ?>
            <div class="mt-3 d-flex gap-2 flex-wrap">
                <a href="<?= e(url('/admin/coding-chart.php?next=1')) ?>" class="btn btn-light"><i class="ti ti-player-play me-1"></i>Get next chart</a>
                <?php if (can('coding.upload')): ?><a href="<?= e(url('/admin/coding-upload.php')) ?>" class="btn btn-outline-light"><i class="ti ti-upload me-1"></i>Upload inventory</a><?php endif; ?>
            </div>
            <?php endif; ?>
        </div>
    </div>
</div>

<div class="page-body"><div class="container-xl">
    <div class="row row-deck row-cards mb-3">
        <?php foreach ($tiles as $t): ?>
        <div class="col-6 col-md-3 col-xl"><div class="card kpi-tile"><div class="card-body py-3">
            <div class="d-flex align-items-center mb-2"><span class="bg-<?= e($t['c']) ?>-lt text-<?= e($t['c']) ?> avatar avatar-sm me-2"><i class="ti ti-<?= e($t['i']) ?>"></i></span><div class="stat-label"><?= e($t['l']) ?></div></div>
            <div class="stat-value"><?= is_int($t['v'])?number_format($t['v']):e((string)$t['v']) ?></div>
        </div></div></div>
        <?php endforeach; ?>
    </div>

    <div class="row row-deck row-cards mb-3">
        <div class="col-lg-7"><div class="card h-100">
            <div class="card-header py-2"><h3 class="card-title small mb-0"><i class="ti ti-bulb me-1 text-warning"></i><?= $isSup?'Team focus':'Your focus' ?></h3></div>
            <div class="card-body p-0">
                <?php foreach ($ins as $x): ?>
                <div class="d-flex align-items-center gap-2 px-3" style="padding:10px 0;border-bottom:1px solid var(--m-border)">
                    <span class="avatar avatar-sm bg-<?= e($x['c']) ?>-lt text-<?= e($x['c']) ?>"><i class="ti ti-<?= e($x['i']) ?>"></i></span>
                    <div class="small"><?= $x['t'] ?></div>
                </div>
                <?php endforeach; ?>
            </div>
        </div></div>
        <div class="col-lg-5"><div class="card h-100">
            <div class="card-header py-2"><h3 class="card-title small mb-0"><i class="ti ti-activity me-1 text-primary"></i><?= $isSup?'Team production':'My production' ?> · 14 days</h3></div>
            <div class="card-body p-2"><div id="prod" style="min-height:170px"></div></div>
        </div></div>
    </div>

    <div class="row row-deck row-cards mb-3">
        <div class="col-lg-5"><div class="card h-100">
            <div class="card-header py-2"><h3 class="card-title small mb-0"><i class="ti ti-award me-1 text-purple"></i><?= $isSup?'Team':'My' ?> accuracy (DPO) · 14 days</h3></div>
            <div class="card-body p-2"><div id="qual" style="min-height:170px"></div></div>
        </div></div>
        <div class="col-lg-3"><div class="card h-100">
            <div class="card-header py-2"><h3 class="card-title small mb-0"><i class="ti ti-chart-donut me-1 text-blue"></i><?= $isSup?'Team':'My' ?> status mix</h3></div>
            <div class="card-body p-2"><div id="mix" style="min-height:170px"></div></div>
        </div></div>
        <div class="col-lg-4"><div class="card h-100">
            <div class="card-header py-2"><h3 class="card-title small mb-0"><i class="ti ti-alert-circle me-1 text-orange"></i>Needs attention</h3></div>
            <div class="list-group list-group-flush">
            <?php
            $attn = [];
            if ($isCoder && $myReturned)         $attn[] = ['danger','arrow-back-up',$myReturned.' chart(s) sent back to you — rework','/admin/coding-inventory.php?returned=1'];
            if ($isCoder && ($myProg||$myHold)) $attn[] = ['warning','player-pause',($myProg+$myHold).' chart(s) in progress / on hold','/admin/coding-inventory.php'];
            if ($isCoder && $myRebuttable)       $attn[] = ['pink','message-report',$myRebuttable.' audited error(s) you can rebut','/admin/coding-rebuttals.php'];
            if ($isAud && $awaitAudit)           $attn[] = ['orange','checklist',$awaitAudit.' sampled chart(s) awaiting audit','/admin/coding-audit.php?queue=audit&sample=1&astate=todo'];
            if ($isVal && $rfiDisVal)            $attn[] = ['cyan','shield-check',$rfiDisVal.' coder-flagged RFI/Disregard to validate','/admin/coding-validate.php?q=toreview'];
            if ($isAud && $myRebResolve)         $attn[] = ['yellow','gavel',$myRebResolve.' rebuttal(s) to decide','/admin/coding-audit.php?queue=rebuttals'];
            if (($isSup||$isAud) && $relPending) $attn[] = ['azure','send',$relPending.' completed chart(s) to send to billing','/admin/coding-audit.php?queue=audit'];
            if (($isSup||$isAud) && $clientPending) $attn[] = ['orange','mail-forward',$clientPending.' RFI/Disregard to send to client','/admin/coding-deliverables.php?view=rfi'];
            if (!$attn) $attn[] = ['green','circle-check','Nothing pending — all caught up.',''];
            foreach ($attn as [$c2,$i2,$txt,$lnk]): ?>
                <?php if ($lnk): ?><a href="<?= e(url($lnk)) ?>" class="list-group-item list-group-item-action d-flex align-items-center gap-2 py-2">
                    <span class="avatar avatar-sm bg-<?= e($c2) ?>-lt text-<?= e($c2) ?>"><i class="ti ti-<?= e($i2) ?>"></i></span><span class="small"><?= e($txt) ?></span>
                    <i class="ti ti-chevron-right ms-auto text-secondary"></i></a>
                <?php else: ?><div class="list-group-item d-flex align-items-center gap-2 py-2">
                    <span class="avatar avatar-sm bg-<?= e($c2) ?>-lt text-<?= e($c2) ?>"><i class="ti ti-<?= e($i2) ?>"></i></span><span class="small"><?= e($txt) ?></span></div><?php endif; ?>
            <?php endforeach; ?>
            </div>
        </div></div>
    </div>

    <?php if ($leaders): ?>
    <div class="card mb-3"><div class="card-header py-2"><h3 class="card-title small mb-0"><i class="ti ti-trophy me-1 text-yellow"></i>Team performance · last 30 days</h3>
        <div class="card-actions"><a href="<?= e(url('/admin/coding-reports.php?report=production&by=coder')) ?>" class="small">Full reports →</a></div></div>
        <div class="table-responsive"><table class="table table-sm table-vcenter card-table mb-0">
            <thead><tr><th>Coder</th><th class="text-end">Completed 30d</th><th class="text-end">Open now</th><th class="text-end">Accuracy (DPO)</th></tr></thead>
            <tbody>
            <?php foreach ($leaders as $L): $o=(int)$L['opp']; $a=$o?round(100*($o-(int)$L['def'])/$o,1):null; ?>
                <tr><td><strong><?= e($L['name']) ?></strong></td>
                    <td class="text-end"><?= (int)$L['done30'] ?></td>
                    <td class="text-end text-secondary"><?= (int)$L['open_n'] ?></td>
                    <td class="text-end"><?php if($a===null): ?><span class="text-secondary">—</span><?php else: ?><span class="badge bg-<?= $accCol($a) ?>-lt"><?= $a ?>%</span><?php endif; ?></td></tr>
            <?php endforeach; ?>
            </tbody></table></div></div>
    <?php endif; ?>

    <div class="row row-cards">
        <?php foreach ($cards as $c): ?>
        <div class="col-sm-6 col-lg-4 col-xl-3">
            <a href="<?= e(url($c['u'])) ?>" class="text-decoration-none">
                <div class="card kpi-tile h-100"><div class="card-body">
                    <div class="d-flex align-items-center mb-2">
                        <span class="bg-<?= e($c['c']) ?>-lt text-<?= e($c['c']) ?> avatar me-2"><i class="ti ti-<?= e($c['i']) ?>"></i></span>
                        <div class="fw-bold"><?= e($c['t']) ?></div>
                    </div>
                    <div class="text-secondary small"><?= e($c['d']) ?></div>
                </div></div>
            </a>
        </div>
        <?php endforeach; ?>
    </div>
</div></div>

<script>
(function(){
  var labels=<?= json_encode(array_map(fn($d)=>date('M j',strtotime($d)), array_keys($days))) ?>;
  var vals=<?= json_encode(array_values($days)) ?>;
  function dark(){ return document.documentElement.getAttribute('data-bs-theme')==='dark'; }
  if(!window.ApexCharts) return;
  new ApexCharts(document.querySelector('#prod'),{
    chart:{type:'area',height:170,sparkline:{enabled:false},toolbar:{show:false},fontFamily:'inherit',background:'transparent'},
    theme:{mode:dark()?'dark':'light'}, series:[{name:'Completed',data:vals}], colors:['#2fb344'],
    stroke:{curve:'smooth',width:2}, fill:{type:'gradient',gradient:{opacityFrom:.4,opacityTo:.05}},
    dataLabels:{enabled:false}, xaxis:{categories:labels,labels:{rotate:0}}, grid:{borderColor:dark()?'#1e2a44':'#eef0f3'}
  }).render();

  /* quality (DPO accuracy) trend — nulls render as gaps */
  var acc=<?= json_encode(array_values($accSeries)) ?>;
  var qel=document.querySelector('#qual');
  if(qel){ new ApexCharts(qel,{
    chart:{type:'line',height:170,toolbar:{show:false},fontFamily:'inherit',background:'transparent'},
    theme:{mode:dark()?'dark':'light'}, series:[{name:'Accuracy %',data:acc}], colors:['#7048e8'],
    stroke:{curve:'smooth',width:2}, markers:{size:3}, dataLabels:{enabled:false},
    xaxis:{categories:labels,labels:{rotate:0}}, yaxis:{min:0,max:100,labels:{formatter:function(v){return Math.round(v)+'%';}}},
    tooltip:{y:{formatter:function(v){return v==null?'—':v+'%';}}}, grid:{borderColor:dark()?'#1e2a44':'#eef0f3'}
  }).render(); }

  /* status mix donut */
  var mixV=<?= json_encode(array_values($dist)) ?>, mixL=<?= json_encode(array_map(fn($k)=>str_replace('_',' ',$k), array_keys($dist))) ?>;
  var mel=document.querySelector('#mix');
  if(mel && mixV.reduce(function(a,b){return a+b;},0)>0){ new ApexCharts(mel,{
    chart:{type:'donut',height:170,fontFamily:'inherit',background:'transparent'}, theme:{mode:dark()?'dark':'light'},
    series:mixV, labels:mixL, colors:['#206bc4','#17a2b8','#f59f00','#2fb344','#f76707','#d6336c'],
    legend:{position:'bottom',fontSize:'11px'}, dataLabels:{enabled:false}, stroke:{width:0}
  }).render(); }
  else if(mel){ mel.innerHTML='<div class="text-secondary text-center small py-4">No charts in scope.</div>'; }
})();
</script>
<?php require __DIR__ . '/../includes/footer.php'; ?>
