<?php
// Permite acesso de aplicativos externos (CORS)
header('Access-Control-Allow-Origin: *');

require_once 'config.php';
$pdo = getConexaoAtiva();
$pdo->exec("SET NAMES utf8mb4");

// ==============================================================================
// --- SISTEMA DE SEGURANÇA (BLOQUEIOS DE FIREWALL) ---
// ==============================================================================
try {
    $ip_cliente = $_SERVER['HTTP_CLIENT_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'];
    $ua_cliente = $_SERVER['HTTP_USER_AGENT'] ?? '';

    $tabelas_seguranca = $pdo->query("SHOW TABLES LIKE 'blocked_ips'")->rowCount() > 0;
    
    if ($tabelas_seguranca) {
        $stmtIp = $pdo->prepare("SELECT id FROM blocked_ips WHERE ip = ?");
        $stmtIp->execute([$ip_cliente]);
        if ($stmtIp->fetch()) {
            $pdo->prepare("UPDATE blocked_ips SET attempts_blocked = attempts_blocked + 1 WHERE ip = ?")->execute([$ip_cliente]);
            http_response_code(403); die("Acesso Bloqueado (IP).");
        }

        $stmtUa = $pdo->prepare("SELECT id, user_agent, exact_match FROM blocked_user_agents");
        $stmtUa->execute();
        while ($rowUa = $stmtUa->fetch(PDO::FETCH_ASSOC)) {
            if ($rowUa['exact_match'] == 1) {
                if ($ua_cliente === $rowUa['user_agent']) {
                    $pdo->prepare("UPDATE blocked_user_agents SET attempts_blocked = attempts_blocked + 1 WHERE id = ?")->execute([$rowUa['id']]);
                    http_response_code(403); die("Acesso Bloqueado (UA Exato).");
                }
            } else {
                if (!empty($rowUa['user_agent']) && stripos($ua_cliente, $rowUa['user_agent']) !== false) {
                    $pdo->prepare("UPDATE blocked_user_agents SET attempts_blocked = attempts_blocked + 1 WHERE id = ?")->execute([$rowUa['id']]);
                    http_response_code(403); die("Acesso Bloqueado (UA Contém).");
                }
            }
        }
    }
} catch (Exception $e) {}
// ==============================================================================

// 1. RECEBE OS PARÂMETROS DO APLICATIVO
$username = $_GET['username'] ?? '';
$password = $_GET['password'] ?? '';
$action   = $_GET['action'] ?? '';
$type_req = $_GET['type'] ?? '';
$output   = $_GET['output'] ?? 'ts';

if (empty($username) || empty($password)) {
    header('Content-Type: application/json; charset=utf-8');
    die(json_encode(['user_info' => ['auth' => 0]]));
}

// 2. AUTENTICAÇÃO DO USUÁRIO
try {
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $check_last = $pdo->query("SHOW COLUMNS FROM `users` LIKE 'last_activity'");
    if (!$check_last->fetch()) {
        $pdo->exec("ALTER TABLE `users` ADD COLUMN `last_activity` INT(11) DEFAULT 0");
    }
} catch (PDOException $e) {}

$stmtUser = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmtUser->execute([$username, $password]);
$user = $stmtUser->fetch(PDO::FETCH_ASSOC);

if (!$user) {
    header('Content-Type: application/json; charset=utf-8');
    die(json_encode(['user_info' => ['auth' => 0]]));
}

$status = 'Active';
if ($user['exp_date'] < time() && $user['exp_date'] != 0) {
    $status = 'Expired';
    if (empty($action) && empty($type_req)) {
        header('Content-Type: application/json; charset=utf-8');
        die(json_encode(['user_info' => ['auth' => 0, 'status' => 'Expired']]));
    } else {
        http_response_code(403);
        die("Conta vencida.");
    }
}

if ($user['enabled'] == 0) {
    http_response_code(401);
    die("Usuario bloqueado.");
}

$pdo->prepare("UPDATE users SET last_activity = ? WHERE id = ?")->execute([time(), $user['id']]);

