<?php
session_start();

date_default_timezone_set('America/Sao_Paulo');

function db(){
    $path = __DIR__ . '/../api/.db.db';
    $db = new SQLite3($path);
    $db->busyTimeout(5000);
    $db->exec('PRAGMA journal_mode = WAL');
    $db->exec('CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, username TEXT, password TEXT)');
    $db->exec('CREATE TABLE IF NOT EXISTS dns(id INTEGER PRIMARY KEY NOT NULL, portal1 TEXT, portal2 TEXT, portal3 TEXT, portal4 TEXT, portal5 TEXT, portal6 TEXT, portal7 TEXT, portal8 TEXT, portal9 TEXT, portal10 TEXT, portal11 TEXT, portal12 TEXT, portal13 TEXT, portal14 TEXT, portal15 TEXT, portal16 TEXT, portal17 TEXT, portal18 TEXT, portal19 TEXT, portal20 TEXT)');
    ensure_column($db, 'dns', 'owner_type', "TEXT NOT NULL DEFAULT 'admin'");
    ensure_column($db, 'dns', 'owner_id', "INTEGER NOT NULL DEFAULT 0");
    $db->exec('DROP TABLE IF EXISTS dev');
    $db->exec('DROP TABLE IF EXISTS login_requests');

    $count = $db->querySingle('SELECT COUNT(*) FROM users');
    if ((int)$count === 0) {
        $stmt = $db->prepare('INSERT INTO users(id,username,password) VALUES(1,:u,:p)');
        $stmt->bindValue(':u','popplay',SQLITE3_TEXT);
        $stmt->bindValue(':p','popplay',SQLITE3_TEXT);
        $stmt->execute();
    }

    $db->exec('CREATE TABLE IF NOT EXISTS app_settings(id INTEGER PRIMARY KEY, app_password TEXT)');
    $db->exec("CREATE TABLE IF NOT EXISTS screen_messages(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT DEFAULT '',
        message TEXT NOT NULL,
        target_type TEXT NOT NULL DEFAULT 'global',
        target_value TEXT DEFAULT '',
        position TEXT NOT NULL DEFAULT 'top',
        speed INTEGER NOT NULL DEFAULT 18,
        is_active INTEGER NOT NULL DEFAULT 1,
        created_at TEXT DEFAULT CURRENT_TIMESTAMP,
        updated_at TEXT DEFAULT CURRENT_TIMESTAMP
    )");

    ensure_column($db, 'screen_messages', 'start_at', "TEXT DEFAULT ''");
    ensure_column($db, 'screen_messages', 'end_at', "TEXT DEFAULT ''");
    ensure_column($db, 'screen_messages', 'repeat_minutes', "INTEGER NOT NULL DEFAULT 0");
    ensure_column($db, 'screen_messages', 'priority', "TEXT NOT NULL DEFAULT 'normal'");
    ensure_column($db, 'screen_messages', 'color', "TEXT NOT NULL DEFAULT '#ffffff'");

    $db->exec("CREATE TABLE IF NOT EXISTS panel_notices(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT DEFAULT '',
        message TEXT NOT NULL DEFAULT '',
        target_type TEXT NOT NULL DEFAULT 'revenda',
        target_id INTEGER NOT NULL DEFAULT 0,
        is_active INTEGER NOT NULL DEFAULT 1,
        created_by TEXT DEFAULT 'admin',
        created_at TEXT DEFAULT CURRENT_TIMESTAMP,
        updated_at TEXT DEFAULT CURRENT_TIMESTAMP
    )");
    ensure_column($db, 'panel_notices', 'title', "TEXT DEFAULT ''");
    ensure_column($db, 'panel_notices', 'message', "TEXT NOT NULL DEFAULT ''");
    ensure_column($db, 'panel_notices', 'target_type', "TEXT NOT NULL DEFAULT 'revenda'");
    ensure_column($db, 'panel_notices', 'target_id', "INTEGER NOT NULL DEFAULT 0");
    ensure_column($db, 'panel_notices', 'is_active', "INTEGER NOT NULL DEFAULT 1");
    ensure_column($db, 'panel_notices', 'created_by', "TEXT DEFAULT 'admin'");
    ensure_column($db, 'panel_notices', 'created_at', "TEXT DEFAULT CURRENT_TIMESTAMP");
    ensure_column($db, 'panel_notices', 'updated_at', "TEXT DEFAULT CURRENT_TIMESTAMP");

    $db->exec("CREATE TABLE IF NOT EXISTS screen_message_hits(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        message_id INTEGER NOT NULL,
        client_key TEXT DEFAULT '',
        username TEXT DEFAULT '',
        android_id TEXT DEFAULT '',
        code TEXT DEFAULT '',
        ip TEXT DEFAULT '',
        user_agent TEXT DEFAULT '',
        shown_at TEXT DEFAULT CURRENT_TIMESTAMP
    )");


    ensure_panel_settings($db);

    $db->exec("CREATE TABLE IF NOT EXISTS screen_logo(
        id INTEGER PRIMARY KEY,
        is_active INTEGER NOT NULL DEFAULT 0,
        image_path TEXT DEFAULT '',
        position TEXT NOT NULL DEFAULT 'bottom_left',
        opacity INTEGER NOT NULL DEFAULT 45,
        width INTEGER NOT NULL DEFAULT 120,
        height INTEGER NOT NULL DEFAULT 60,
        target_type TEXT NOT NULL DEFAULT 'global',
        target_value TEXT DEFAULT '',
        updated_at TEXT DEFAULT CURRENT_TIMESTAMP
    )");


    $db->exec("CREATE TABLE IF NOT EXISTS client_online_status(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        usuario TEXT DEFAULT '',
        senha TEXT DEFAULT '',
        mac TEXT DEFAULT '',
        android_id TEXT DEFAULT '',
        canal TEXT DEFAULT '',
        canal_id TEXT DEFAULT '',
        ip TEXT DEFAULT '',
        modelo TEXT DEFAULT '',
        app_version TEXT DEFAULT '',
        status TEXT DEFAULT 'online',
        first_seen TEXT DEFAULT CURRENT_TIMESTAMP,
        ultima_atividade TEXT DEFAULT CURRENT_TIMESTAMP
    )");
    ensure_column($db, 'client_online_status', 'canal_id', "TEXT DEFAULT ''");
    ensure_column($db, 'client_online_status', 'app_version', "TEXT DEFAULT ''");

    $db->exec("CREATE TABLE IF NOT EXISTS revendas(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        nome TEXT NOT NULL DEFAULT '',
        usuario TEXT NOT NULL DEFAULT '',
        senha TEXT NOT NULL DEFAULT '',
        whatsapp TEXT DEFAULT '',
        email TEXT DEFAULT '',
        creditos INTEGER NOT NULL DEFAULT 0,
        is_active INTEGER NOT NULL DEFAULT 1,
        created_at TEXT DEFAULT CURRENT_TIMESTAMP,
        updated_at TEXT DEFAULT CURRENT_TIMESTAMP
    )");
    ensure_column($db, 'revendas', 'plano', "TEXT NOT NULL DEFAULT 'mensal'");
    ensure_column($db, 'revendas', 'started_at', "TEXT DEFAULT ''");
    ensure_column($db, 'revendas', 'expires_at', "TEXT DEFAULT ''");
    ensure_column($db, 'revendas', 'manual_blocked', "INTEGER NOT NULL DEFAULT 0");

    $db->exec("CREATE TABLE IF NOT EXISTS sub_revendas(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        revenda_id INTEGER NOT NULL DEFAULT 0,
        nome TEXT NOT NULL DEFAULT '',
        usuario TEXT NOT NULL DEFAULT '',
        senha TEXT NOT NULL DEFAULT '',
        whatsapp TEXT DEFAULT '',
        email TEXT DEFAULT '',
        creditos INTEGER NOT NULL DEFAULT 0,
        is_active INTEGER NOT NULL DEFAULT 1,
        created_at TEXT DEFAULT CURRENT_TIMESTAMP,
        updated_at TEXT DEFAULT CURRENT_TIMESTAMP
    )");
    ensure_column($db, 'sub_revendas', 'plano', "TEXT NOT NULL DEFAULT 'mensal'");
    ensure_column($db, 'sub_revendas', 'started_at', "TEXT DEFAULT ''");
    ensure_column($db, 'sub_revendas', 'expires_at', "TEXT DEFAULT ''");
    ensure_column($db, 'sub_revendas', 'manual_blocked', "INTEGER NOT NULL DEFAULT 0");

    $db->exec("CREATE TABLE IF NOT EXISTS client_macs(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        mac TEXT NOT NULL DEFAULT '',
        cliente_nome TEXT DEFAULT '',
        usuario TEXT DEFAULT '',
        senha TEXT DEFAULT '',
        owner_type TEXT NOT NULL DEFAULT 'admin',
        owner_id INTEGER NOT NULL DEFAULT 0,
        notes TEXT DEFAULT '',
        is_active INTEGER NOT NULL DEFAULT 1,
        created_at TEXT DEFAULT CURRENT_TIMESTAMP,
        updated_at TEXT DEFAULT CURRENT_TIMESTAMP
    )");
    ensure_column($db, 'client_macs', 'notes', "TEXT DEFAULT ''");
    ensure_column($db, 'client_macs', 'status', "TEXT NOT NULL DEFAULT 'ativo'");
    ensure_column($db, 'client_macs', 'modelo', "TEXT DEFAULT ''");
    ensure_column($db, 'client_macs', 'dns_service', "TEXT DEFAULT 'off'");
    ensure_column($db, 'client_macs', 'dns_active', "INTEGER DEFAULT 0");
    ensure_column($db, 'client_macs', 'dns_primary', "TEXT DEFAULT ''");
    ensure_column($db, 'client_macs', 'dns_secondary', "TEXT DEFAULT ''");
    ensure_column($db, 'client_macs', 'app_version', "TEXT DEFAULT ''");
    ensure_column($db, 'client_macs', 'ip', "TEXT DEFAULT ''");
    ensure_column($db, 'client_macs', 'first_seen', "TEXT DEFAULT ''");
    ensure_column($db, 'client_macs', 'last_seen', "TEXT DEFAULT ''");
    ensure_column($db, 'client_macs', 'expires_at', "TEXT DEFAULT ''");
    ensure_column($db, 'client_macs', 'auto_blocked', "INTEGER NOT NULL DEFAULT 0");
    ensure_column($db, 'client_macs', 'discount_note', "TEXT DEFAULT ''");

    $db->exec("CREATE TABLE IF NOT EXISTS app_appearance(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        owner_type TEXT NOT NULL DEFAULT 'global',
        owner_id INTEGER NOT NULL DEFAULT 0,
        logo_path TEXT DEFAULT '',
        wallpaper_path TEXT DEFAULT '',
        is_active INTEGER NOT NULL DEFAULT 1,
        updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
        UNIQUE(owner_type, owner_id)
    )");
    ensure_column($db, 'app_appearance', 'logo_path', "TEXT DEFAULT ''");
    ensure_column($db, 'app_appearance', 'wallpaper_path', "TEXT DEFAULT ''");
    ensure_column($db, 'app_appearance', 'is_active', "INTEGER NOT NULL DEFAULT 1");

    $exists_logo = $db->querySingle('SELECT COUNT(*) FROM screen_logo WHERE id=1');
    if((int)$exists_logo===0){
        $db->exec("INSERT INTO screen_logo(id,is_active,image_path,position,opacity,width,height,target_type,target_value) VALUES(1,0,'','bottom_left',45,120,60,'global','')");
    }

    $exists=$db->querySingle('SELECT COUNT(*) FROM app_settings');
    if((int)$exists===0){$db->exec("INSERT INTO app_settings(id,app_password) VALUES(1,'123456')");}
    return $db;
}

