<?php
header('Content-Type: application/json; charset=utf-8');
error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('memory_limit', '512M');
set_time_limit(60);

$logFile = __DIR__ . '/../../logs/api_series.log';

function aw_log($msg) {
    global $logFile;
    @file_put_contents($logFile, '['.date('Y-m-d H:i:s').'] '.$msg.PHP_EOL, FILE_APPEND);
}
function aw_out($arr) {
    echo json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}
function aw_fail($msg, $detail = '') {
    aw_log($msg . ($detail ? ' | '.$detail : ''));
    aw_out(array('success'=>false, 'message'=>$msg, 'detail'=>$detail));
}
try {
    require_once __DIR__ . '/../../app/db.php';
} catch (Throwable $e) {
    aw_fail('Falha ao carregar db.php', $e->getMessage());
}
function aw_find_db() {
    if (function_exists('db')) {
        try {
            $d = db();
            if ($d instanceof PDO) return array('type'=>'pdo','db'=>$d);
            if (class_exists('mysqli') && $d instanceof mysqli) return array('type'=>'mysqli','db'=>$d);
        } catch (Throwable $e) {
            aw_fail('Função db() falhou', $e->getMessage());
        }
    }
    foreach ($GLOBALS as $v) {
        if ($v instanceof PDO) return array('type'=>'pdo','db'=>$v);
        if (class_exists('mysqli') && $v instanceof mysqli) return array('type'=>'mysqli','db'=>$v);
    }
    $configFile = __DIR__ . '/../../app/config.php';
    if (file_exists($configFile)) {
        $c = require $configFile;
        if (is_array($c) && isset($c['db_host'], $c['db_name'], $c['db_user'])) {
            $pass = isset($c['db_pass']) ? $c['db_pass'] : '';
            $dsn = "mysql:host={$c['db_host']};dbname={$c['db_name']};charset=utf8mb4";
            $pdo = new PDO($dsn, $c['db_user'], $pass, array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC));
            return array('type'=>'pdo','db'=>$pdo);
        }
    }
    aw_fail('Conexão do banco não encontrada');
}
function aw_db_row($sql, $params) {
    $found = aw_find_db();
    if ($found['type'] === 'pdo') {
        $st = $found['db']->prepare($sql);
        $st->execute($params);
        $row = $st->fetch(PDO::FETCH_ASSOC);
        return $row ? $row : null;
    }
    $mysqli = $found['db'];
    $st = $mysqli->prepare($sql);
    if (!$st) aw_fail('Erro mysqli prepare', $mysqli->error);
    if (count($params) > 0) {
        $types = str_repeat('s', count($params));
        $refs = array($types);
        foreach ($params as $i => $p) $refs[] = &$params[$i];
        call_user_func_array(array($st, 'bind_param'), $refs);
    }
    if (!$st->execute()) aw_fail('Erro mysqli execute', $st->error);
    $res = $st->get_result();
    $row = $res ? $res->fetch_assoc() : null;
    $st->close();
    return $row ? $row : null;
}
function aw_device($token) {
    if (!$token) aw_fail('token obrigatório');
    $sql = "SELECT d.*, s.base_url FROM roku_devices d LEFT JOIN dns_servers s ON s.id=d.dns_id WHERE d.token=? LIMIT 1";
    $d = aw_db_row($sql, array($token));
    if (!$d) aw_fail('aparelho não encontrado');
    if ($d['status'] !== 'active') aw_fail('aparelho não ativo', $d['status']);
    if (!empty($d['expires_at']) && strtotime($d['expires_at']) < time()) aw_fail('aparelho vencido');
    if (empty($d['base_url']) || empty($d['username']) || empty($d['password'])) aw_fail('DNS/usuário/senha não configurados');
    return $d;
}
function aw_get_json($url) {
    aw_log('GET '.$url);
    if (!function_exists('curl_init')) aw_fail('PHP cURL não instalado');
    $ch = curl_init($url);
    curl_setopt_array($ch, array(
        CURLOPT_RETURNTRANSFER=>true,
        CURLOPT_CONNECTTIMEOUT=>10,
        CURLOPT_TIMEOUT=>45,
        CURLOPT_FOLLOWLOCATION=>true,
        CURLOPT_SSL_VERIFYPEER=>false,
        CURLOPT_SSL_VERIFYHOST=>false,
        CURLOPT_USERAGENT=>'AWPlayerRoku/1.5.0'
    ));
    $raw = curl_exec($ch);
    $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err = curl_error($ch);
    curl_close($ch);
    if ($raw === false || $raw === '') aw_fail('DNS sem resposta', $err);
    if ($code >= 400) aw_fail('DNS retornou HTTP '.$code, substr($raw,0,300));
    $json = json_decode($raw, true);
    if (!is_array($json)) aw_fail('DNS retornou JSON inválido', substr($raw,0,300));
    return $json;
}
function aw_base($d) { return rtrim($d['base_url'], '/'); }
function aw_player_url($d, $action, $extra = array()) {
    $base = aw_base($d);
    $q = array_merge(array('username'=>$d['username'], 'password'=>$d['password'], 'action'=>$action), $extra);
    return $base . '/player_api.php?' . http_build_query($q);
}
function aw_abs_url($base, $url) {
    if (!$url) return '';
    if (preg_match('~^https?://~i', $url)) return $url;
    return rtrim($base, '/') . '/' . ltrim($url, '/');
}
function aw_s($v) {
    if ($v === null || is_array($v)) return '';
    return (string)$v;
}
function aw_normalize_series($base, $row) {
    $sid = isset($row['series_id']) ? $row['series_id'] : (isset($row['id']) ? $row['id'] : '');
    $name = isset($row['name']) ? $row['name'] : (isset($row['title']) ? $row['title'] : '');
    $cover = '';
    if (isset($row['cover'])) $cover = $row['cover'];
    if (!$cover && isset($row['cover_big'])) $cover = $row['cover_big'];
    if (!$cover && isset($row['stream_icon'])) $cover = $row['stream_icon'];
    $plot = isset($row['plot']) ? $row['plot'] : (isset($row['description']) ? $row['description'] : '');
    return array(
        'series_id'=>aw_s($sid),
        'id'=>aw_s($sid),
        'name'=>aw_s($name),
        'title'=>aw_s($name),
        'cover'=>aw_abs_url($base, aw_s($cover)),
        'cover_big'=>aw_abs_url($base, aw_s($cover)),
        'plot'=>aw_s($plot),
        'genre'=>isset($row['genre']) ? aw_s($row['genre']) : '',
        'rating'=>isset($row['rating']) ? aw_s($row['rating']) : '',
        'releaseDate'=>isset($row['releaseDate']) ? aw_s($row['releaseDate']) : (isset($row['releasedate']) ? aw_s($row['releasedate']) : '')
    );
}

$token = isset($_GET['token']) ? $_GET['token'] : '';
$cid = isset($_GET['category_id']) ? $_GET['category_id'] : '';
$d = aw_device($token);
$base = aw_base($d);
$json = aw_get_json(aw_player_url($d, 'get_series', array('category_id'=>$cid)));
$out = array();
foreach ($json as $row) {
    if (!is_array($row)) continue;
    $out[] = aw_normalize_series($base, $row);
    if (count($out) >= 300) break;
}
aw_out(array('success'=>true,'items'=>$out,'data'=>$out));