if (in_array($action, ['get_live_categories', 'get_vod_categories', 'get_series_categories'])) {
    $pdo->prepare("UPDATE users SET current_channel = 0 WHERE id = ?")->execute([$user['id']]);
}

// ==============================================================================
// --- LÓGICA DE BOUQUETS BLINDADA E EXTREMA ---
// ==============================================================================
$has_bouquet_filter = false;
$allowed_streams_str = '0';

$bouquet_str = trim($user['bouquet'] ?? '');
if (!empty($bouquet_str) && $bouquet_str !== 'null' && $bouquet_str !== '[]') {
    $user_bouquets = json_decode($bouquet_str, true);
    
    if (is_array($user_bouquets) && count($user_bouquets) > 0) {
        $has_bouquet_filter = true;
        $allowed_streams = [];
        
        $in_bouquets = str_repeat('?,', count($user_bouquets) - 1) . '?';
        $stmtBq = $pdo->prepare("SELECT bouquet_channels FROM bouquets WHERE id IN ($in_bouquets)");
        $stmtBq->execute($user_bouquets);
        $bqs = $stmtBq->fetchAll(PDO::FETCH_ASSOC);
        
        foreach ($bqs as $b) {
            if (!empty($b['bouquet_channels'])) {
                $chs = json_decode($b['bouquet_channels'], true);
                if (is_array($chs)) {
                    $allowed_streams = array_merge($allowed_streams, $chs);
                }
            }
        }
        
        $allowed_streams = array_unique(array_map('intval', $allowed_streams)); 
        if (count($allowed_streams) > 0) {
            $allowed_streams_str = implode(',', $allowed_streams);
        }
    }
}
// ==============================================================================