function ensure_column($db, $table, $column, $definition){
    $table = preg_replace('/[^a-zA-Z0-9_]/', '', $table);
    $column = preg_replace('/[^a-zA-Z0-9_]/', '', $column);
    $exists = false;
    $res = $db->query("PRAGMA table_info($table)");
    while ($row = $res->fetchArray(SQLITE3_ASSOC)) {
        if (($row['name'] ?? '') === $column) { $exists = true; break; }
    }
    if (!$exists) {
        $db->exec("ALTER TABLE $table ADD COLUMN $column $definition");
    }
}



function ensure_panel_settings($db){
    $db->exec("CREATE TABLE IF NOT EXISTS panel_settings(
        setting_key TEXT PRIMARY KEY,
        setting_value TEXT DEFAULT ''
    )");
    $defaults = [
        'history_auto_clean_enabled' => '0',
        'history_retention_days' => '30',
        'history_last_clean' => '',
        'expiry_alert_enabled' => '1',
        'expiry_auto_block_enabled' => '1',
        'expiry_discount_enabled' => '1',
        'expiry_discount_days' => '7',
        'expiry_discount_message' => '💰 Pagando antes do vencimento você pode ganhar desconto. Fale com sua revenda.',
        'expiry_msg_7' => '⚠️ Seu acesso vence em 7 dias. Evite bloqueio renovando antecipadamente.',
        'expiry_msg_5' => '⚠️ Seu acesso vence em 5 dias. Renove para continuar assistindo sem interrupções.',
        'expiry_msg_3' => '⚠️ Seu acesso vence em 3 dias. Regularize para evitar bloqueio.',
        'expiry_msg_1' => '⚠️ Seu acesso vence amanhã. Renove agora para não perder o sinal.',
        'expiry_msg_blocked' => '🚫 Seu acesso venceu e foi bloqueado. Fale com sua revenda para renovar.',
        'banner_position' => 'top',
        'banner_duration' => '12'
    ];
    foreach($defaults as $k=>$v){
        $stmt=$db->prepare('INSERT OR IGNORE INTO panel_settings(setting_key,setting_value) VALUES(:k,:v)');
        $stmt->bindValue(':k',$k,SQLITE3_TEXT);
        $stmt->bindValue(':v',$v,SQLITE3_TEXT);
        $stmt->execute();
    }
}

