<?php
session_start();
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
    header('Location: login.php');
    exit;
}

$page_title = 'Live Calls';
$current_page = 'live_calls.php';

ob_start();
?>
<style>
.live-shell { display: grid; gap: 18px; }
.live-hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 16px;
    align-items: center;
    background: #101827;
    color: #fff;
    border-radius: 8px;
    padding: 22px;
    border: 1px solid rgba(255,255,255,.08);
    box-shadow: 0 14px 36px rgba(15,23,42,.18);
}
.live-hero h2 { margin: 0; font-weight: 800; letter-spacing: 0; }
.live-hero p { margin: 5px 0 0; color: #cbd5e1; }
.hero-actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.live-card {
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 18px;
    box-shadow: 0 10px 24px rgba(15,23,42,.07);
}
.live-grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(340px, .95fr); gap: 18px; }
.live-title { font-size: 18px; font-weight: 800; color: #111827; margin: 0; }
.muted { color: #64748b; }
.status-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.status-tile {
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 14px;
    background: #f8fafc;
    min-height: 92px;
}
.status-tile span { display: block; font-size: 12px; color: #64748b; font-weight: 700; text-transform: uppercase; }
.status-tile strong { display: block; margin-top: 8px; font-size: 18px; color: #0f172a; }
.pill { display:inline-flex; align-items:center; gap:7px; padding:7px 10px; border-radius:999px; font-weight:800; font-size:13px; }
.pill-on { background:#dcfce7; color:#166534; }
.pill-off { background:#fee2e2; color:#991b1b; }
.pill-warn { background:#fef3c7; color:#92400e; }
.metric-row { display:grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap:10px; margin-top:14px; }
.metric { background:#f8fafc; border:1px solid #e5e7eb; border-radius:8px; padding:13px; min-width:0; }
.metric span { display:block; color:#64748b; font-size:12px; font-weight:700; text-transform:uppercase; }
.metric strong { display:block; color:#0f172a; font-size:20px; margin-top:5px; overflow-wrap:anywhere; }
.setting-grid { display:grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap:12px; }
.setting-grid .full { grid-column:1 / -1; }
.call-actions { display:flex; gap:9px; flex-wrap:wrap; margin-top:16px; }
.queue-item { display:flex; justify-content:space-between; gap:12px; padding:12px 0; border-bottom:1px solid #e5e7eb; }
.queue-item:last-child { border-bottom:none; }
.setup-list { display:grid; gap:9px; margin-top:12px; }
.setup-item { display:flex; justify-content:space-between; gap:12px; align-items:center; border:1px solid #e5e7eb; border-radius:8px; padding:10px 12px; background:#fff; }
.setup-item strong { color:#111827; }
.video-grid { display:grid; grid-template-columns: 1fr 1fr; gap:12px; margin-top:14px; }
.video-box { height:220px; background:#0f172a; border-radius:8px; overflow:hidden; display:flex; align-items:center; justify-content:center; color:#fff; }
.toast-line { min-height: 44px; }
.call-debug {
    margin-top: 14px;
    background: #0f172a;
    color: #dbeafe;
    border-radius: 8px;
    padding: 12px;
    font-family: Consolas, Monaco, monospace;
    font-size: 12px;
    max-height: 170px;
    overflow: auto;
    white-space: pre-wrap;
}
.answer-note { margin-top: 10px; font-weight: 700; color: #334155; }
@media (max-width: 1100px) {
    .live-grid, .status-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 768px) {
    .live-hero, .live-grid, .status-grid, .setting-grid, .metric-row, .video-grid { grid-template-columns: 1fr; }
    .hero-actions { justify-content: flex-start; }
}
</style>

<div class="live-shell">
    <div class="live-hero">
        <div>
            <h2><i class="fas fa-video me-2 text-info"></i>Live Audio / Video Calls</h2>
            <p>Guruji online control, wallet billing, Agora call join, queue, and push notification status.</p>
        </div>
        <div class="hero-actions">
            <button class="btn btn-warning" onclick="enableRingSound()">
                <i class="fas fa-volume-high me-1"></i>Enable Ring Sound
            </button>
            <button class="btn btn-success" onclick="quickGuruStatus(true)">
                <i class="fas fa-toggle-on me-1"></i>Guruji Online
            </button>
            <button class="btn btn-outline-light" onclick="quickGuruStatus(false)">
                <i class="fas fa-toggle-off me-1"></i>Guruji Offline
            </button>
            <button class="btn btn-info text-white" onclick="loadLiveCalls()">
                <i class="fas fa-sync-alt me-1"></i>Refresh
            </button>
        </div>
    </div>

    <div id="notice" class="toast-line"></div>

    <div class="status-grid" id="statusGrid">
        <div class="status-tile"><span>System</span><strong>Loading</strong></div>
        <div class="status-tile"><span>Guruji</span><strong>Loading</strong></div>
        <div class="status-tile"><span>Agora</span><strong>Loading</strong></div>
        <div class="status-tile"><span>Push</span><strong>Loading</strong></div>
    </div>

    <div class="live-grid">
        <div class="live-card">
            <div class="d-flex justify-content-between align-items-start gap-2 flex-wrap">
                <div>
                    <h3 class="live-title">Current Call</h3>
                    <div class="muted">User balance, time, charge and extension are updated automatically.</div>
                </div>
                <button class="btn btn-outline-secondary btn-sm" onclick="sendTestPush()">
                    <i class="fas fa-bell me-1"></i>Test Push
                </button>
            </div>
            <div id="currentCall" class="mt-3"></div>
        </div>

        <div class="live-card">
            <h3 class="live-title">Setup Checklist</h3>
            <div id="setupChecklist" class="setup-list"></div>
        </div>
    </div>

    <div class="live-grid">
        <div class="live-card">
            <h3 class="live-title">Waiting Queue</h3>
            <div id="queueList" class="mt-2"></div>
        </div>

        <div class="live-card">
            <h3 class="live-title">System Settings</h3>
            <form id="settingsForm" class="mt-3">
                <div class="setting-grid">
                    <div>
                        <label class="form-label fw-bold">Live Call System</label>
                        <select class="form-select" name="live_call_system_enabled">
                            <option value="on">Enabled</option>
                            <option value="off">Disabled</option>
                        </select>
                    </div>
                    <div>
                        <label class="form-label fw-bold">Guruji Status</label>
                        <select class="form-select" name="guru_online">
                            <option value="on">Online</option>
                            <option value="off">Offline</option>
                        </select>
                    </div>
                    <div>
                        <label class="form-label fw-bold">Audio Call</label>
                        <select class="form-select" name="live_call_audio_enabled">
                            <option value="on">Enabled</option>
                            <option value="off">Disabled</option>
                        </select>
                    </div>
                    <div>
                        <label class="form-label fw-bold">Video Call</label>
                        <select class="form-select" name="live_call_video_enabled">
                            <option value="on">Enabled</option>
                            <option value="off">Disabled</option>
                        </select>
                    </div>
                    <div>
                        <label class="form-label fw-bold">First Call Min Balance</label>
                        <input class="form-control" type="number" name="live_call_min_first_call_balance" min="0" step="1">
                    </div>
                    <div>
                        <label class="form-label fw-bold">Normal Min Balance</label>
                        <input class="form-control" type="number" name="live_call_min_wallet_balance" min="0" step="1">
                    </div>
                    <div>
                        <label class="form-label fw-bold">Audio Rate / Min</label>
                        <input class="form-control" type="number" name="live_call_audio_rate_per_minute" min="0" step="1">
                    </div>
                    <div>
                        <label class="form-label fw-bold">Video Rate / Min</label>
                        <input class="form-control" type="number" name="live_call_video_rate_per_minute" min="0" step="1">
                    </div>
                    <div>
                        <label class="form-label fw-bold">Billing Tick Seconds</label>
                        <input class="form-control" type="number" name="live_call_tick_seconds" min="5" step="5">
                    </div>
                    <div>
                        <label class="form-label fw-bold">Agora App ID</label>
                        <input class="form-control" type="text" name="live_call_agora_app_id" placeholder="Agora App ID">
                    </div>
                    <div class="full">
                        <label class="form-label fw-bold">Agora App Certificate</label>
                        <input class="form-control" type="text" name="live_call_agora_app_certificate" placeholder="Required only when token auth is enabled">
                        <small class="muted">Token auth enabled ho to App Certificate save karo. Certificate browser/app me expose nahi hota.</small>
                    </div>
                    <div>
                        <label class="form-label fw-bold">OneSignal App ID</label>
                        <input class="form-control" type="text" name="onesignal_app_id" placeholder="OneSignal App ID">
                    </div>
                    <div>
                        <label class="form-label fw-bold">OneSignal REST API Key</label>
                        <input class="form-control" type="password" name="onesignal_rest_api_key" placeholder="Server REST API Key">
                    </div>
                </div>
                <button class="btn btn-primary mt-3" type="submit">
                    <i class="fas fa-save me-1"></i>Save Settings
                </button>
            </form>
        </div>
    </div>
</div>

<script src="https://download.agora.io/sdk/release/AgoraRTC_N.js"></script>
<script>
const apiUrl = '../api/live_call_admin.php';
let lastData = null;
let agoraClient = null;
let localTracks = [];
let joinedSessionId = null;
let audioContext = null;
let ringTimer = null;
let lastRingingSessionId = null;
let soundEnabled = false;
let activeSessionCache = {};
let answerInProgress = false;

window.onerror = function(message, source, lineno, colno, error) {
    logDebug(`JS error: ${message} at ${lineno}:${colno}`);
};

window.onunhandledrejection = function(event) {
    logDebug(`Promise error: ${event.reason?.message || event.reason || 'Unknown error'}`);
};

function rupee(value) {
    return 'Rs. ' + Number(value || 0).toFixed(2);
}

function secondsToClock(seconds) {
    seconds = Number(seconds || 0);
    const m = Math.floor(seconds / 60).toString().padStart(2, '0');
    const s = Math.floor(seconds % 60).toString().padStart(2, '0');
    return `${m}:${s}`;
}

function isOn(value) {
    return ['1', 'on', 'true', 'yes', 'enabled'].includes(String(value || '').toLowerCase());
}

function showNotice(message, type = 'success') {
    const el = document.getElementById('notice');
    el.innerHTML = `<div class="alert alert-${type} mb-0">${message}</div>`;
    setTimeout(() => { if (el.innerHTML.includes(message)) el.innerHTML = ''; }, 5000);
}

function logDebug(message) {
    const text = `[${new Date().toLocaleTimeString()}] ${message}`;
    console.log(text);
    const el = document.getElementById('callDebug');
    if (el) {
        el.textContent = `${text}\n${el.textContent || ''}`.slice(0, 5000);
    }
}

function setAnswerStatus(message, type = 'info') {
    const el = document.getElementById('answerStatus');
    if (el) {
        el.className = `answer-note text-${type === 'danger' ? 'danger' : type === 'success' ? 'success' : 'primary'}`;
        el.textContent = message;
    }
    logDebug(message);
}

async function enableRingSound() {
    try {
        audioContext = audioContext || new (window.AudioContext || window.webkitAudioContext)();
        if (audioContext.state === 'suspended') await audioContext.resume();
        soundEnabled = true;
        showNotice('Ring sound enabled. Incoming call par sound aayega.');
        playRingOnce();
        if ('Notification' in window && Notification.permission === 'default') {
            await Notification.requestPermission();
        }
    } catch (e) {
        showNotice('Ring sound enable nahi hua: ' + e.message, 'warning');
    }
}

function playRingOnce() {
    if (!soundEnabled || !audioContext) return;
    const osc = audioContext.createOscillator();
    const gain = audioContext.createGain();
    osc.type = 'sine';
    osc.frequency.setValueAtTime(880, audioContext.currentTime);
    gain.gain.setValueAtTime(0.0001, audioContext.currentTime);
    gain.gain.exponentialRampToValueAtTime(0.35, audioContext.currentTime + 0.03);
    gain.gain.exponentialRampToValueAtTime(0.0001, audioContext.currentTime + 0.45);
    osc.connect(gain);
    gain.connect(audioContext.destination);
    osc.start();
    osc.stop(audioContext.currentTime + 0.5);
}

function startRing(session) {
    if (!session || joinedSessionId === Number(session.id)) return;
    if (lastRingingSessionId !== Number(session.id)) {
        lastRingingSessionId = Number(session.id);
        if ('Notification' in window && Notification.permission === 'granted') {
            new Notification('Incoming Live Call', {
                body: `${session.user_name || 'User'} ${session.call_type} call kar raha hai`,
                tag: `live-call-${session.id}`
            });
        }
        showNotice('Incoming call aa rahi hai. Uthao & Join dabao.', 'warning');
    }
    if (ringTimer) return;
    playRingOnce();
    ringTimer = setInterval(playRingOnce, 1200);
}

function stopRing() {
    if (ringTimer) clearInterval(ringTimer);
    ringTimer = null;
}

function pushMessage(push) {
    if (!push) return '';
    const code = push.onesignal_http_code ? ` HTTP ${push.onesignal_http_code}` : '';
    const body = push.onesignal_response ? ` - ${push.onesignal_response}` : '';
    const err = push.onesignal_error ? ` - ${push.onesignal_error}` : '';
    return `${code}${err}${body}`;
}

async function apiRequest(payload) {
    logDebug(`API POST ${payload.action || 'unknown'} started`);
    const res = await fetch(apiUrl, {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(payload)
    });
    const text = await res.text();
    logDebug(`API POST ${payload.action || 'unknown'} HTTP ${res.status}: ${text.slice(0, 350)}`);
    let data = {};
    try {
        data = JSON.parse(text);
    } catch (e) {
        throw new Error(text || 'Invalid API response');
    }
    if (!data.success) throw new Error(data.message || 'Action failed');
    return data;
}

async function postAction(payload, successMessage = '') {
    try {
        const data = await apiRequest(payload);
        const detail = data.push ? pushMessage(data.push) : '';
        showNotice((successMessage || data.message || 'Done') + detail);
    } catch (e) {
        showNotice(e.message, 'danger');
    }
    await loadLiveCalls();
}

async function quickGuruStatus(online) {
    await postAction({
        action: 'set_guru_status',
        live_call_system_enabled: online ? 'on' : (lastData?.settings?.live_call_system_enabled || 'off'),
        guru_online: online ? 'on' : 'off'
    });
}

async function sendTestPush() {
    await postAction({action: 'send_test_push'}, 'Test push trigger ho gaya');
}

function fillSettings(settings) {
    const form = document.getElementById('settingsForm');
    Object.keys(settings || {}).forEach(key => {
        const input = form.querySelector(`[name="${key}"]`);
        if (input) input.value = settings[key];
    });
}

function setupBadge(ok, onText = 'Ready', offText = 'Missing') {
    return `<span class="pill ${ok ? 'pill-on' : 'pill-warn'}"><i class="fas ${ok ? 'fa-check' : 'fa-exclamation-triangle'}"></i>${ok ? onText : offText}</span>`;
}

function renderStatus(data) {
    const s = data.settings || {};
    const d = data.diagnostics || {};
    const systemOn = isOn(s.live_call_system_enabled);
    const guruOn = isOn(s.guru_online);
    document.getElementById('statusGrid').innerHTML = `
        <div class="status-tile"><span>System</span><strong>${setupBadge(systemOn, 'Enabled', 'Off')}</strong></div>
        <div class="status-tile"><span>Guruji</span><strong>${setupBadge(guruOn, 'Online', 'Offline')}</strong></div>
        <div class="status-tile"><span>Agora</span><strong>${setupBadge(d.agora_configured, 'App ID Set', 'App ID Missing')}</strong></div>
        <div class="status-tile"><span>Push</span><strong>${setupBadge(d.onesignal_key_configured, 'Key Set', 'Key Missing')}</strong></div>
    `;

    document.getElementById('setupChecklist').innerHTML = `
        <div class="setup-item"><div><strong>Live Call System</strong><div class="muted">Users can only call when this is enabled.</div></div>${setupBadge(systemOn, 'On', 'Off')}</div>
        <div class="setup-item"><div><strong>Guruji Online</strong><div class="muted">Online karte hi push notification trigger hota hai.</div></div>${setupBadge(guruOn, 'Online', 'Offline')}</div>
        <div class="setup-item"><div><strong>Agora App ID</strong><div class="muted">Video/audio room join ke liye required.</div></div>${setupBadge(d.agora_configured)}</div>
        <div class="setup-item"><div><strong>OneSignal REST Key</strong><div class="muted">${Number(d.device_token_count || 0)} device tokens, ${Number(d.pending_push_count || 0)} pending logs.</div></div>${setupBadge(d.onesignal_key_configured)}</div>
    `;
}

function renderCurrentCall(session) {
    const el = document.getElementById('currentCall');
    if (!session) {
        activeSessionCache = {};
        el.innerHTML = `
            <div class="text-center py-5">
                <i class="fas fa-phone-slash fa-3x text-muted mb-3"></i>
                <h5>No active call</h5>
                <p class="muted mb-0">User call start karega to yahan ringing/current call dikhega.</p>
            </div>
        `;
        return;
    }
    activeSessionCache[Number(session.id)] = session;
    el.innerHTML = `
        <div class="d-flex justify-content-between align-items-start flex-wrap gap-2">
            <div>
                <h4 class="mb-1">${session.user_name || 'User'} <span class="badge bg-primary">${session.call_type}</span></h4>
                <div class="muted">${session.user_mobile || ''}</div>
            </div>
            <span class="pill ${session.status === 'active' ? 'pill-on' : 'pill-warn'}">
                <i class="fas fa-circle"></i>${session.status}
            </span>
        </div>
        <div class="metric-row">
            <div class="metric"><span>Wallet Balance</span><strong>${rupee(session.balance)}</strong></div>
            <div class="metric"><span>Call Time</span><strong>${secondsToClock(session.billed_seconds)}</strong></div>
            <div class="metric"><span>Charged</span><strong>${rupee(session.charged_amount)}</strong></div>
        </div>
        <div class="metric-row">
            <div class="metric"><span>Rate / Min</span><strong>${rupee(session.rate_per_minute)}</strong></div>
            <div class="metric"><span>Extended</span><strong>${secondsToClock(session.admin_extension_seconds)}</strong></div>
            <div class="metric"><span>Channel</span><strong style="font-size:13px">${session.channel_name}</strong></div>
        </div>
        <div class="call-actions">
            <button id="answerCallBtn" class="btn btn-success btn-lg" onclick="answerCallById(${Number(session.id)})">
                <i class="fas fa-phone-volume me-1"></i>Uthao & Join
            </button>
            <button class="btn btn-outline-primary" onclick="postAction({action:'accept', session_id:${session.id}})">
                <i class="fas fa-check me-1"></i>Only Accept
            </button>
            <button class="btn btn-outline-danger" onclick="leaveAgoraCall()">
                <i class="fas fa-sign-out-alt me-1"></i>Leave
            </button>
            <button class="btn btn-warning" onclick="postAction({action:'extend', session_id:${session.id}, seconds:60})">
                <i class="fas fa-clock me-1"></i>Extend 60s
            </button>
            <button class="btn btn-danger" onclick="postAction({action:'reject', session_id:${session.id}})">
                <i class="fas fa-phone-slash me-1"></i>Reject
            </button>
        </div>
        <div id="answerStatus" class="answer-note">Ready: Uthao & Join dabao. Browser permission aaye to Allow karo.</div>
        <div class="video-grid">
            <div id="localPlayer" class="video-box">Guruji Preview</div>
            <div id="remotePlayer" class="video-box">User Video / Audio</div>
        </div>
        <div id="callDebug" class="call-debug">Debug ready. Click Uthao & Join.</div>
    `;
}

async function answerCallById(sessionId) {
    const session = activeSessionCache[Number(sessionId)] || lastData?.active_session;
    if (!session) {
        showNotice('Call session data nahi mila. Refresh karo.', 'danger');
        logDebug(`No session found for id ${sessionId}`);
        return;
    }
    await answerCall(session);
}

async function answerCall(session) {
    if (answerInProgress) {
        logDebug('Answer already in progress, duplicate click ignored');
        return;
    }
    answerInProgress = true;
    const btn = document.getElementById('answerCallBtn');
    if (btn) {
        btn.disabled = true;
        btn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>Connecting...';
    }
    stopRing();
    try {
        await joinAgoraCall(session);
    } finally {
        answerInProgress = false;
        const currentBtn = document.getElementById('answerCallBtn');
        if (currentBtn && joinedSessionId !== Number(session.id)) {
            currentBtn.disabled = false;
            currentBtn.innerHTML = '<i class="fas fa-phone-volume me-1"></i>Uthao & Join';
        }
    }
}

async function joinAgoraCall(session) {
    setAnswerStatus('Step 1: Button click received. Agora SDK check ho raha hai...');
    if (!window.AgoraRTC) {
        showNotice('Agora Web SDK load nahi hua. Internet/CDN check karo.', 'danger');
        setAnswerStatus('Fail: Agora Web SDK load nahi hua. CDN blocked/internet issue.', 'danger');
        return;
    }
    const appId = lastData?.settings?.live_call_agora_app_id || '';
    if (!appId) {
        showNotice('Agora App ID admin settings me save karo.', 'warning');
        setAnswerStatus('Fail: Agora App ID missing hai.', 'danger');
        return;
    }
    if (joinedSessionId === Number(session.id)) {
        setAnswerStatus('Already joined this call.', 'success');
        return;
    }
    await leaveAgoraCall(false);

    try {
        showNotice('Call connect ho rahi hai. Browser mic/camera permission Allow karo.', 'info');
        setAnswerStatus('Step 2: Agora client create ho raha hai...');
        agoraClient = AgoraRTC.createClient({ mode: 'rtc', codec: 'vp8' });
        agoraClient.on('user-published', async (user, mediaType) => {
            await agoraClient.subscribe(user, mediaType);
            if (mediaType === 'video') {
                document.getElementById('remotePlayer').innerHTML = '';
                user.videoTrack.play('remotePlayer');
            }
            if (mediaType === 'audio') user.audioTrack.play();
        });
        agoraClient.on('user-unpublished', () => {
            const remote = document.getElementById('remotePlayer');
            if (remote) remote.innerHTML = 'User disconnected';
        });

        const uid = Number(session.guru_uid || 1);
        const token = session.guru_agora_token || null;
        if (session.agora_token_required && !token) {
            showNotice('Agora App Certificate missing/invalid hai. Admin settings me certificate save karo.', 'danger');
            setAnswerStatus('Fail: Agora token generate nahi hua. App Certificate settings me save karo.', 'danger');
            return;
        }
        setAnswerStatus(`Step 3: Channel join ho raha hai (${session.channel_name})...`);
        logDebug(`Agora join: channel=${session.channel_name}, uid=${uid}, token=${token ? 'present' : 'not required'}`);
        await agoraClient.join(appId, session.channel_name, token, uid);
        setAnswerStatus('Step 4: Mic/camera permission request ho raha hai...');
        if (session.call_type === 'video') {
            localTracks = await AgoraRTC.createMicrophoneAndCameraTracks();
            document.getElementById('localPlayer').innerHTML = '';
            localTracks[1].play('localPlayer');
        } else {
            localTracks = [await AgoraRTC.createMicrophoneAudioTrack()];
            document.getElementById('localPlayer').innerHTML = '<strong>Audio connected</strong>';
        }
        setAnswerStatus('Step 5: Guruji audio/video publish ho raha hai...');
        await agoraClient.publish(localTracks);
        joinedSessionId = Number(session.id);
        stopRing();
        setAnswerStatus('Step 6: Call accepted API update ho raha hai...');
        await postAction({action:'accept', session_id: session.id}, 'Call joined');
        setAnswerStatus('Connected: Call join ho gayi.', 'success');
    } catch (e) {
        stopRing();
        showNotice('Agora join failed: ' + e.message, 'danger');
        setAnswerStatus('Fail: ' + e.message, 'danger');
    }
}

async function leaveAgoraCall(refresh = true) {
    for (const track of localTracks) {
        try {
            track.stop();
            track.close();
        } catch (e) {}
    }
    localTracks = [];
    if (agoraClient) {
        try { await agoraClient.leave(); } catch (e) {}
    }
    agoraClient = null;
    joinedSessionId = null;
    stopRing();
    if (refresh) loadLiveCalls();
}

function renderQueue(queue) {
    const el = document.getElementById('queueList');
    if (!queue || queue.length === 0) {
        el.innerHTML = '<p class="muted mb-0">No users waiting in queue.</p>';
        return;
    }
    el.innerHTML = queue.map((item, index) => `
        <div class="queue-item">
            <div>
                <strong>#${index + 1} ${item.user_name || 'User'}</strong>
                <div class="muted">${item.user_mobile || ''} - ${item.call_type}</div>
            </div>
            <span class="badge bg-secondary align-self-center">${item.status}</span>
        </div>
    `).join('');
}

async function loadLiveCalls() {
    try {
        const res = await fetch(apiUrl);
        const data = await res.json();
        if (!data.success) throw new Error(data.message || 'Failed to load');
        lastData = data;
        fillSettings(data.settings);
        renderStatus(data);
        if (!(joinedSessionId && data.active_session && Number(data.active_session.id) === Number(joinedSessionId))) {
            renderCurrentCall(data.active_session);
        }
        if (data.active_session && ['requested', 'ringing'].includes(String(data.active_session.status))) {
            startRing(data.active_session);
        } else {
            stopRing();
        }
        renderQueue(data.queue);
    } catch (e) {
        document.getElementById('currentCall').innerHTML = `<div class="alert alert-danger">${e.message}</div>`;
        showNotice(e.message, 'danger');
    }
}

document.getElementById('settingsForm').addEventListener('submit', async (e) => {
    e.preventDefault();
    const form = new FormData(e.target);
    const payload = {action: 'save_settings'};
    for (const [key, value] of form.entries()) payload[key] = value;
    await postAction(payload, 'Settings saved');
});

loadLiveCalls();
setInterval(loadLiveCalls, 5000);
</script>
<?php
$content = ob_get_clean();
include 'layout.php';
?>
