<?php
declare(strict_types=1);

session_start();
date_default_timezone_set('America/Sao_Paulo');

if (isset($_SESSION["panel_user"])) {
    header("Location: dashboard.php");
    exit;
}

function getRealIP(){
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) return $_SERVER['HTTP_CLIENT_IP'];
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) return trim(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]);
    return $_SERVER['REMOTE_ADDR'] ?? "0.0.0.0";
}

function csrf_token(){
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

function csrf_check($token){
    return isset($_SESSION['csrf_token']) && is_string($token) && hash_equals($_SESSION['csrf_token'], $token);
}

function rate_limit_login(){
    if (!isset($_SESSION['login_attempts'])) $_SESSION['login_attempts'] = 0;
    if (!isset($_SESSION['login_block_until'])) $_SESSION['login_block_until'] = 0;

    $now = time();
    if ($_SESSION['login_block_until'] > $now) return false;

    return true;
}

function rate_limit_fail(){
    $now = time();
    $_SESSION['login_attempts'] = ($_SESSION['login_attempts'] ?? 0) + 1;

    if ($_SESSION['login_attempts'] >= 6) {
        $_SESSION['login_block_until'] = $now + 45;
        $_SESSION['login_attempts'] = 0;
    }
}

function rate_limit_success(){
    $_SESSION['login_attempts'] = 0;
    $_SESSION['login_block_until'] = 0;
}

function safeText($s){
    return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
}

function checkPasswordCompat(string $senhaInformada, string $senhaBanco): bool
{
    $senhaBanco = (string)$senhaBanco;

    if ($senhaBanco === "") return false;

    $info = password_get_info($senhaBanco);

    if (!empty($info["algo"]) && (int)$info["algo"] !== 0) {
        return password_verify($senhaInformada, $senhaBanco);
    }

    if (strlen($senhaBanco) === 32 && ctype_xdigit($senhaBanco)) {
        return hash_equals(strtolower($senhaBanco), md5($senhaInformada));
    }

    return hash_equals($senhaBanco, $senhaInformada);
}

function sqliteExecRetry(PDO $db, string $sql, array $params = [], int $tries = 6, int $sleepMs = 150): bool
{
    for ($i = 0; $i < $tries; $i++) {
        try {
            $st = $db->prepare($sql);
            return $st->execute($params);
        } catch (PDOException $e) {
            $msg = strtolower($e->getMessage());
            if (str_contains($msg, "database is locked") || str_contains($msg, "locked")) {
                usleep($sleepMs * 1000);
                continue;
            }
            throw $e;
        }
    }
    return false;
}

$db = new PDO("sqlite:" . dirname(__DIR__) . "/api/db.db");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$db->setAttribute(PDO::ATTR_TIMEOUT, 5);

$db->exec("PRAGMA busy_timeout = 8000");
$db->exec("PRAGMA journal_mode = WAL");
$db->exec("PRAGMA synchronous = NORMAL");

require_once dirname(__DIR__) . "/includes/revenda_schema.php";
revenda_ensure_schema($db);

$panelIdentityPath = dirname(__DIR__) . "/api/panel_identity.json";
$panelName = "THEFULL TV";

if (is_file($panelIdentityPath)) {
    $panelIdentityRaw = @file_get_contents($panelIdentityPath);
    $panelIdentity = json_decode((string)$panelIdentityRaw, true);
    if (is_array($panelIdentity) && isset($panelIdentity["name"])) {
        $candidateName = trim((string)$panelIdentity["name"]);
        if ($candidateName !== "") {
            $panelName = $candidateName;
        }
    }
}

$panelLogoFile = dirname(__DIR__) . "/api/img/logo.png";
$panelLogoVersion = is_file($panelLogoFile) ? (string)filemtime($panelLogoFile) : (string)time();

$error = "";

if (isset($_POST["login"])) {
    if (!rate_limit_login()) {
        $error = "Muitas tentativas. Aguarde alguns segundos e tente novamente.";
    } else {
        $u = trim((string)($_POST["username"] ?? ""));
        $p = trim((string)($_POST["password"] ?? ""));
        $csrf = (string)($_POST["csrf_token"] ?? "");

        if (!csrf_check($csrf)) {
            $error = "Falha de segurança (CSRF). Recarregue a página.";
        } else {
            if ($u === "" || $p === "") {
                $error = "Preencha usuário e senha";
            } else {

                $user = null;
                $tipo = "";

                $stmt = $db->prepare("SELECT id, username, password FROM panel_users WHERE username=? LIMIT 1");
                $stmt->execute([$u]);
                $panelUser = $stmt->fetch();

                if ($panelUser) {
                    $senhaBanco = (string)($panelUser["password"] ?? "");
                    if (checkPasswordCompat($p, $senhaBanco)) {
                        $user = $panelUser;
                        $tipo = "admin";

                        if (password_get_info($senhaBanco)["algo"] === 0) {
                            try {
                                $newHash = password_hash($p, PASSWORD_DEFAULT);
                                $db->beginTransaction();
                                $db->exec("BEGIN IMMEDIATE");
                                sqliteExecRetry($db, "UPDATE panel_users SET password=? WHERE id=?", [$newHash, (int)$panelUser["id"]], 6, 160);
                                $db->commit();
                            } catch (Throwable $e) {
                                if ($db->inTransaction()) $db->rollBack();
                            }
                        }
                    }
                }

                if (!$user) {
                    $stmt2 = $db->prepare("SELECT id, username, password, status, vencimento FROM revendedores WHERE username=? AND (status IS NULL OR status='' OR status='ativo') LIMIT 1");
                    $stmt2->execute([$u]);
                    $revUser = $stmt2->fetch();

                    if ($revUser && !revenda_is_expired($revUser["vencimento"] ?? "")) {
                        $senhaBanco = (string)($revUser["password"] ?? "");
                        if (checkPasswordCompat($p, $senhaBanco)) {
                            $user = $revUser;
                            $tipo = "revendedor";

                            if (password_get_info($senhaBanco)["algo"] === 0) {
                                try {
                                    $newHash = password_hash($p, PASSWORD_DEFAULT);
                                    $db->beginTransaction();
                                    $db->exec("BEGIN IMMEDIATE");
                                    sqliteExecRetry($db, "UPDATE revendedores SET password=? WHERE id=?", [$newHash, (int)$revUser["id"]], 6, 160);
                                    $db->commit();
                                } catch (Throwable $e) {
                                    if ($db->inTransaction()) $db->rollBack();
                                }
                            }
                        }
                    }
                }

                $ip = getRealIP();

                $country = "Unknown";
                $state   = "Unknown";
                $isp     = "Unknown";

                $ctx = stream_context_create([
                    "http" => [
                        "timeout" => 2,
                        "ignore_errors" => true,
                        "header" => "User-Agent: THEFULLTV-PANEL\r\n"
                    ],
                    "ssl" => [
                        "verify_peer" => true,
                        "verify_peer_name" => true
                    ]
                ]);

                $detailsRaw = @file_get_contents("https://ipinfo.io/" . urlencode($ip) . "/json", false, $ctx);
                if ($detailsRaw) {
                    $details = json_decode($detailsRaw);
                    if (is_object($details)) {
                        $country = $details->country ?? "Unknown";
                        $state   = $details->region ?? "Unknown";
                        $isp     = preg_replace("/AS\\d+\\s/", "", $details->org ?? "Unknown");
                    }
                }

                if ($user) {
                    session_regenerate_id(true);

                    $_SESSION["panel_user"] = $user["username"];
                    $_SESSION["tipo_user"]  = $tipo;

                    if ($tipo === "admin") {
                        $_SESSION["panel_id"] = $user["id"];
                    } else {
                        $_SESSION["revendedor_id"] = $user["id"];
                    }

                    rate_limit_success();

                    if ($tipo === "revendedor") {
                        header("Location: revenda_clientes.php");
                        exit;
                    }

                    header("Location: dashboard.php");
                    exit;

                } else {
                    rate_limit_fail();
                    $error = "Usuário ou senha inválidos";
                    try {
                        sqliteExecRetry($db, "INSERT INTO panel_logs(date,access,ip,country,state,isp) VALUES(?,?,?,?,?,?)", [date("d/m/Y H:i:s"), "Login inválido", $ip, $country, $state, $isp], 6, 150);
                    } catch (Throwable $e) {}
                }
            }
        }
    }
}
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#070b12">
<title><?= safeText($panelName) ?> • Acesso ao painel</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link href="https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
<link href="assets/css/pages/index.css?v=<?= is_file(dirname(__DIR__) . '/assets/css/pages/index.css') ? (int)filemtime(dirname(__DIR__) . '/assets/css/pages/index.css') : time() ?>" rel="stylesheet">
</head>
<body>
<main class="login-shell">
  <section class="login-visual" aria-hidden="true">
    <div class="visual-top">
      <div class="brand">
        <span class="brand-logo"><img src="api/img/logo.png?v=<?= safeText($panelLogoVersion) ?>" alt=""></span>
        <span class="brand-copy"><strong><?= safeText($panelName) ?></strong><small>Painel administrativo</small></span>
      </div>
    </div>
    <div class="visual-content">
      <span class="visual-kicker"><span></span> Ambiente seguro e integrado</span>
      <h1>Controle completo em uma interface simples.</h1>
      <p>Gerencie clientes, revendas, aplicativos, servidores e acessos em um painel organizado para funcionar bem no computador, tablet e celular.</p>
      <div class="feature-list">
        <span class="feature"><i class="bx bx-user-check"></i> Gestão de clientes</span>
        <span class="feature"><i class="bx bx-store-alt"></i> Controle de revendas</span>
        <span class="feature"><i class="bx bx-devices"></i> Aplicativos integrados</span>
        <span class="feature"><i class="bx bx-shield-quarter"></i> Acesso protegido</span>
      </div>
    </div>
    <div class="visual-footer"><i class="bx bx-check-shield"></i> Sessão protegida e validação de acesso ativa</div>
  </section>

  <section class="login-panel">
    <div class="login-content">
      <div class="mobile-brand">
        <img src="api/img/logo.png?v=<?= safeText($panelLogoVersion) ?>" alt="<?= safeText($panelName) ?>">
        <span><strong><?= safeText($panelName) ?></strong><small>Painel administrativo</small></span>
      </div>

      <div class="login-heading">
        <span class="eyebrow"><i class="bx bx-lock-alt"></i> Acesso restrito</span>
        <h2>Bem-vindo de volta</h2>
        <p>Informe seus dados para acessar o painel de controle.</p>
      </div>

      <?php if ($error !== ''): ?>
        <div class="login-error"><i class="bx bx-error-circle"></i><span><?= safeText($error) ?></span></div>
      <?php endif; ?>

      <form method="post" autocomplete="off">
        <input type="hidden" name="csrf_token" value="<?= safeText(csrf_token()) ?>">
        <div class="field">
          <label for="username">Usuário</label>
          <div class="input-wrap"><i class="bx bx-user"></i><input id="username" type="text" name="username" placeholder="Digite seu usuário" required autofocus autocomplete="username"></div>
        </div>
        <div class="field">
          <label for="password">Senha</label>
          <div class="input-wrap"><i class="bx bx-lock-alt"></i><input id="password" type="password" name="password" placeholder="Digite sua senha" required autocomplete="current-password"><button class="password-toggle" type="button" aria-label="Mostrar senha" id="passwordToggle"><i class="bx bx-show"></i></button></div>
        </div>
        <button class="login-button" name="login" value="1" type="submit"><span>Entrar no painel</span><i class="bx bx-right-arrow-alt"></i></button>
      </form>

      <div class="login-note"><i class="bx bx-check-shield"></i> Seus dados são enviados por uma sessão protegida</div>
      <div class="login-copyright">© <?= date('Y') ?> <?= safeText($panelName) ?></div>
    </div>
  </section>
</main>
<script src="assets/js/pages/index.js?v=<?= is_file(dirname(__DIR__) . '/assets/js/pages/index.js') ? (int)filemtime(dirname(__DIR__) . '/assets/js/pages/index.js') : time() ?>"></script>
</body>
</html>