function get_setting($key, $default=''){
    $db=db();
    ensure_panel_settings($db);
    $stmt=$db->prepare('SELECT setting_value FROM panel_settings WHERE setting_key=:k');
    $stmt->bindValue(':k',$key,SQLITE3_TEXT);
    $res=$stmt->execute();
    $row=$res ? $res->fetchArray(SQLITE3_ASSOC) : false;
    return $row ? (string)$row['setting_value'] : $default;
}

function set_setting($key, $value){
    $db=db();
    ensure_panel_settings($db);
    $stmt=$db->prepare('INSERT OR REPLACE INTO panel_settings(setting_key,setting_value) VALUES(:k,:v)');
    $stmt->bindValue(':k',$key,SQLITE3_TEXT);
    $stmt->bindValue(':v',(string)$value,SQLITE3_TEXT);
    $stmt->execute();
}

function cleanup_message_history($force=false){
    $db=db();
    ensure_panel_settings($db);
    $enabled = (int)get_setting('history_auto_clean_enabled','0');
    $days = (int)get_setting('history_retention_days','30');
    if (!$force && $enabled !== 1) return 0;
    if ($days <= 0) return 0;
    $cutoff = date('Y-m-d H:i:s', strtotime('-'.$days.' days'));
    $before = (int)$db->querySingle('SELECT COUNT(*) FROM screen_message_hits WHERE shown_at < \'' . SQLite3::escapeString($cutoff) . '\'');
    $stmt=$db->prepare('DELETE FROM screen_message_hits WHERE shown_at < :cutoff');
    $stmt->bindValue(':cutoff',$cutoff,SQLITE3_TEXT);
    $stmt->execute();
    set_setting('history_last_clean', date('Y-m-d H:i:s'));
    return $before;
}

