<?php
/**
 * RemoteX Signaling Server - Fixed Version
 */

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

$data_dir = __DIR__ . '/sessions/';
if (!file_exists($data_dir)) {
    @mkdir($data_dir, 0777, true);
}
@chmod($data_dir, 0777);

$action     = $_GET['action'] ?? '';
$session_id = $_GET['session'] ?? '';

// ─── Helpers ─────────────────────────────────

function session_file($sid) {
    global $data_dir;
    $safe = preg_replace('/[^a-zA-Z0-9_-]/', '', $sid);
    return $data_dir . $safe . '.json';
}

function read_session($sid) {
    $f = session_file($sid);
    if (!file_exists($f)) return null;
    $d = json_decode(file_get_contents($f), true);
    if (!$d) return null;
    // 1 ghante se purani session expire
    if (isset($d['created']) && (time() - $d['created']) > 3600) {
        @unlink($f);
        return null;
    }
    return $d;
}

function save_session($sid, $data) {
    file_put_contents(session_file($sid), json_encode($data), LOCK_EX);
}

function ok($extra = []) {
    echo json_encode(array_merge(['success' => true], $extra));
}

function err($msg) {
    echo json_encode(['success' => false, 'error' => $msg]);
}

// ─── Routes ──────────────────────────────────

switch ($action) {

    // ── CREATE FIXED SESSION (Default PIN = 11111) ──
    case 'create_fixed':
        $fixed_pin = trim($_GET['pin'] ?? $_POST['pin'] ?? '11111');
        if (empty($fixed_pin)) $fixed_pin = '11111';
        $aliases = ($fixed_pin === '11111' || $fixed_pin === '111111') ? ['11111', '111111'] : [$fixed_pin];

        // Check if existing session with this PIN exists and is fresh (within 24 hours)
        if (is_dir($data_dir)) {
            foreach (scandir($data_dir) as $file) {
                if (substr($file, -5) !== '.json') continue;
                $d = json_decode(file_get_contents($data_dir . $file), true);
                if ($d && in_array($d['pin'] ?? '', $aliases) && (time() - ($d['created'] ?? 0)) < 86400) {
                    $d['last_seen'] = time();
                    save_session($d['session_id'], $d);
                    ok(['session_id' => $d['session_id'], 'pin' => $fixed_pin]);
                    exit;
                }
            }
        }
        // Create new session with fixed PIN
        $sid  = bin2hex(random_bytes(8));
        $pin  = $fixed_pin;
        $sess = [
            'session_id' => $sid, 'pin' => $pin, 'created' => time(),
            'status' => 'waiting', 'connected' => false, 'last_seen' => time(),
            'client_answer' => null, 'host_candidates' => [], 'client_candidates' => [],
            'commands' => [], 'cmd_count' => 0, 'screenshots' => [], 'tabs' => [],
            'screenshot_requested' => false,
        ];
        save_session($sid, $sess);
        ok(['session_id' => $sid, 'pin' => $pin]);
        break;

    // ── CREATE SESSION (random PIN) ──
    case 'create':
        $sid  = bin2hex(random_bytes(8));
        $pin  = str_pad(rand(0, 999999), 6, '0', STR_PAD_LEFT);
        $sess = [
            'session_id'           => $sid,
            'pin'                  => $pin,
            'created'              => time(),
            'status'               => 'waiting',
            'connected'            => false,
            'last_seen'            => time(),
            'client_answer'        => null,
            'host_candidates'      => [],
            'client_candidates'    => [],
            'commands'             => [],
            'cmd_count'            => 0,
            'screenshots'          => [],
            'tabs'                 => [],
            'screenshot_requested' => false,
        ];
        save_session($sid, $sess);
        ok(['session_id' => $sid, 'pin' => $pin]);
        break;

    // ── JOIN BY PIN ──
    case 'join':
        $pin = trim($_POST['pin'] ?? $_GET['pin'] ?? '');
        if (empty($pin)) { err('PIN required'); break; }

        $aliases = ($pin === '11111' || $pin === '111111') ? ['11111', '111111'] : [$pin];

        $found = null;
        if (is_dir($data_dir)) {
            foreach (scandir($data_dir) as $file) {
                if (substr($file, -5) !== '.json') continue;
                $d = json_decode(file_get_contents($data_dir . $file), true);
                if ($d && in_array($d['pin'] ?? '', $aliases)) {
                    if ((time() - ($d['created'] ?? 0)) < 86400) {
                        $found = $d;
                        break;
                    }
                }
            }
        }

        if ($found) ok(['session_id' => $found['session_id'], 'pin' => $found['pin']]);
        else         err('Galat PIN ya session expire ho gaya');
        break;

    // ── ANSWER (client connected) ──
    case 'answer':
        $sess = read_session($session_id);
        if (!$sess) { err('Session nahi mila'); break; }
        $body = json_decode(file_get_contents('php://input'), true) ?? [];
        $sess['client_answer'] = $body['answer'] ?? 'connected';
        $sess['status']        = 'answered';
        $sess['connected']     = true;
        $sess['last_seen']     = time();
        save_session($session_id, $sess);
        ok();
        break;

    // ── GET SCREENSHOT BINARY ──
    case 'screen':
        if (!$session_id) { err('Session required'); break; }
        $clean_id = preg_replace('/[^a-zA-Z0-9_-]/', '', $session_id);
        $img_file = $data_dir . 'screen_' . $clean_id . '.jpg';
        if (file_exists($img_file)) {
            header('Content-Type: image/jpeg');
            header('Cache-Control: no-cache, no-store, must-revalidate');
            header('Pragma: no-cache');
            header('Expires: 0');
            readfile($img_file);
            exit;
        } else {
            header('Content-Type: image/gif');
            echo base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
            exit;
        }
        break;

    // ── HIGH-SPEED REACTIVE POLL ──
    case 'poll':
        if (!$session_id) { err('Session required'); break; }
        $role             = $_GET['role'] ?? 'client';
        $last_cmd         = intval($_GET['last_cmd'] ?? 0);
        $last_screen_time = floatval($_GET['last_screen'] ?? 0);

        $start = microtime(true);
        while ((microtime(true) - $start) < 14.0) {
            $sess = read_session($session_id);
            if (!$sess) { err('Session expire'); exit; }

            $sess['last_seen'] = time();

            if ($role === 'host') {
                $cmds = array_slice($sess['commands'] ?? [], $last_cmd);
                if (!empty($cmds) || !empty($sess['client_answer']) || !empty($sess['screenshot_requested'])) {
                    $res = [
                        'success'              => true,
                        'status'               => $sess['status'] ?? 'active',
                        'connected'            => $sess['connected'] ?? false,
                        'commands'             => $cmds,
                        'cmd_count'            => count($sess['commands'] ?? []),
                        'screenshot_requested' => $sess['screenshot_requested'] ?? false,
                        'client_answer'        => $sess['client_answer'] ?? null
                    ];
                    echo json_encode($res);
                    exit;
                }
            } else {
                // Client role
                $cur_screen_time = floatval($sess['screen_time'] ?? 0);
                if ($cur_screen_time > $last_screen_time || $last_screen_time == 0) {
                    $clean_id = preg_replace('/[^a-zA-Z0-9_-]/', '', $session_id);
                    $has_file = file_exists($data_dir . 'screen_' . $clean_id . '.jpg');
                    if ($has_file || !empty($sess['screenshots'])) {
                        $res = [
                            'success'     => true,
                            'status'      => $sess['status'] ?? 'active',
                            'connected'   => $sess['connected'] ?? false,
                            'screen_time' => $cur_screen_time,
                            'width'       => $sess['width'] ?? 1920,
                            'height'      => $sess['height'] ?? 1080,
                            'url'         => $sess['url'] ?? '',
                            'title'       => $sess['title'] ?? '',
                            'tabs'        => $sess['tabs'] ?? []
                        ];
                        // Backward compatibility fallback
                        if (!empty($sess['screenshots'])) {
                            $res['latest_screenshot'] = end($sess['screenshots']);
                        }
                        echo json_encode($res);
                        exit;
                    }
                }
            }

            usleep(35000); // 35ms reactive polling!
        }
        ok(['status' => 'timeout', 'connected' => $sess['connected'] ?? false]);
        break;

    // ── SCREENSHOT upload (from extension) ──
    case 'screenshot':
        $sess = read_session($session_id);
        if (!$sess) { err('Session nahi mila'); break; }
        $body = json_decode(file_get_contents('php://input'), true) ?? [];
        $raw = $body['data'] ?? '';

        if (!empty($raw)) {
            $img_data = $raw;
            if (strpos($img_data, ',') !== false) {
                $img_data = substr($img_data, strpos($img_data, ',') + 1);
            }
            $bin = base64_decode($img_data);
            if ($bin) {
                $clean_id = preg_replace('/[^a-zA-Z0-9_-]/', '', $session_id);
                $img_file = $data_dir . 'screen_' . $clean_id . '.jpg';
                file_put_contents($img_file, $bin, LOCK_EX);
            }
        }

        $screen_time = microtime(true);
        $sess['screen_time'] = $screen_time;
        $sess['width']       = intval($body['width'] ?? 1920);
        $sess['height']      = intval($body['height'] ?? 1080);
        $sess['url']         = $body['url'] ?? '';
        $sess['title']       = $body['title'] ?? '';
        $sess['screenshot_requested'] = false;
        $sess['connected']   = true;
        $sess['last_seen']   = time();
        // Remove heavy screenshots array to keep session json < 1KB
        unset($sess['screenshots']);
        save_session($session_id, $sess);
        ok(['screen_time' => $screen_time]);
        break;

    // ── REQUEST SCREENSHOT (from client) ──
    case 'request_screenshot':
        $sess = read_session($session_id);
        if (!$sess) { err('Session nahi mila'); break; }
        $sess['screenshot_requested'] = true;
        save_session($session_id, $sess);
        ok();
        break;

    // ── COMMAND (from client → host) ──
    case 'command':
        $sess = read_session($session_id);
        if (!$sess) { err('Session nahi mila'); break; }
        $body = json_decode(file_get_contents('php://input'), true) ?? [];
        $sess['commands'][] = [
            'type'      => $body['type'] ?? '',
            'data'      => $body['data'] ?? [],
            'timestamp' => microtime(true),
        ];
        // Keep last 50 commands
        if (count($sess['commands']) > 50) {
            $sess['commands'] = array_values(array_slice($sess['commands'], -50));
        }
        $sess['cmd_count'] = count($sess['commands']);
        save_session($session_id, $sess);
        ok();
        break;

    // ── TABS (from extension) ──
    case 'tabs':
        $sess = read_session($session_id);
        if (!$sess) { err('Session nahi mila'); break; }
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $body = json_decode(file_get_contents('php://input'), true) ?? [];
            $sess['tabs'] = $body['tabs'] ?? [];
            save_session($session_id, $sess);
            ok();
        } else {
            ok(['tabs' => $sess['tabs'] ?? []]);
        }
        break;

    // ── STATUS ──
    case 'status':
        if (!$session_id) { ok(['status' => 'no_session']); break; }
        $sess = read_session($session_id);
        if ($sess) {
            ok([
                'status'     => $sess['status'],
                'connected'  => $sess['connected'] ?? false,
                'last_seen'  => $sess['last_seen']  ?? null,
                'pin'        => $sess['pin'],
            ]);
        } else {
            err('Session nahi mila');
        }
        break;

    default:
        err('Invalid action: ' . htmlspecialchars($action));
}
?>