// ==============================================================================
// ROTEAMENTO 1: DOWNLOAD M3U DIRETO
// ==============================================================================
if ($type_req === 'm3u_plus' || $type_req === 'm3u') {
    ini_set('display_errors', 0);
    error_reporting(0);
    header('Content-Type: application/vnd.apple.mpegurl');
    header('Content-Disposition: attachment; filename="lista_'.$user['username'].'.m3u"');
    header('Cache-Control: no-cache, must-revalidate');

    echo "#EXTM3U\n";

    $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http";
    $server_url = $protocol . "://" . $_SERVER['HTTP_HOST'];

    try {
        // Canais
        $mostrar_live = true;
        if ($has_bouquet_filter) {
            $chk = $pdo->query("SELECT id FROM streams WHERE type IN (1, 3) AND id IN ($allowed_streams_str) LIMIT 1");
            if (!$chk->fetch()) $mostrar_live = false;
        }
        
        if ($mostrar_live) {
            $where_live = "(s.type IN (1, 3) OR c.category_type = 'live')";
            if ($has_bouquet_filter) $where_live .= " AND s.id IN ($allowed_streams_str)";
            
            $queryLive = "SELECT s.id, s.stream_display_name, s.stream_icon, s.direct_source, c.category_name 
                          FROM streams s LEFT JOIN stream_categories c ON s.category_id = c.id 
                          WHERE $where_live";
                          
            $stmtLive = $pdo->query($queryLive);
            if ($stmtLive) {
                while ($row = $stmtLive->fetch(PDO::FETCH_ASSOC)) {
                    $id_canal = $row['id'];
                    $nome     = $row['stream_display_name'];
                    $logo     = $row['stream_icon'];
                    $grupo    = $row['category_name'];
                    $modo_direct = (isset($row['direct_source']) && $row['direct_source'] == 1);
                    
                    echo '#EXTINF:-1 tvg-id="" tvg-name="'.$nome.'" tvg-logo="'.$logo.'" group-title="'.$grupo.'",'.$nome."\n";
                    if ($modo_direct) echo $server_url . "/live/" . $username . "/" . $password . "/" . $id_canal . "." . $output . "\n";
                    else echo $server_url . "/hls/" . $username . "/" . $password . "/" . $id_canal . "_.m3u8\n";
                }
            }
        }

        // Filmes
        $mostrar_vod = true;
        if ($has_bouquet_filter) {
            $chk = $pdo->query("SELECT id FROM streams WHERE type = 2 AND id IN ($allowed_streams_str) LIMIT 1");
            if (!$chk->fetch()) $mostrar_vod = false;
        }
        
        if ($mostrar_vod) {
            $where_vod = "(s.type = 2 OR c.category_type = 'movie')";
            if ($has_bouquet_filter) $where_vod .= " AND s.id IN ($allowed_streams_str)";
            
            $queryVod = "SELECT s.id, s.stream_display_name, s.stream_icon, c.category_name 
                         FROM streams s LEFT JOIN stream_categories c ON s.category_id = c.id 
                         WHERE $where_vod";
                         
            $stmtVod = $pdo->query($queryVod);
            if ($stmtVod) {
                while ($row = $stmtVod->fetch(PDO::FETCH_ASSOC)) {
                    $id_filme = $row['id'];
                    $nome     = $row['stream_display_name'];
                    $logo     = $row['stream_icon'];
                    $grupo    = $row['category_name'];
                    
                    echo '#EXTINF:-1 tvg-name="'.$nome.'" tvg-logo="'.$logo.'" group-title="'.$grupo.'",'.$nome."\n";
                    $extensao_vod = ($output == 'm3u8') ? 'm3u8' : 'mp4'; 
                    echo $server_url . "/movie/" . $username . "/" . $password . "/" . $id_filme . "." . $extensao_vod . "\n";
                }
            }
        }
        
        // Séries
        $mostrar_series = true;
        if ($has_bouquet_filter) {
            $chk = $pdo->query("SELECT id FROM series_episodes WHERE stream_id IN ($allowed_streams_str) LIMIT 1");
            if (!$chk->fetch()) $mostrar_series = false;
        }
        
        if ($mostrar_series) {
            $where_series = "";
            if ($has_bouquet_filter) $where_series = "WHERE s.id IN ($allowed_streams_str)";
            
            $querySeries = "SELECT se.stream_id, s.stream_display_name as ep_name, s.stream_icon, c.category_name, ser.title as serie_name, se.season_num, se.sort as ep_num
                            FROM series_episodes se
                            LEFT JOIN streams s ON se.stream_id = s.id
                            LEFT JOIN series ser ON se.series_id = ser.id
                            LEFT JOIN stream_categories c ON ser.category_id = c.id
                            $where_series";
            
            $stmtSeries = $pdo->query($querySeries);
            if ($stmtSeries) {
                while ($row = $stmtSeries->fetch(PDO::FETCH_ASSOC)) {
                    $id_ep    = $row['stream_id'];
                    $nome     = $row['serie_name'] . ' - S' . sprintf("%02d", $row['season_num']) . 'E' . sprintf("%02d", $row['ep_num']) . ' - ' . $row['ep_name'];
                    $logo     = $row['stream_icon'];
                    $grupo    = $row['category_name'];
                    
                    echo '#EXTINF:-1 tvg-name="'.$nome.'" tvg-logo="'.$logo.'" group-title="'.$grupo.'",'.$nome."\n";
                    $extensao_vod = ($output == 'm3u8') ? 'm3u8' : 'mp4'; 
                    echo $server_url . "/series/" . $username . "/" . $password . "/" . $id_ep . "." . $extensao_vod . "\n";
                }
            }
        }

    } catch (PDOException $e) {
        echo '#EXTINF:-1 tvg-name="ERRO" group-title="ERRO_SQL",Erro interno'."\n";
    }
    exit;
}

// ==============================================================================
// ROTEAMENTO 2: API JSON (XCIPTV, SMARTERS)
// ==============================================================================
header('Content-Type: application/json; charset=utf-8');