function get_app_password(){ $db=db(); return (string)$db->querySingle('SELECT app_password FROM app_settings WHERE id=1'); }
function set_app_password($p){ $db=db(); $st=$db->prepare('UPDATE app_settings SET app_password=:p WHERE id=1'); $st->bindValue(':p',$p,SQLITE3_TEXT); $st->execute(); }

function password_ok($input, $stored){
    $input = (string)$input;
    $stored = (string)$stored;
    if (preg_match('/^\$2y\$|^\$argon2/', $stored)) {
        return password_verify($input, $stored);
    }
    return hash_equals($stored, $input);
}

function logged(){ return !empty($_SESSION['loggedin']); }
function require_login(){ if(!logged()){ header('Location: index.php'); exit; } }
function h($v){ return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); }

function normalize_portal($url){
    $url = trim((string)$url);
    if ($url === '') return '';
    if (!preg_match('~^https?://~i', $url)) $url = 'http://' . $url;
    return rtrim($url, '/');
}

function dns_owner_type(){
    $role = current_role();
    if($role === 'revenda') return 'revenda';
    if($role === 'subrevenda') return 'subrevenda';
    return 'admin';
}
function dns_owner_id(){
    $role = current_role();
    if($role === 'revenda' || $role === 'subrevenda') return current_owner_id();
    return 0;
}
function get_portals($owner_type=null, $owner_id=null){
    $db = db();
    if($owner_type === null) $owner_type = dns_owner_type();
    if($owner_id === null) $owner_id = dns_owner_id();
    $owner_type = (string)$owner_type;
    $owner_id = (int)$owner_id;

    $st=$db->prepare('SELECT * FROM dns WHERE owner_type=:ot AND owner_id=:oid ORDER BY id LIMIT 1');
    $st->bindValue(':ot',$owner_type,SQLITE3_TEXT);
    $st->bindValue(':oid',$owner_id,SQLITE3_INTEGER);
    $row=$st->execute()->fetchArray(SQLITE3_ASSOC);

    // Se revenda/subrevenda ainda não tiver DNS próprio, começa vazio e não mistura com admin.
    if(!$row) $row = [];

    $portals=[];
    for($i=1;$i<=20;$i++){
        $v = normalize_portal($row['portal'.$i] ?? '');
        if($v !== '') $portals[] = $v;
    }
    return $portals;
}
function get_dns_row($owner_type=null,$owner_id=null){
    $db=db();
    if($owner_type === null) $owner_type=dns_owner_type();
    if($owner_id === null) $owner_id=dns_owner_id();
    $st=$db->prepare('SELECT * FROM dns WHERE owner_type=:ot AND owner_id=:oid ORDER BY id LIMIT 1');
    $st->bindValue(':ot',(string)$owner_type,SQLITE3_TEXT);
    $st->bindValue(':oid',(int)$owner_id,SQLITE3_INTEGER);
    $row=$st->execute()->fetchArray(SQLITE3_ASSOC);
    return $row ?: [];
}
function save_dns_row($portals,$owner_type=null,$owner_id=null){
    $db=db();
    if($owner_type === null) $owner_type=dns_owner_type();
    if($owner_id === null) $owner_id=dns_owner_id();
    $owner_type=(string)$owner_type;
    $owner_id=(int)$owner_id;
    $st=$db->prepare('DELETE FROM dns WHERE owner_type=:ot AND owner_id=:oid');
    $st->bindValue(':ot',$owner_type,SQLITE3_TEXT);
    $st->bindValue(':oid',$owner_id,SQLITE3_INTEGER);
    $st->execute();

    $cols=['owner_type','owner_id']; $vals=[':owner_type',':owner_id'];
    for($i=1;$i<=20;$i++){ $cols[]='portal'.$i; $vals[]=':p'.$i; }
    $stmt=$db->prepare('INSERT INTO dns('.implode(',',$cols).') VALUES('.implode(',',$vals).')');
    $stmt->bindValue(':owner_type',$owner_type,SQLITE3_TEXT);
    $stmt->bindValue(':owner_id',$owner_id,SQLITE3_INTEGER);
    for($i=1;$i<=20;$i++){
        $stmt->bindValue(':p'.$i, normalize_portal($portals[$i] ?? ''), SQLITE3_TEXT);
    }
    $stmt->execute();
}
function dns_owner_label(){
    $type=dns_owner_type(); $id=dns_owner_id();
    if($type==='admin') return 'Admin / DNS Geral';
    return get_owner_label($type,$id);
}

