<?php
/**
 * Scheduling At A Deficit — Staffing analysis + scheduling software evaluation
 */
$db = getDB();
date_default_timezone_set('America/New_York');
$currentShift = getCurrentShiftBounds();
$shift = $currentShift['shift'];
?>

<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>

<!-- SECTION 1: Hero Header -->
<div style="
    position:relative; border-radius:16px; overflow:hidden; margin-bottom:24px;
    background:linear-gradient(135deg, #1a0505 0%, #3b0a0a 40%, #7f1d1d 100%);
    padding:40px 44px; color:#fff;
">
    <div style="position:absolute; inset:0; opacity:0.05; background-image:
        radial-gradient(circle at 30% 70%, #FCA5A5 1px, transparent 1px),
        radial-gradient(circle at 70% 30%, #FF6B6B 1px, transparent 1px);
        background-size:45px 45px, 55px 55px;
    "></div>
    <div style="position:absolute; top:-40px; right:-40px; width:200px; height:200px; background:radial-gradient(circle, rgba(220,38,38,0.15) 0%, transparent 70%); border-radius:50%;"></div>

    <div style="position:relative; z-index:2;">
        <div style="display:flex; align-items:center; gap:10px; margin-bottom:12px;">
            <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#FCA5A5" stroke-width="2">
                <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
                <line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>
            </svg>
            <span style="font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:1.5px; color:#FCA5A5;">Staffing Intelligence</span>
        </div>
        <h1 style="font-size:32px; font-weight:800; margin-bottom:8px;">Scheduling At A Deficit</h1>
        <p style="font-size:16px; color:rgba(255,255,255,0.6); max-width:600px; line-height:1.5;">
            Evaluate scheduling solutions, analyze staffing patterns, and identify when the department runs below minimum manning — before it happens.
        </p>
        <div style="margin-top:16px; display:flex; gap:8px;">
            <span style="padding:4px 12px; background:rgba(255,255,255,0.08); border:1px solid rgba(255,255,255,0.1); border-radius:20px; font-size:11px; color:rgba(255,255,255,0.5);">
                On Duty: <strong style="color:<?= $shift['color'] ?>;"><?= $shift['unit'] ?></strong>
            </span>
            <span style="padding:4px 12px; background:rgba(255,255,255,0.08); border:1px solid rgba(255,255,255,0.1); border-radius:20px; font-size:11px; color:rgba(255,255,255,0.5);">
                Data: Active911 (Live)
            </span>
        </div>
    </div>
</div>

<!-- SECTION 2: Software Comparison -->
<h2 style="font-size:18px; font-weight:700; color:var(--primary); margin-bottom:4px;">Scheduling Software Evaluation</h2>
<p style="font-size:13px; color:var(--ios-secondary); margin-bottom:16px;">Side-by-side comparison of leading fire/EMS scheduling platforms</p>

<div class="grid grid-2" style="margin-bottom:32px;">
    <!-- Aladtec Card -->
    <div class="card" style="overflow:hidden; border:2px solid var(--ios-border); transition:border-color 0.2s;">
        <div style="background:linear-gradient(135deg, #0B2240, #1B6CB0); padding:20px; text-align:center;">
            <img src="https://tcpsoftware.com/wp-content/uploads/2025/05/cropped-TCP-logo-full-color-150x150.webp" width="48" height="48" style="border-radius:12px; margin-bottom:8px;" onerror="this.style.display='none'">
            <h3 style="font-size:18px; font-weight:800; color:#fff; margin-bottom:2px;">Aladtec</h3>
            <p style="font-size:11px; color:rgba(255,255,255,0.5);">by TCP Software</p>
        </div>
        <div style="padding:20px;">
            <img src="https://tcpsoftware.com/wp-content/uploads/2025/08/Aladtec.png" style="width:100%; border-radius:8px; border:1px solid var(--ios-border); margin-bottom:16px;" onerror="this.style.display='none'">

            <div style="font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.5px; color:var(--ios-tertiary); margin-bottom:8px;">Key Features</div>
            <div style="display:flex; flex-direction:column; gap:6px; margin-bottom:16px;">
                <?php foreach(['24/7 Public Safety Scheduling','Custom Rotation Patterns','Compliance Risk Mitigation','Policy-Based OT Rules','Shift Swap Management','Real-Time Staffing Alerts','Integration Support','Mobile Access'] as $f): ?>
                <div style="display:flex; align-items:center; gap:8px; font-size:13px; color:var(--primary);">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>
                    <?= $f ?>
                </div>
                <?php endforeach; ?>
            </div>

            <div style="font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.5px; color:var(--ios-tertiary); margin-bottom:8px; margin-top:8px;">API & Integration</div>
            <div style="padding:12px; background:var(--ios-bg); border-radius:10px; border:1px solid var(--ios-border); margin-bottom:16px;">
                <div style="display:flex; align-items:center; gap:6px; margin-bottom:8px;">
                    <span style="width:8px; height:8px; border-radius:50%; background:#8CC63F; box-shadow:0 0 6px #8CC63F80;"></span>
                    <span style="font-size:12px; font-weight:700; color:#8CC63F;">Public REST API — Fully Documented</span>
                </div>
                <p style="font-size:12px; color:var(--ios-secondary); line-height:1.5; margin-bottom:8px;">
                    Aladtec offers a comprehensive public JSON API with OAuth 2.0 authentication. Endpoints include member data, schedules, availability, time-off requests, and event calendars. Proven integrations with data warehouses (Snowflake), payroll systems, and custom applications.
                </p>
                <div style="display:flex; gap:6px; flex-wrap:wrap;">
                    <span style="padding:2px 8px; background:#8CC63F15; border:1px solid #8CC63F30; border-radius:10px; font-size:10px; font-weight:600; color:#8CC63F;">OAuth 2.0</span>
                    <span style="padding:2px 8px; background:#8CC63F15; border:1px solid #8CC63F30; border-radius:10px; font-size:10px; font-weight:600; color:#8CC63F;">REST/JSON</span>
                    <span style="padding:2px 8px; background:#8CC63F15; border:1px solid #8CC63F30; border-radius:10px; font-size:10px; font-weight:600; color:#8CC63F;">Snowflake Ready</span>
                    <span style="padding:2px 8px; background:#8CC63F15; border:1px solid #8CC63F30; border-radius:10px; font-size:10px; font-weight:600; color:#8CC63F;">3rd Party Friendly</span>
                </div>
            </div>

            <div style="display:flex; gap:8px;">
                <a href="https://tcpsoftware.com/products/aladtec/" target="_blank" class="btn btn-sm" style="flex:1; text-align:center;">Learn More</a>
                <a href="https://developer.aladtec.com/docs/json_api_docs.html" target="_blank" class="btn btn-sm btn-secondary" style="flex:1; text-align:center;">API Docs</a>
            </div>
        </div>
    </div>

    <!-- Vector Scheduling Card -->
    <div class="card" style="overflow:hidden; border:2px solid var(--ios-border); transition:border-color 0.2s;">
        <div style="background:linear-gradient(135deg, #065f46, #00A6A0); padding:20px; text-align:center;">
            <div style="width:48px; height:48px; background:rgba(255,255,255,0.15); border-radius:12px; display:flex; align-items:center; justify-content:center; margin:0 auto 8px;">
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
            </div>
            <h3 style="font-size:18px; font-weight:800; color:#fff; margin-bottom:2px;">Vector Scheduling</h3>
            <p style="font-size:11px; color:rgba(255,255,255,0.5);">by Vector Solutions (Target Solutions)</p>
        </div>
        <div style="padding:20px;">
            <img src="https://www.vectorsolutions.com/wp-content/uploads/2023/12/fire-scheduling-benefits.webp" style="width:100%; border-radius:8px; border:1px solid var(--ios-border); margin-bottom:16px;" onerror="this.style.display='none'">

            <div style="font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.5px; color:var(--ios-tertiary); margin-bottom:8px;">Key Features</div>
            <div style="display:flex; flex-direction:column; gap:6px; margin-bottom:16px;">
                <?php foreach(['Fire/EMS Crew Shift Scheduling','Mobile-First Shift Acceptance','Automated Callback Management','Real-Time Push Notifications','Swap Management','Part of Vector Training Suite','EMS Scheduling Module','Schedule Tracking & Visibility'] as $f): ?>
                <div style="display:flex; align-items:center; gap:8px; font-size:13px; color:var(--primary);">
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#00A6A0" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>
                    <?= $f ?>
                </div>
                <?php endforeach; ?>
            </div>

            <div style="font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:0.5px; color:var(--ios-tertiary); margin-bottom:8px; margin-top:8px;">API & Integration</div>
            <div style="padding:12px; background:var(--ios-bg); border-radius:10px; border:1px solid var(--ios-border); margin-bottom:16px;">
                <div style="display:flex; align-items:center; gap:6px; margin-bottom:8px;">
                    <span style="width:8px; height:8px; border-radius:50%; background:#FCD34D; box-shadow:0 0 6px #FCD34D80;"></span>
                    <span style="font-size:12px; font-weight:700; color:#FCD34D;">Limited API — Vendor Contact Required</span>
                </div>
                <p style="font-size:12px; color:var(--ios-secondary); line-height:1.5; margin-bottom:8px;">
                    Vector Solutions mentions "open API access" for payroll connectivity but does not publish public API documentation. Integration requires direct vendor engagement through their enterprise sales team. No public developer portal, sandbox, or self-service API keys available.
                </p>
                <div style="display:flex; gap:6px; flex-wrap:wrap;">
                    <span style="padding:2px 8px; background:#FCD34D15; border:1px solid #FCD34D30; border-radius:10px; font-size:10px; font-weight:600; color:#FCD34D;">Closed Ecosystem</span>
                    <span style="padding:2px 8px; background:#FCD34D15; border:1px solid #FCD34D30; border-radius:10px; font-size:10px; font-weight:600; color:#FCD34D;">Payroll Only</span>
                    <span style="padding:2px 8px; background:#FCD34D15; border:1px solid #FCD34D30; border-radius:10px; font-size:10px; font-weight:600; color:#FCD34D;">No Public Docs</span>
                </div>
            </div>

            <div style="display:flex; gap:8px;">
                <a href="https://www.vectorsolutions.com/solutions/vector-scheduling/fire-ems/" target="_blank" class="btn btn-sm" style="flex:1; text-align:center; background:#00A6A0; border-color:#00A6A0;">Learn More</a>
                <button class="btn btn-sm btn-secondary" style="flex:1;" onclick="alert('Contact Vector Solutions for API access')">Request API Access</button>
            </div>
        </div>
    </div>
</div>

<!-- API Integration Assessment -->
<div class="card" style="margin-bottom:32px; border-left:4px solid #8CC63F; padding:24px;">
    <div style="display:flex; align-items:flex-start; gap:16px;">
        <div style="width:44px; height:44px; background:#8CC63F15; border-radius:12px; display:flex; align-items:center; justify-content:center; flex-shrink:0;">
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#8CC63F" stroke-width="2"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>
        </div>
        <div>
            <h3 style="font-size:16px; font-weight:700; color:var(--primary); margin-bottom:6px;">Integration Assessment: Aladtec Has the Clear API Advantage</h3>
            <p style="font-size:13px; color:var(--ios-secondary); line-height:1.6; margin-bottom:12px;">
                For a department building a custom command center portal like this one, <strong>API openness is critical</strong>. Aladtec's fully documented public REST API means we can pull real-time staffing data directly into our dashboards — minimum manning alerts, overtime triggers, and deficit forecasting could all be automated without vendor gatekeeping.
            </p>
            <p style="font-size:13px; color:var(--ios-secondary); line-height:1.6; margin-bottom:12px;">
                Vector Solutions offers a strong product suite (especially with their training integration), but their closed API ecosystem means every integration requires vendor approval and custom development through their team — adding cost, delay, and dependency.
            </p>
            <div style="display:flex; gap:16px; flex-wrap:wrap;">
                <div style="flex:1; min-width:200px; padding:12px; background:var(--ios-bg); border-radius:8px;">
                    <div style="font-size:11px; font-weight:700; color:#8CC63F; margin-bottom:4px;">With Aladtec API we could:</div>
                    <ul style="font-size:12px; color:var(--ios-secondary); line-height:1.6; padding-left:16px; margin:0;">
                        <li>Auto-detect below-minimum shifts in real-time</li>
                        <li>Trigger OT callbacks before gaps occur</li>
                        <li>Feed staffing data into the kiosk dashboard</li>
                        <li>Sync with Snowflake for historical analysis</li>
                    </ul>
                </div>
                <div style="flex:1; min-width:200px; padding:12px; background:var(--ios-bg); border-radius:8px;">
                    <div style="font-size:11px; font-weight:700; color:#FCD34D; margin-bottom:4px;">Vector limitations:</div>
                    <ul style="font-size:12px; color:var(--ios-secondary); line-height:1.6; padding-left:16px; margin:0;">
                        <li>No self-service API — requires vendor engagement</li>
                        <li>Payroll integration only (no scheduling data export)</li>
                        <li>Cannot build custom dashboards from their data</li>
                        <li>Locked into their UI for all scheduling views</li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- SECTION 3: Staffing Deficit Dashboard (Live) -->
<h2 style="font-size:18px; font-weight:700; color:var(--primary); margin-bottom:4px;">Staffing Pattern Analysis</h2>
<p style="font-size:13px; color:var(--ios-secondary); margin-bottom:16px;">Live data from Active911 — identifies when staffing pressure is highest</p>

<div class="grid grid-2" style="margin-bottom:24px;">
    <div class="card">
        <div class="card-header">
            <h2 class="card-title">Shift Load Comparison</h2>
            <p id="shiftLoadSubtitle" style="font-size:11px; color:var(--ios-tertiary); margin-top:2px;">Complete shifts only (7AM–7AM)</p>
        </div>
        <div id="chartShiftLoad" style="height:280px;"></div>
    </div>
    <div class="card">
        <div class="card-header">
            <h2 class="card-title">Peak Hours — Deficit Risk Windows</h2>
            <p style="font-size:11px; color:var(--ios-tertiary); margin-top:2px;">Daily avg vs current shift — bars colored by risk level</p>
        </div>
        <div id="chartPeakHours" style="height:280px;"></div>
    </div>
</div>

<div class="card" style="margin-bottom:32px;">
    <div class="card-header">
        <h2 class="card-title">Unit Utilization — Busiest Apparatus</h2>
        <p id="unitUtilSubtitle" style="font-size:11px; color:var(--ios-tertiary); margin-top:2px;">Complete shifts only (7AM–7AM)</p>
    </div>
    <div id="chartUnitUtil" style="height:300px;"></div>
</div>

<!-- SECTION 4: Known Deficit Scenarios -->
<h2 style="font-size:18px; font-weight:700; color:var(--primary); margin-bottom:4px;">Known Deficit Scenarios</h2>
<p style="font-size:13px; color:var(--ios-secondary); margin-bottom:16px;">Common patterns that trigger below-minimum staffing — API integration pending</p>

<div class="grid grid-4" style="margin-bottom:32px;">
    <?php
    $scenarios = [
        ['icon' => '<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>', 'title' => 'Holiday Staffing', 'desc' => 'Leave request surges around Thanksgiving, Christmas, July 4th, and spring break create predictable gaps.', 'color' => '#DC2626'],
        ['icon' => '<path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/>', 'title' => 'Training Days', 'desc' => 'Companies at training leave coverage gaps in their district. Multi-company training amplifies the deficit.', 'color' => '#1B6CB0'],
        ['icon' => '<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>', 'title' => 'Sick Leave Clusters', 'desc' => 'Flu season (Dec-Feb), COVID waves, and post-holiday illness create unpredictable staffing drops.', 'color' => '#FF9800'],
        ['icon' => '<circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/>', 'title' => 'Special Events', 'desc' => 'Reds, Bengals, FC Cincinnati, concerts at Riverbend — mutual aid draw-down and increased call volume.', 'color' => '#8CC63F'],
    ];
    foreach ($scenarios as $s): ?>
    <div class="card" style="padding:20px; border-left:3px solid <?= $s['color'] ?>;">
        <div style="display:flex; align-items:center; gap:8px; margin-bottom:10px;">
            <div style="width:36px; height:36px; background:<?= $s['color'] ?>15; border-radius:10px; display:flex; align-items:center; justify-content:center;">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="<?= $s['color'] ?>" stroke-width="2"><?= $s['icon'] ?></svg>
            </div>
            <h3 style="font-size:14px; font-weight:700; color:var(--primary);"><?= $s['title'] ?></h3>
        </div>
        <p style="font-size:12px; color:var(--ios-secondary); line-height:1.5; margin-bottom:12px;"><?= $s['desc'] ?></p>
        <span style="display:inline-block; padding:2px 10px; background:var(--ios-bg); border:1px solid var(--ios-border); border-radius:12px; font-size:10px; font-weight:600; color:var(--ios-tertiary);">Coming Soon</span>
    </div>
    <?php endforeach; ?>
</div>

<!-- SECTION 5: AI Scheduling Assistant -->
<div class="card" style="margin-bottom:24px; overflow:hidden;">
    <div style="background:linear-gradient(135deg, #0B2240, #1B6CB0); padding:16px 24px; display:flex; align-items:center; justify-content:space-between;">
        <div>
            <h2 style="font-size:15px; font-weight:700; color:#fff; margin-bottom:2px;">AI Scheduling Assistant</h2>
            <p style="font-size:11px; color:rgba(255,255,255,0.5);">Gemini 3.1 Pro — Ask about minimum manning, overtime rules, and staffing policies</p>
        </div>
        <span style="padding:3px 10px; background:rgba(140,198,63,0.2); border:1px solid rgba(140,198,63,0.3); border-radius:12px; font-size:10px; font-weight:600; color:#8CC63F;">AI Powered</span>
    </div>
    <div style="padding:16px 24px;">
        <div style="display:flex; gap:8px; flex-wrap:wrap; margin-bottom:12px;">
            <button class="btn btn-sm btn-secondary" onclick="askScheduleAI(this.textContent)">What is minimum manning per shift?</button>
            <button class="btn btn-sm btn-secondary" onclick="askScheduleAI(this.textContent)">Overtime callback procedure</button>
            <button class="btn btn-sm btn-secondary" onclick="askScheduleAI(this.textContent)">How many sick days per year?</button>
            <button class="btn btn-sm btn-secondary" onclick="askScheduleAI(this.textContent)">Vacation scheduling rules</button>
        </div>
        <div id="scheduleAiResponse" style="min-height:60px; padding:16px; background:var(--ios-bg); border-radius:12px; border:1px solid var(--ios-border); font-size:13px; color:var(--ios-secondary); line-height:1.6;">
            Click a question above or type your own below to get contract-based answers about staffing and scheduling.
        </div>
        <div style="display:flex; gap:8px; margin-top:12px;">
            <input type="text" id="scheduleAiInput" placeholder="Ask about scheduling, staffing, or overtime..." class="input" style="flex:1;" onkeydown="if(event.key==='Enter')askScheduleAI(this.value)">
            <button class="btn btn-sm" onclick="askScheduleAI(document.getElementById('scheduleAiInput').value)">Ask AI</button>
        </div>
    </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', async function() {
    // Fetch staffing data
    const data = await window.portalAPI('incidents.php?action=list&hours=168');
    if (!data || !data.incidents) return;

    const incidents = data.incidents;
    const shiftRotation = [3, 1, 2]; // anchor: Unit 3 on 2026-03-26
    const anchorDate = new Date('2026-03-26T07:00:00');

    function getShiftForDate(d) {
        const target = new Date(d);
        target.setHours(target.getHours() < 7 ? target.getHours() - 7 : target.getHours());
        const diffDays = Math.floor((target - anchorDate) / 86400000);
        return shiftRotation[((diffDays % 3) + 3) % 3];
    }

    // Group by shift
    const shiftCounts = { 1: 0, 2: 0, 3: 0 };
    const shiftDays = { 1: new Set(), 2: new Set(), 3: new Set() };
    const hourlyAll = new Array(24).fill(0);
    const unitCounts = {};
    const daySet = new Set();
    const hourlyToday = new Array(24).fill(0);
    const now = new Date();
    const shiftStart = new Date(now);
    shiftStart.setHours(7, 0, 0, 0);
    if (now.getHours() < 7) shiftStart.setDate(shiftStart.getDate() - 1);

    // Complete shift boundaries — exclude partial first/last shifts
    const earliest = new Date(Math.min(...incidents.map(i => new Date(i.received_at.replace(' ', 'T')))));
    const completeStart = new Date(earliest);
    completeStart.setHours(7, 0, 0, 0);
    if (completeStart <= earliest) completeStart.setDate(completeStart.getDate() + 1);
    const completeEnd = new Date(now);
    completeEnd.setHours(7, 0, 0, 0);
    if (completeEnd > now) completeEnd.setDate(completeEnd.getDate() - 1);

    incidents.forEach(inc => {
        const dt = new Date(inc.received_at.replace(' ', 'T'));
        const shiftUnit = getShiftForDate(dt);

        // Only count complete shifts for Shift Load chart
        if (dt >= completeStart && dt < completeEnd) {
            shiftCounts[shiftUnit]++;
            // Track distinct shift-days per unit for averaging
            const sd = new Date(dt);
            if (sd.getHours() < 7) sd.setDate(sd.getDate() - 1);
            shiftDays[shiftUnit].add(sd.toDateString());
        }

        hourlyAll[dt.getHours()]++;

        // Track distinct shift-days for averaging
        const shiftDay = new Date(dt);
        if (shiftDay.getHours() < 7) shiftDay.setDate(shiftDay.getDate() - 1);
        daySet.add(shiftDay.toDateString());

        // Count current shift-day incidents by hour
        if (dt >= shiftStart && dt <= now) {
            hourlyToday[dt.getHours()]++;
        }

        // Only count complete shifts for Unit Utilization chart
        if (dt >= completeStart && dt < completeEnd) {
            (inc.units_assigned || '').split(',').forEach(u => {
                u = u.trim();
                if (u) unitCounts[u] = (unitCounts[u] || 0) + 1;
            });
        }
    });

    // Compute daily average per hour
    const numDays = Math.max(daySet.size, 1);
    const hourlyAvg = hourlyAll.map(v => +(v / numDays).toFixed(1));
    const overallAvg = +(hourlyAvg.reduce((a, b) => a + b, 0) / 24).toFixed(1);

    const navy = '#0B2240', blue = '#1B6CB0', teal = '#00A6A0', green = '#8CC63F', red = '#DC2626';
    const shiftColors = { 1: green, 2: blue, 3: red };
    const shiftNames = { 1: 'Unit 1 (Green)', 2: 'Unit 2 (Blue)', 3: 'Unit 3 (Red)' };

    // Update shift load subtitle with actual date range
    const completeDays = Math.round((completeEnd - completeStart) / 86400000);
    const fmtShort = d => d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
    const subEl = document.getElementById('shiftLoadSubtitle');
    if (subEl) subEl.textContent = `${fmtShort(completeStart)} 7AM — ${fmtShort(completeEnd)} 7AM (${completeDays} complete shifts)`;

    // Compute per-shift averages (fair comparison when units have unequal shift counts)
    const shiftAvg = {};
    [1, 2, 3].forEach(u => {
        const numShifts = shiftDays[u].size || 1;
        shiftAvg[u] = Math.round(shiftCounts[u] / numShifts);
    });

    // Shift Load Chart
    const shiftChart = echarts.init(document.getElementById('chartShiftLoad'));
    shiftChart.setOption({
        tooltip: {
            trigger: 'axis',
            formatter: params => {
                const p = params[0];
                const u = [1, 2, 3][p.dataIndex];
                return `<strong>${p.name}</strong><br>Avg: <strong>${shiftAvg[u]}</strong> runs/shift<br>Total: ${shiftCounts[u]} runs (${shiftDays[u].size} shifts)`;
            }
        },
        grid: { top: 20, right: 20, bottom: 30, left: 50 },
        xAxis: { type: 'category', data: Object.values(shiftNames), axisLabel: { color: '#5A6A7E', fontSize: 11 } },
        yAxis: { type: 'value', name: 'Avg Runs / Shift', nameTextStyle: { color: '#999' }, axisLabel: { color: '#5A6A7E' }, splitLine: { lineStyle: { color: '#F0F2F5' } } },
        series: [{
            type: 'bar',
            data: [1, 2, 3].map(u => ({
                value: shiftAvg[u],
                itemStyle: { color: new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:shiftColors[u]},{offset:1,color:shiftColors[u]+'80'}]), borderRadius: [8,8,0,0] }
            })),
            barWidth: '40%',
            label: { show: true, position: 'top', color: '#0B2240', fontWeight: 700, fontSize: 14 },
            animationDuration: 1500, animationEasing: 'elasticOut',
        }]
    });

    // Peak Hours Chart — 7-Day Average (bars) vs Today's Shift (line)
    const peakChart = echarts.init(document.getElementById('chartPeakHours'));
    const maxHourlyAvg = Math.max(...hourlyAvg);
    const hourLabels = Array.from({length:24}, (_,i) => i === 0 ? '12a' : i < 12 ? i+'a' : i === 12 ? '12p' : (i-12)+'p');
    const currentHour = now.getHours();

    peakChart.setOption({
        tooltip: {
            trigger: 'axis',
            formatter: function(params) {
                let tip = '<strong>' + params[0].axisValue + '</strong><br>';
                params.forEach(p => { tip += p.marker + ' ' + p.seriesName + ': <strong>' + p.value + '</strong><br>'; });
                return tip;
            }
        },
        legend: { data: ['7-Day Avg', 'Today'], right: 16, top: 0, textStyle: { color: '#5A6A7E', fontSize: 11 } },
        grid: { top: 28, right: 20, bottom: 30, left: 50 },
        xAxis: { type: 'category', data: hourLabels, axisLabel: { color: '#5A6A7E', fontSize: 9 } },
        yAxis: { type: 'value', axisLabel: { color: '#5A6A7E' }, splitLine: { lineStyle: { color: '#F0F2F5' } } },
        series: [{
            name: '7-Day Avg',
            type: 'bar',
            data: hourlyAvg.map(v => ({
                value: v,
                itemStyle: {
                    color: v > maxHourlyAvg * 0.8 ? red : v > maxHourlyAvg * 0.5 ? '#FF9800' : v > maxHourlyAvg * 0.25 ? blue : '#E8ECF0',
                    borderRadius: [4,4,0,0]
                }
            })),
            barWidth: '55%',
            animationDuration: 1500,
            markLine: {
                silent: true, symbol: 'none',
                lineStyle: { color: '#9CA3AF', type: 'dashed', width: 1 },
                label: { position: 'end', formatter: 'Avg: ' + overallAvg, color: '#9CA3AF', fontSize: 10 },
                data: [{ yAxis: overallAvg }]
            }
        }, {
            name: 'Today',
            type: 'line',
            data: hourlyToday.map((v, i) => (now.getHours() < 7 || i <= currentHour) ? v : null),
            smooth: 0.3,
            symbol: 'circle',
            symbolSize: 6,
            lineStyle: { color: teal, width: 2.5 },
            itemStyle: { color: teal, borderColor: '#fff', borderWidth: 1 },
            connectNulls: false,
            animationDuration: 2000,
        }]
    });

    // Update unit utilization subtitle
    const utilSubEl = document.getElementById('unitUtilSubtitle');
    if (utilSubEl) utilSubEl.textContent = `${fmtShort(completeStart)} 7AM — ${fmtShort(completeEnd)} 7AM (${completeDays} complete shifts)`;

    // Unit Utilization Chart
    const sorted = Object.entries(unitCounts).sort((a,b) => b[1]-a[1]).slice(0, 20);
    const utilChart = echarts.init(document.getElementById('chartUnitUtil'));
    utilChart.setOption({
        tooltip: { trigger: 'axis' },
        grid: { top: 8, right: 40, bottom: 8, left: 8, containLabel: true },
        xAxis: { type: 'value', show: false },
        yAxis: { type: 'category', data: sorted.map(s=>s[0]).reverse(), axisLabel: { color: '#0B2240', fontSize: 11, fontWeight: 600 }, axisLine: { show: false }, axisTick: { show: false } },
        series: [{
            type: 'bar',
            data: sorted.map(s=>s[1]).reverse().map((v,i) => ({
                value: v,
                itemStyle: {
                    color: new echarts.graphic.LinearGradient(0,0,1,0,[
                        {offset:0, color: sorted[sorted.length-1-i][0].startsWith('E') ? red+'60' : sorted[sorted.length-1-i][0].startsWith('M') ? teal+'60' : blue+'60'},
                        {offset:1, color: sorted[sorted.length-1-i][0].startsWith('E') ? red : sorted[sorted.length-1-i][0].startsWith('M') ? teal : blue}
                    ]),
                    borderRadius: [0,6,6,0]
                }
            })),
            barWidth: '55%',
            label: { show: true, position: 'right', color: '#5A6A7E', fontSize: 11 },
            animationDuration: 1500, animationDelay: (i) => i * 50, animationEasing: 'elasticOut',
        }]
    });

    [shiftChart, peakChart, utilChart].forEach(c => window.addEventListener('resize', () => c.resize()));
});

