<?php
// stream.php - COM LOAD BALANCE (Balanceamento de Carga)
// Distribui clientes entre servidores cadastrados na tabela 'servers'

set_time_limit(0);
error_reporting(0);
ini_set('display_errors', 0);

require_once 'includes/db.php';

// 1. ValidaÃ§Ã£o de UsuÃ¡rio (PadrÃ£o)
$username = $_GET['username'] ?? '';
$password = $_GET['password'] ?? '';
$stream_id = (int)($_GET['stream'] ?? 0);
$type = $_GET['type'] ?? 'live'; 

$stmt = $pdo->prepare("SELECT id, username, active, expire_date FROM users WHERE username = ? AND password = ? LIMIT 1");
$stmt->execute([$username, $password]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$user || $user['active'] == 0 || (!empty($user['expire_date']) && strtotime($user['expire_date']) < time())) {
    http_response_code(403); exit;
}

// 2. Busca Dados do ConteÃºdo
$real_link = "";
$content_name = "Stream";
$content_img = "";
$monitor_id = $stream_id;
$use_proxy = false;

// VariÃ¡vel para armazenar o servidor escolhido
$target_server = null; 

if ($type == 'live') {
    $r = $pdo->query("SELECT stream_url, name, logo_url, running FROM channels WHERE id=$stream_id")->fetch(PDO::FETCH_ASSOC);
    if($r){ 
        $real_link = $r['stream_url']; 
        $content_name = $r['name']; 
        $content_img = $r['logo_url'];
        // Se estiver ativado o Proxy, vamos usar o Load Balance
        if($r['running'] == 1) {
            $use_proxy = true;
        }
    }
} elseif ($type == 'movie') {
    $r = $pdo->query("SELECT stream_url, name, cover_url FROM movies WHERE id=$stream_id")->fetch(PDO::FETCH_ASSOC);
    if($r){ $real_link=$r['stream_url']; $content_name=$r['name']; $content_img=$r['cover_url']; }
} elseif ($type == 'series') {
    $r = $pdo->query("SELECT e.stream_url, s.series_id, ser.name, ser.cover_url FROM episodes e JOIN seasons s ON e.season_id=s.id JOIN series ser ON s.series_id=ser.id WHERE e.id=$stream_id")->fetch(PDO::FETCH_ASSOC);
    if($r){ $real_link=$r['stream_url']; $content_name=$r['name']; $content_img=$r['cover_url']; $monitor_id=$r['series_id']; }
}

if (empty($real_link)) { http_response_code(404); exit; }

// ============================================================
// LÃ“GICA DE LOAD BALANCE (SÃ³ para Proxy/Live)
// ============================================================
$chosen_server_id = 0;

if ($use_proxy) {
    try {
        // Busca o servidor ATIVO com MENOS conexÃµes atuais
        // Isso garante que sempre vai para o servidor mais livre
        $sql_lb = "SELECT * FROM servers WHERE status = 1 ORDER BY active_connections ASC LIMIT 1";
        $server_stmt = $pdo->query($sql_lb);
        $best_server = $server_stmt->fetch(PDO::FETCH_ASSOC);

        if ($best_server) {
            $chosen_server_id = $best_server['id'];
            
            // Incrementa conexÃ£o neste servidor
            $pdo->query("UPDATE servers SET active_connections = active_connections + 1 WHERE id = $chosen_server_id");
            
            // Opcional: Se este script NÃƒO estiver rodando no servidor escolhido, 
            // vocÃª poderia redirecionar o cliente para o script lÃ¡.
            // Mas para FFMPEG local (Proxy reverso), continuamos aqui.
        }
    } catch (Exception $e) {
        // Se der erro ou nÃ£o tiver servidor cadastrado, segue o fluxo normal (localhost)
    }
}

// 3. FunÃ§Ã£o para Registrar Online
function registerOnline($pdo, $user, $monitor_id, $type, $content_name, $content_img, $server_id) {
    try {
        $user_ip = $_SERVER['REMOTE_ADDR'];
        $ua = $_SERVER['HTTP_USER_AGENT'] ?? 'App';
        $pdo->prepare("DELETE FROM active_connections WHERE username=? AND user_ip=?")->execute([$user['username'], $user_ip]);
        
        // Adicionei server_id se vocÃª quiser criar essa coluna na active_connections futuramente
        $pdo->prepare("INSERT INTO active_connections (user_id, username, content_id, stream_type, user_ip, start_time, user_agent, content_name, content_image) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
            ->execute([$user['id'], $user['username'], $monitor_id, $type, $user_ip, time(), $ua, $content_name, $content_img]);
        
        return $pdo->lastInsertId();
    } catch(Exception $e){ return 0; }
}

// ============================================================
// EXECUÃ‡ÃƒO (PROXY FFMPEG)
// ============================================================

if ($use_proxy) {
    
    // Caminho FFMPEG
    $ffmpeg_bin = trim(shell_exec('which ffmpeg'));
    if (empty($ffmpeg_bin)) $ffmpeg_bin = '/usr/bin/ffmpeg'; 
    if (!file_exists($ffmpeg_bin)) $ffmpeg_bin = 'ffmpeg';

    $ua_fake = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";
    
    // Buffer ajustado para estabilidade
    $cmd = "$ffmpeg_bin -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 -user_agent \"$ua_fake\" -i \"$real_link\" -c copy -f mpegts -bufsize 512k pipe:1 2>/dev/null";
    
    $handle = popen($cmd, 'r');
    
    if ($handle) {
        $buffer = fread($handle, 4096);
        
        if (empty($buffer)) {
            pclose($handle);
            // Fallback para direct se falhar
        } else {
            if (ob_get_level()) ob_end_clean();
            header('Content-Type: video/mp2t');
            ob_implicit_flush(true);
            
            $conn_id = registerOnline($pdo, $user, $monitor_id, $type, $content_name, $content_img, $chosen_server_id);
            
            echo $buffer;
            $last_update = time();
            
            while (!feof($handle)) {
                if (connection_aborted()) break;

                $chunk = fread($handle, 16384);
                echo $chunk;
                
                if (ob_get_length() > 0) ob_flush();
                flush();
                
                if (time() - $last_update > 10) {
                    if ($conn_id) $pdo->query("UPDATE active_connections SET start_time = ".time()." WHERE id = $conn_id");
                    $last_update = time();
                }
            }
            pclose($handle);
            
            // Limpeza
            if ($conn_id) $pdo->query("DELETE FROM active_connections WHERE id = $conn_id");
            
            // Decrementa conexÃ£o do servidor de Balanceamento ao sair
            if ($chosen_server_id > 0) {
                $pdo->query("UPDATE servers SET active_connections = active_connections - 1 WHERE id = $chosen_server_id AND active_connections > 0");
            }
            exit; 
        }
    }
}

// ============================================================
// MODO DIRECT (FALLBACK)
// ============================================================
registerOnline($pdo, $user, $monitor_id, $type, $content_name, $content_img, 0);
header("Location: " . $real_link);
exit;
?>