function clients_online_timeout_seconds(){ return 120; }

function cleanup_old_online_clients(){
    $db = db();
    $cutoff = date('Y-m-d H:i:s', time() - 86400);
    $stmt = $db->prepare('DELETE FROM client_online_status WHERE ultima_atividade < :cutoff');
    $stmt->bindValue(':cutoff', $cutoff, SQLITE3_TEXT);
    $stmt->execute();
}

function count_online_clients(){
    $db = db();
    $cutoff = date('Y-m-d H:i:s', time() - clients_online_timeout_seconds());
    $stmt = $db->prepare('SELECT COUNT(*) FROM client_online_status WHERE ultima_atividade >= :cutoff');
    $stmt->bindValue(':cutoff', $cutoff, SQLITE3_TEXT);
    $res = $stmt->execute();
    $row = $res ? $res->fetchArray(SQLITE3_NUM) : [0];
    return (int)($row[0] ?? 0);
}


function normalize_mac_value($mac){
    $mac = strtoupper(trim((string)$mac));
    $mac = str_replace(['-', '.', ' '], ':', $mac);
    $mac = preg_replace('/:+/', ':', $mac);
    return trim($mac, ':');
}

function get_owner_label($owner_type, $owner_id){
    $owner_type = (string)$owner_type;
    $owner_id = (int)$owner_id;
    if ($owner_type === 'admin') return 'Admin';
    $db = db();
    if ($owner_type === 'revenda') {
        $st=$db->prepare('SELECT nome,usuario FROM revendas WHERE id=:id');
        $st->bindValue(':id',$owner_id,SQLITE3_INTEGER);
        $r=$st->execute()->fetchArray(SQLITE3_ASSOC);
        return $r ? 'Revenda: '.($r['nome'] ?: $r['usuario']) : 'Revenda removida';
    }
    if ($owner_type === 'subrevenda') {
        $st=$db->prepare('SELECT nome,usuario FROM sub_revendas WHERE id=:id');
        $st->bindValue(':id',$owner_id,SQLITE3_INTEGER);
        $r=$st->execute()->fetchArray(SQLITE3_ASSOC);
        return $r ? 'Sub Revenda: '.($r['nome'] ?: $r['usuario']) : 'Sub revenda removida';
    }
    return 'Indefinido';
}