// AI Scheduling Assistant
let schedChartId = 0;
const schedChartColors = ['#1B6CB0','#00A6A0','#8CC63F','#FCD34D','#FF9800','#DC2626'];

window.askScheduleAI = async function(question) {
    if (!question || !question.trim()) return;
    const el = document.getElementById('scheduleAiResponse');
    const input = document.getElementById('scheduleAiInput');
    el.innerHTML = '<div style="display:flex;gap:4px;"><span style="width:6px;height:6px;background:var(--accent);border-radius:50%;animation:tb 1.4s infinite;"></span><span style="width:6px;height:6px;background:var(--accent);border-radius:50%;animation:tb 1.4s infinite 0.2s;"></span><span style="width:6px;height:6px;background:var(--accent);border-radius:50%;animation:tb 1.4s infinite 0.4s;"></span></div>';
    if (input) input.value = '';

    try {
        const resp = await fetch(window.CFD_PORTAL.apiPath + '/contract-chat.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': window.CFD_PORTAL.csrfToken },
            body: JSON.stringify({ question: question.trim(), history: [], document: 'l48-contract', csrf_token: window.CFD_PORTAL.csrfToken })
        });
        const data = await resp.json();
        if (data.answer) {
            let text = data.answer;
            // Extract chart directives using balanced brace matching
            const pendingCharts = [];
            function extractCharts(str) {
                let result = str;
                const marker = '[CHART:';
                let idx = result.indexOf(marker);
                while (idx !== -1) {
                    const typeEnd = result.indexOf(' ', idx + marker.length);
                    if (typeEnd === -1) break;
                    const chartType = result.substring(idx + marker.length, typeEnd).toLowerCase();
                    // Find balanced JSON by counting braces
                    let braceStart = result.indexOf('{', typeEnd);
                    if (braceStart === -1) break;
                    let depth = 0, jsonEnd = -1;
                    for (let i = braceStart; i < result.length; i++) {
                        if (result[i] === '{') depth++;
                        else if (result[i] === '}') { depth--; if (depth === 0) { jsonEnd = i; break; } }
                    }
                    if (jsonEnd === -1) break;
                    const jsonStr = result.substring(braceStart, jsonEnd + 1);
                    // Find the closing ]
                    const directiveEnd = result.indexOf(']', jsonEnd);
                    if (directiveEnd === -1) break;
                    const cid = 'schedChart_' + (++schedChartId);
                    try {
                        let clean = jsonStr.replace(/,\s*}/g, '}').replace(/,\s*]/g, ']');
                        const config = JSON.parse(clean);
                        pendingCharts.push({ id: cid, type: chartType, config });
                        result = result.substring(0, idx) + `__CHART_${cid}__` + result.substring(directiveEnd + 1);
                    } catch(e) {
                        console.warn('Chart JSON parse failed:', e.message, jsonStr.substring(0,100));
                        result = result.substring(0, idx) + result.substring(directiveEnd + 1);
                    }
                    idx = result.indexOf(marker);
                }
                return result;
            }
            text = extractCharts(text);

            // Markdown formatting
            let html = text
                .replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
                .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
                .replace(/\*(.+?)\*/g, '<em>$1</em>')
                .replace(/`([^`]+)`/g, '<code style="background:rgba(0,0,0,0.05);padding:1px 5px;border-radius:4px;font-size:12px;">$1</code>')
                .replace(/^[\s]*[-*]\s+(.+)$/gm, '<li>$1</li>')
                .replace(/\n{2,}/g, '<br><br>')
                .replace(/\n/g, '<br>');

            // Restore chart placeholders
            pendingCharts.forEach(c => {
                html = html.replace(`__CHART_${c.id}__`,
                    `<div style="margin:12px 0;border:1px solid var(--ios-border);border-radius:12px;overflow:hidden;background:#fff;">
                        <div id="${c.id}" style="width:100%;height:260px;"></div>
                    </div>`);
            });

            el.innerHTML = `<div style="color:var(--primary);">${html}</div>`;

            // Render charts
            setTimeout(() => {
                pendingCharts.forEach(c => {
                    const chartEl = document.getElementById(c.id);
                    if (!chartEl || !window.echarts) return;
                    const chart = echarts.init(chartEl);
                    const cfg = c.config;
                    const labels = cfg.labels || [];
                    const ds = cfg.datasets || [];

                    if (c.type === 'bar') {
                        chart.setOption({
                            title: cfg.title ? { text: cfg.title, textStyle: { fontSize: 13, fontWeight: 700, color: '#0B2240' }, left: 'center', top: 8 } : undefined,
                            tooltip: { trigger: 'axis' },
                            grid: { top: cfg.title ? 40 : 12, right: 16, bottom: 30, left: 50 },
                            xAxis: { type: 'category', data: labels, axisLabel: { color: '#5A6A7E', fontSize: 11, rotate: labels.length > 5 ? 20 : 0 } },
                            yAxis: { type: 'value', axisLabel: { color: '#5A6A7E', fontSize: 10 }, splitLine: { lineStyle: { color: '#F0F2F5' } } },
                            series: ds.map((d, i) => ({
                                name: d.name || '', type: 'bar', data: d.values,
                                itemStyle: { color: schedChartColors[i % schedChartColors.length], borderRadius: [6,6,0,0] },
                                barWidth: '50%', animationDuration: 1500, animationEasing: 'elasticOut',
                                label: { show: true, position: 'top', color: '#0B2240', fontWeight: 700, fontSize: 12 },
                            })),
                        });
                    } else if (c.type === 'pie') {
                        const vals = ds[0]?.values || [];
                        chart.setOption({
                            title: cfg.title ? { text: cfg.title, textStyle: { fontSize: 13, fontWeight: 700, color: '#0B2240' }, left: 'center', top: 8 } : undefined,
                            tooltip: { trigger: 'item' },
                            series: [{ type: 'pie', radius: ['35%','65%'], center: ['50%','55%'],
                                data: labels.map((l,i) => ({ name: l, value: vals[i]||0, itemStyle: { color: schedChartColors[i%schedChartColors.length] } })),
                                label: { color: '#0B2240', fontSize: 11 }, itemStyle: { borderRadius: 4, borderColor: '#fff', borderWidth: 2 },
                            }],
                        });
                    }
                    window.addEventListener('resize', () => chart.resize());
                });
            }, 100);
        } else {
            el.textContent = data.error || 'No response';
        }
    } catch (e) {
        el.textContent = 'Failed to reach AI assistant.';
    }
};
</script>