switch ($action) {

    // --- CATEGORIAS ---
    case 'get_live_categories':
    case 'get_vod_categories':
    case 'get_series_categories':
        $cat_type = 'live';
        $cat_filter = "";
        
        if ($has_bouquet_filter) {
            $allowed_cats = [];
            
            if ($action == 'get_live_categories') {
                $stmt = $pdo->query("SELECT DISTINCT category_id FROM streams WHERE type IN (1, 3) AND id IN ($allowed_streams_str)");
                $allowed_cats = $stmt->fetchAll(PDO::FETCH_COLUMN);
            } 
            elseif ($action == 'get_vod_categories') {
                $stmt = $pdo->query("SELECT DISTINCT category_id FROM streams WHERE type = 2 AND id IN ($allowed_streams_str)");
                $allowed_cats = $stmt->fetchAll(PDO::FETCH_COLUMN);
            } 
            elseif ($action == 'get_series_categories') {
                $stmt = $pdo->query("SELECT DISTINCT category_id FROM series WHERE id IN (SELECT series_id FROM series_episodes WHERE stream_id IN ($allowed_streams_str))");
                $allowed_cats = $stmt->fetchAll(PDO::FETCH_COLUMN);
            }
            
            // CORTA AQUI: Se a lista de categorias permitidas estiver vazia, retorna vazio imediatamente!
            if (empty($allowed_cats)) {
                echo json_encode([]);
                exit;
            }
            
            $cat_in = implode(',', $allowed_cats);
            $cat_filter = "AND id IN ($cat_in)";
        }

        if ($action == 'get_vod_categories') $cat_type = 'movie';
        if ($action == 'get_series_categories') $cat_type = 'series';

        $cats = [];
        try {
            $stmt = $pdo->prepare("SELECT id as category_id, category_name, parent_id FROM stream_categories WHERE category_type = ? $cat_filter ORDER BY cat_order ASC");
            $stmt->execute([$cat_type]);
            $cats = $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            try {
                $stmt = $pdo->prepare("SELECT id as category_id, category_name, parent_id FROM stream_categories WHERE category_type = ? $cat_filter ORDER BY category_order ASC");
                $stmt->execute([$cat_type]);
                $cats = $stmt->fetchAll(PDO::FETCH_ASSOC);
            } catch (PDOException $e2) {
                $stmt = $pdo->prepare("SELECT id as category_id, category_name, parent_id FROM stream_categories WHERE category_type = ? $cat_filter ORDER BY category_name ASC");
                $stmt->execute([$cat_type]);
                $cats = $stmt->fetchAll(PDO::FETCH_ASSOC);
            }
        }
        
        foreach ($cats as &$c) { $c['parent_id'] = (int)$c['parent_id']; }
        echo json_encode($cats);
        break;

    // --- CANAIS AO VIVO ---
    case 'get_live_streams':
        if ($has_bouquet_filter) {
            $chk = $pdo->query("SELECT id FROM streams WHERE type IN (1, 3) AND id IN ($allowed_streams_str) LIMIT 1");
            if (!$chk->fetch()) { echo json_encode([]); exit; }
        }
        
        $cat_id = $_GET['category_id'] ?? null;
        $where = "WHERE type IN (1, 3)";
        if ($has_bouquet_filter) $where .= " AND id IN ($allowed_streams_str)";
        
        $params = [];
        if ($cat_id) { $where .= " AND category_id = ?"; $params[] = $cat_id; }

        $stmt = $pdo->prepare("SELECT id as stream_id, stream_display_name as name, stream_icon, category_id, stream_source, added FROM streams $where");
        $stmt->execute($params);
        $streams = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $resultado = [];
        $num = 1;
        foreach ($streams as $s) {
            $resultado[] = [
                "num" => $num++, "name" => $s['name'], "stream_type" => "live",
                "stream_id" => (int)$s['stream_id'], "stream_icon" => $s['stream_icon'],
                "epg_channel_id" => null, "added" => (string)$s['added'],
                "category_id" => (string)$s['category_id'], "custom_sid" => null,
                "tv_archive" => 0, "direct_source" => "", "tv_archive_duration" => 0
            ];
        }
        echo json_encode($resultado);
        break;

    // --- FILMES (VOD) ---
    case 'get_vod_streams':
        if ($has_bouquet_filter) {
            // CORTA AQUI: Se não tem nenhum filme no bouquet, nem processa!
            $chk = $pdo->query("SELECT id FROM streams WHERE type = 2 AND id IN ($allowed_streams_str) LIMIT 1");
            if (!$chk->fetch()) { echo json_encode([]); exit; }
        }
        
        $cat_id = $_GET['category_id'] ?? null;
        $where = "WHERE type = 2";
        if ($has_bouquet_filter) $where .= " AND id IN ($allowed_streams_str)";
        
        $params = [];
        if ($cat_id) { $where .= " AND category_id = ?"; $params[] = $cat_id; }

        $stmt = $pdo->prepare("SELECT id as stream_id, stream_display_name as name, stream_icon, category_id, stream_source, added, notes FROM streams $where");
        $stmt->execute($params);
        $streams = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $resultado = [];
        $num = 1;
        foreach ($streams as $s) {
            $resultado[] = [
                "num" => $num++, "name" => $s['name'], "stream_type" => "movie",
                "stream_id" => (int)$s['stream_id'], "stream_icon" => $s['stream_icon'],
                "rating" => "5", "rating_5based" => "2.5", "added" => (string)$s['added'],
                "category_id" => (string)$s['category_id'], "container_extension" => "mp4",
                "custom_sid" => null, "direct_source" => "", "plot" => (string)$s['notes'] 
            ];
        }
        echo json_encode($resultado);
        break;

    // --- INFORMAÇÕES DE UM FILME ESPECÍFICO ---
    case 'get_vod_info':
        $vod_id = $_GET['vod_id'] ?? 0;
        
        $where_vod = "WHERE id = ? AND type = 2";
        if ($has_bouquet_filter) $where_vod .= " AND id IN ($allowed_streams_str)";
        
        $stmtVod = $pdo->prepare("SELECT stream_display_name as name, stream_icon as cover, notes as plot, category_id, added FROM streams $where_vod");
        $stmtVod->execute([$vod_id]);
        $info = $stmtVod->fetch(PDO::FETCH_ASSOC);

        if (!$info) { echo json_encode([]); break; }

        $cover = (string)$info['cover'];
        $plot = (string)$info['plot'];
        $name = (string)$info['name'];

        $resultado = [
            "info" => [
                "kinopoisk_url" => "", "tmdb_id" => "", "name" => $name, "o_name" => $name,
                "cover_big" => $cover, "movie_image" => $cover, "releasedate" => "", 
                "episode_run_time" => "0", "youtube_trailer" => "", "director" => "",
                "actors" => "", "cast" => "", "description" => $plot, "plot" => $plot,
                "age" => "", "mpaa_rating" => "", "rating_count_kinopoisk" => 0,
                "country" => "", "genre" => "Diversos", "backdrop_path" => [$cover], 
                "duration_secs" => 0, "duration" => "00:00:00", "video" => [],
                "audio" => [], "bitrate" => 0, "rating" => "5"
            ],
            "movie_data" => [
                "stream_id" => (int)$vod_id, "name" => $name, "title" => $name,
                "added" => (string)$info['added'], "category_id" => (string)$info['category_id'],
                "container_extension" => "mp4", "custom_sid" => "", "direct_source" => ""
            ]
        ];
        echo json_encode($resultado);
        break;

    // --- SÉRIES ---
    case 'get_series':
        if ($has_bouquet_filter) {
            // CORTA AQUI: Se não tem nenhuma série no bouquet, nem processa!
            $chk = $pdo->query("SELECT id FROM series_episodes WHERE stream_id IN ($allowed_streams_str) LIMIT 1");
            if (!$chk->fetch()) { echo json_encode([]); exit; }
        }
        
        $cat_id = $_GET['category_id'] ?? null;
        
        $where = "WHERE 1=1";
        if ($has_bouquet_filter) {
            $where .= " AND id IN (SELECT series_id FROM series_episodes WHERE stream_id IN ($allowed_streams_str))";
        }
        $params = [];
        if ($cat_id) { $where .= " AND category_id = ?"; $params[] = $cat_id; }

        $stmt = $pdo->prepare("SELECT id as series_id, title as name, cover, plot as overview, category_id, last_modified FROM series $where");
        $stmt->execute($params);
        $series = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $resultado = [];
        $num = 1;
        foreach ($series as $s) {
            $resultado[] = [
                "num" => $num++, "name" => $s['name'], "series_id" => (int)$s['series_id'],
                "cover" => $s['cover'], "plot" => $s['overview'], "cast" => "",
                "director" => "", "genre" => "", "releaseDate" => "",
                "last_modified" => (string)$s['last_modified'], "rating" => "5",
                "rating_5based" => "2.5", "backdrop_path" => null, "youtube_trailer" => "",
                "episode_run_time" => "0", "category_id" => (string)$s['category_id']
            ];
        }
        echo json_encode($resultado);
        break;

    // --- EPISÓDIOS DA SÉRIE ---
    case 'get_series_info':
        $series_id = $_GET['series_id'] ?? 0;

        $stmtInfo = $pdo->prepare("SELECT title as name, cover, plot as overview, last_modified FROM series WHERE id = ?");
        $stmtInfo->execute([$series_id]);
        $info = $stmtInfo->fetch(PDO::FETCH_ASSOC);

        if (!$info) { echo json_encode([]); break; }

        $where_eps = "WHERE se.series_id = ?";
        if ($has_bouquet_filter) {
            $where_eps .= " AND s.id IN ($allowed_streams_str)";
        }

        $stmtEps = $pdo->prepare("
            SELECT se.season_num, se.sort as episode_num, s.id as stream_id, s.stream_display_name as title, s.stream_source, s.added 
            FROM series_episodes se 
            LEFT JOIN streams s ON se.stream_id = s.id 
            $where_eps
            ORDER BY se.season_num ASC, se.sort ASC
        ");
        $stmtEps->execute([$series_id]);
        $episodes_raw = $stmtEps->fetchAll(PDO::FETCH_ASSOC);

        $episodes_formatted = [];
        $seasons_array = [];
        $seasons_tracker = [];

        foreach ($episodes_raw as $ep) {
            $s_num = (int)$ep['season_num'];

            if (!isset($episodes_formatted[$s_num])) { $episodes_formatted[$s_num] = []; }

            if (!in_array($s_num, $seasons_tracker)) {
                $seasons_tracker[] = $s_num;
                $seasons_array[] = ["season_number" => $s_num];
            }

            $episodes_formatted[$s_num][] = [
                "id" => (string)$ep['stream_id'], "episode_num" => (string)$ep['episode_num'],
                "title" => $ep['title'], "container_extension" => "mp4",
                "info" => [ "plot" => "", "duration" => "" ], "custom_sid" => null,
                "added" => (string)$ep['added'], "season" => $s_num,
                "direct_source" => ""
            ];
        }

        $resultado = [
            "seasons" => $seasons_array,
            "info" => [
                "name" => $info['name'], "cover" => $info['cover'], "plot" => $info['overview'],
                "cast" => "", "director" => "", "genre" => "", "releaseDate" => "",
                "last_modified" => (string)$info['last_modified'], "rating" => "5",
                "rating_5based" => "2.5", "backdrop_path" => null, "youtube_trailer" => "",
                "episode_run_time" => "0", "category_id" => "0"
            ],
            "episodes" => (object)$episodes_formatted 
        ];
        echo json_encode($resultado);
        break;

    // --- AUTENTICAÇÃO PADRÃO ---
    default:
        $server_info = [
            "url" => $_SERVER['HTTP_HOST'], "port" => $_SERVER['SERVER_PORT'] ?? "80",
            "https_port" => "443", "server_protocol" => isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http",
            "rtmp_port" => "25462", "timezone" => "America/Sao_Paulo",
            "timestamp_now" => time(), "time_now" => date('Y-m-d H:i:s')
        ];

        $user_info = [
            "username" => $user['username'], "password" => $user['password'],
            "message" => "Welcome to Custom Panel", "auth" => 1, "status" => $status,
            "exp_date" => (string)$user['exp_date'], "is_trial" => "0", "active_cons" => "0",
            "created_at" => (string)$user['created_at'], "max_connections" => (string)$user['max_connections'],
            "allowed_output_formats" => ["m3u8", "ts"]
        ];

        echo json_encode(["user_info" => $user_info, "server_info" => $server_info]);
        break;
}
?>