function count_revendas(){ return (int)db()->querySingle('SELECT COUNT(*) FROM revendas'); }
function count_sub_revendas(){ return (int)db()->querySingle('SELECT COUNT(*) FROM sub_revendas'); }
function count_client_macs(){ return (int)db()->querySingle('SELECT COUNT(*) FROM client_macs'); }

function plan_options(){
    return [
        'teste_1_dia' => 'Teste 1 Dia',
        'mensal' => 'Mensal',
        '3_meses' => '3 Meses',
        '6_meses' => '6 Meses',
        '1_ano' => '1 Ano',
        'ilimitado' => 'Ilimitado'
    ];
}

function plan_label($plan){
    $opts = plan_options();
    return $opts[$plan] ?? 'Mensal';
}

function calculate_expiry_by_plan($plan, $start_ts=null){
    $start_ts = $start_ts ?: time();
    if ($plan === 'ilimitado') return '';
    $dt = new DateTime('@'.$start_ts);
    $dt->setTimezone(new DateTimeZone('America/Sao_Paulo'));
    switch($plan){
        case 'teste_1_dia': $dt->modify('+1 day'); break;
        case '3_meses': $dt->modify('+3 months'); break;
        case '6_meses': $dt->modify('+6 months'); break;
        case '1_ano': $dt->modify('+1 year'); break;
        case 'mensal':
        default: $dt->modify('+1 month'); break;
    }
    return $dt->format('Y-m-d H:i:s');
}

function is_plan_expired($row){
    $plan = $row['plano'] ?? 'mensal';
    if ($plan === 'ilimitado') return false;
    $expires = trim((string)($row['expires_at'] ?? ''));
    if ($expires === '') return false;
    return strtotime($expires) <= time();
}

