<?php // Vocal secours — WebRTC P2P + signalisation PHP via DB + participants via DB
declare(strict_types=1);
require_once "auth/session.php";
header("X-Content-Type-Options: nosniff");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");

$user = getCurrentUser();
$current_user_id = $user ? (int)$user["id"] : 0;

function room_id(string $s): string {
    $s = preg_replace("~[^a-zA-Z0-9_\-]~", "", $s);
    return $s !== "" ? $s : "secours";
}

function peer_id(): string {
    return bin2hex(random_bytes(8));
}

function now_ms(): int {
    return (int) floor(microtime(true) * 1000);
}

function json_out($data, int $code = 200): void {
    http_response_code($code);
    header("Content-Type: application/json; charset=utf-8");
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

// Logic for signaling
$action = $_REQUEST["action"] ?? "";
$room = room_id($_REQUEST["room"] ?? "secours");
$my_id = $_REQUEST["peer_id"] ?? "";

if ($action === "join") {
    $name = $_REQUEST["name"] ?? "User";
    
    $new_id = peer_id();
    if ($current_user_id > 0) {
        try {
            $stmt = db()->prepare("INSERT INTO voice_sessions (user_id, channel_id, peer_id, name, last_seen) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE channel_id = ?, peer_id = ?, name = ?, last_seen = ?");
            $stmt->execute([$current_user_id, $room, $new_id, $name, now_ms(), $room, $new_id, $name, now_ms()]);
        } catch (Exception $e) {
            json_out(["error" => "DB Error: " . $e->getMessage()], 500);
        }
    } else {
        json_out(["error" => "Not logged in"], 401);
    }
    
    // Fetch all participants in this room
    $ps = [];
    try {
        $stmt = db()->prepare("SELECT vs.*, u.avatar_url FROM voice_sessions vs JOIN users u ON vs.user_id = u.id WHERE vs.channel_id = ? AND vs.last_seen > ?");
        $stmt->execute([$room, now_ms() - 7000]);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        foreach ($rows as $row) {
            $ps[$row["peer_id"]] = [
                "id" => $row["peer_id"],
                "user_id" => (int)$row["user_id"],
                "name" => $row["name"],
                "avatar_url" => $row["avatar_url"],
                "last_seen" => (int)$row["last_seen"]
            ];
        }
    } catch (Exception $e) {}
    
    json_out(["success" => true, "peer_id" => $new_id, "participants" => $ps]);
}

if ($action === "poll") {
    if (!$my_id) json_out(["error" => "Missing peer_id"], 400);
    
    // Update last_seen
    if ($current_user_id > 0) {
        try {
            $stmt = db()->prepare("UPDATE voice_sessions SET last_seen = ? WHERE user_id = ? AND peer_id = ?");
            $stmt->execute([now_ms(), $current_user_id, $my_id]);
        } catch (Exception $e) {}
    }
    
    // Fetch participants
    $ps = [];
    try {
        $stmt = db()->prepare("SELECT vs.*, u.avatar_url FROM voice_sessions vs JOIN users u ON vs.user_id = u.id WHERE vs.channel_id = ? AND vs.last_seen > ?");
        $stmt->execute([$room, now_ms() - 7000]);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        foreach ($rows as $row) {
            $ps[$row["peer_id"]] = [
                "id" => $row["peer_id"],
                "user_id" => (int)$row["user_id"],
                "name" => $row["name"],
                "avatar_url" => $row["avatar_url"],
                "last_seen" => (int)$row["last_seen"]
            ];
        }
    } catch (Exception $e) {}

    // Read signals
    $signals = [];
    try {
        $stmt = db()->prepare("SELECT * FROM voice_signals WHERE to_peer_id = ? AND room_id = ?");
        $stmt->execute([$my_id, $room]);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $ids_to_delete = [];
        foreach ($rows as $row) {
            $signals[] = [
                "from" => $row["from_peer_id"],
                "to" => $row["to_peer_id"],
                "data" => json_decode($row["data"], true),
                "time" => (int)$row["created_at"]
            ];
            $ids_to_delete[] = $row["id"];
        }
        if (!empty($ids_to_delete)) {
            $placeholders = implode(',', array_fill(0, count($ids_to_delete), '?'));
            db()->prepare("DELETE FROM voice_signals WHERE id IN ($placeholders)")->execute($ids_to_delete);
        }
        
        // Occasional cleanup of old signals
        if (rand(1, 20) === 1) {
            $stale_sig = now_ms() - 60000;
            db()->prepare("DELETE FROM voice_signals WHERE created_at < ?")->execute([$stale_sig]);
        }
    } catch (Exception $e) {}
    
    json_out(["success" => true, "participants" => $ps, "signals" => $signals]);
}

if ($action === "signal") {
    if (!$my_id) json_out(["error" => "Missing peer_id"], 400);
    $to = $_REQUEST["to"] ?? "";
    $data = $_REQUEST["data"] ?? "";
    if (!$to || !$data) json_out(["error" => "Missing to/data"], 400);
    
    try {
        $stmt = db()->prepare("INSERT INTO voice_signals (room_id, from_peer_id, to_peer_id, data, created_at) VALUES (?, ?, ?, ?, ?)");
        $stmt->execute([$room, $my_id, $to, $data, now_ms()]);
    } catch (Exception $e) {
        json_out(["error" => "Signal Error: " . $e->getMessage()], 500);
    }
    json_out(["success" => true]);
}

if ($action === "list_all") {
    try {
        $stmt = db()->prepare("
            SELECT vs.channel_id, vs.user_id, u.username, u.display_name, u.avatar_url 
            FROM voice_sessions vs
            JOIN users u ON vs.user_id = u.id
            WHERE vs.last_seen > ?
        ");
        $stale_db_time = now_ms() - 30000;
        $stmt->execute([$stale_db_time]);
        $sessions = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        $by_channel = [];
        foreach ($sessions as $s) {
            $by_channel[$s['channel_id']][] = $s;
        }
        json_out(["success" => true, "channels" => $by_channel]);
    } catch (Exception $e) {
        json_out(["error" => $e->getMessage()], 500);
    }
}

if ($action === "leave") {
    if ($my_id) {
        try {
            $stmt = db()->prepare("DELETE FROM voice_sessions WHERE peer_id = ?");
            $stmt->execute([$my_id]);
        } catch (Exception $e) {}
    } elseif ($current_user_id > 0) {
        try {
            $stmt = db()->prepare("DELETE FROM voice_sessions WHERE user_id = ?");
            $stmt->execute([$current_user_id]);
        } catch (Exception $e) {}
    }
    json_out(["success" => true]);
}

json_out(["error" => "Unknown action"], 404);