function plan_status_html($row){
    if ((int)($row['manual_blocked'] ?? 0) === 1 || (int)($row['is_active'] ?? 1) !== 1) return '<span class="bad">Bloqueado</span>';
    if (is_plan_expired($row)) return '<span class="bad">Vencido</span>';
    return '<span class="pill">Ativo</span>';
}

function remaining_seconds($row){
    $plan = $row['plano'] ?? 'mensal';
    if ($plan === 'ilimitado') return -1;
    $expires = trim((string)($row['expires_at'] ?? ''));
    if ($expires === '') return 0;
    return max(0, strtotime($expires) - time());
}

function render_countdown($row){
    $plan = $row['plano'] ?? 'mensal';
    if ($plan === 'ilimitado') return '<span class="pill">♾ Ilimitado</span>';
    $sec = remaining_seconds($row);
    if ($sec <= 0) return '<span class="bad">Vencido</span>';
    return '<span class="countdown" data-seconds="'.(int)$sec.'">Carregando...</span>';
}

function plan_countdown_script(){
    return '<script>
    function fmtTimePlan(total){
        total = Math.max(0, parseInt(total||0,10));
        var d=Math.floor(total/86400); total%=86400;
        var h=Math.floor(total/3600); total%=3600;
        var m=Math.floor(total/60); var s=total%60;
        return d+"d "+String(h).padStart(2,"0")+"h "+String(m).padStart(2,"0")+"m "+String(s).padStart(2,"0")+"s";
    }
    function tickPlanCounters(){
        document.querySelectorAll(".countdown").forEach(function(el){
            var sec=parseInt(el.getAttribute("data-seconds")||"0",10);
            if(sec<=0){ el.innerHTML="<span class=\\"bad\\">Vencido</span>"; return; }
            el.textContent=fmtTimePlan(sec);
            el.setAttribute("data-seconds", sec-1);
        });
    }
    tickPlanCounters(); setInterval(tickPlanCounters,1000);
    </script>';
}




function current_role(){
    return $_SESSION['role'] ?? 'admin';
}
function is_admin(){
    return current_role() === 'admin';
}

function expiry_days_left($expires_at){
    $expires_at = trim((string)$expires_at);
    if ($expires_at === '') return null;
    $today = new DateTime(date('Y-m-d'));
    $expire = new DateTime(substr($expires_at, 0, 10));
    return (int)$today->diff($expire)->format('%r%a');
}

function expiry_auto_messages_for_device($device_key){
    $device_key = normalize_mac_value($device_key);
    if ($device_key === '') return [];
    $db = db();
    $st=$db->prepare('SELECT * FROM client_macs WHERE mac=:mac LIMIT 1');
    $st->bindValue(':mac',$device_key,SQLITE3_TEXT);
    $r=$st->execute()->fetchArray(SQLITE3_ASSOC);
    if(!$r) return [];

    $expires_at = trim((string)($r['expires_at'] ?? ''));
    if($expires_at === '') return [];

    $days = expiry_days_left($expires_at);
    if($days === null) return [];

    $items = [];
    $now = date('Y-m-d H:i:s');

    if((int)get_setting('expiry_auto_block_enabled','1') === 1 && $days < 0 && ((int)($r['is_active'] ?? 1) === 1 || ($r['status'] ?? '') !== 'bloqueado')){
        $up=$db->prepare("UPDATE client_macs SET is_active=0,status='bloqueado',auto_blocked=1,updated_at=:now WHERE id=:id");
        $up->bindValue(':now',$now,SQLITE3_TEXT);
        $up->bindValue(':id',(int)$r['id'],SQLITE3_INTEGER);
        $up->execute();
        $r['is_active']=0; $r['status']='bloqueado';
    }

    if((int)get_setting('expiry_alert_enabled','1') !== 1) return [];

    if($days < 0 || (int)($r['is_active'] ?? 0) !== 1 || (($r['status'] ?? 'ativo') === 'bloqueado')){
        $items[] = [
            'id' => 900001,
            'title' => 'Acesso bloqueado',
            'message' => get_setting('expiry_msg_blocked','🚫 Seu acesso venceu e foi bloqueado. Fale com sua revenda para renovar.'),
            'target_type' => 'auto_expired',
            'position' => 'center',
            'speed' => 18,
            'repeat_minutes' => 0,
            'priority' => 'urgente',
            'color' => '#ff5d6c',
            'start_at' => '',
            'end_at' => '',
            'updated_at' => $now
        ];
        return $items;
    }

    $map = [7=>'expiry_msg_7',5=>'expiry_msg_5',3=>'expiry_msg_3',1=>'expiry_msg_1'];
    if(isset($map[$days])){
        $items[] = [
            'id' => 900000 + $days,
            'title' => 'Aviso de vencimento',
            'message' => get_setting($map[$days], ''),
            'target_type' => 'auto_expiry',
            'position' => 'top',
            'speed' => 18,
            'repeat_minutes' => 720,
            'priority' => 'urgente',
            'color' => '#ffba26',
            'start_at' => '',
            'end_at' => '',
            'updated_at' => $now
        ];
    }

    if((int)get_setting('expiry_discount_enabled','1') === 1){
        $discountDays = (int)get_setting('expiry_discount_days','7');
        if($discountDays > 0 && $days >= 1 && $days <= $discountDays){
            $items[] = [
                'id' => 900100,
                'title' => 'Desconto antecipado',
                'message' => get_setting('expiry_discount_message','💰 Pagando antes do vencimento você pode ganhar desconto. Fale com sua revenda.'),
                'target_type' => 'auto_discount',
                'position' => 'bottom',
                'speed' => 18,
                'repeat_minutes' => 720,
                'priority' => 'normal',
                'color' => '#38e07d',
                'start_at' => '',
                'end_at' => '',
                'updated_at' => $now
            ];
        }
    }

    return $items;
}

function expiry_auto_process_all(){
    $db = db();
    if((int)get_setting('expiry_auto_block_enabled','1') !== 1) return 0;
    $today = date('Y-m-d');
    $now = date('Y-m-d H:i:s');
    $st=$db->prepare("UPDATE client_macs SET is_active=0,status='bloqueado',auto_blocked=1,updated_at=:now WHERE expires_at<>'' AND date(expires_at) < date(:today) AND is_active=1");
    $st->bindValue(':now',$now,SQLITE3_TEXT);
    $st->bindValue(':today',$today,SQLITE3_TEXT);
    $st->execute();
    return $db->changes();
}

function current_owner_type(){
    return $_SESSION['owner_type'] ?? 'admin';
}
function current_owner_id(){
    return (int)($_SESSION['owner_id'] ?? 0);
}
function require_admin(){
    require_login();
    if(!is_admin()){
        header('Location: meus_avisos.php');
        exit;
    }
}
function panel_notice_target_label($type, $id){
    $type = (string)$type;
    $id = (int)$id;
    if($type === 'revenda'){
        $db = db();
        $st=$db->prepare('SELECT nome,usuario FROM revendas WHERE id=:id');
        $st->bindValue(':id',$id,SQLITE3_INTEGER);
        $r=$st->execute()->fetchArray(SQLITE3_ASSOC);
        return $r ? 'Revenda: '.($r['nome'] ?: $r['usuario']) : 'Revenda removida';
    }
    if($type === 'subrevenda'){
        $db = db();
        $st=$db->prepare('SELECT nome,usuario FROM sub_revendas WHERE id=:id');
        $st->bindValue(':id',$id,SQLITE3_INTEGER);
        $r=$st->execute()->fetchArray(SQLITE3_ASSOC);
        return $r ? 'Sub Revenda: '.($r['nome'] ?: $r['usuario']) : 'Sub revenda removida';
    }
    return 'Indefinido';
}
function count_my_panel_notices(){
    if(!logged()) return 0;
    $type = current_owner_type();
    $id = current_owner_id();
    if($type === 'admin') return 0;
    $db = db();
    $st=$db->prepare('SELECT COUNT(*) FROM panel_notices WHERE is_active=1 AND target_type=:t AND target_id=:id');
    $st->bindValue(':t',$type,SQLITE3_TEXT);
    $st->bindValue(':id',$id,SQLITE3_INTEGER);
    return (int)$st->execute()->fetchArray(SQLITE3_NUM)[0];
}
