<?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");

$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 FROM revendedores WHERE username=? AND (status IS NULL OR status='' OR status='ativo') LIMIT 1");
                    $stmt2->execute([$u]);
                    $revUser = $stmt2->fetch();

                    if ($revUser) {
                        $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">
<title><?= safeText($panelName) ?></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;600;700;800&display=swap" rel="stylesheet">
<style>
:root{
  --bg:#07070b;
  --panel: rgba(255,255,255,.06);
  --panel2: rgba(255,255,255,.09);
  --stroke: rgba(255,255,255,.12);
  --stroke2: rgba(255,255,255,.18);
  --shadow: 0 22px 70px rgba(0,0,0,.55);
  --shadow2: 0 16px 55px rgba(0,0,0,.45);

  --white:#ffffff;
  --white2:#d6d6d6;

  --text:#ffffff;
  --muted: rgba(255,255,255,.72);
  --muted2: rgba(255,255,255,.50);
  --radius: 24px;
  --ease: cubic-bezier(.2,.9,.2,1);
  --speed: .22s;
}

*{ box-sizing:border-box; }
html,body{
  margin:0;
  padding:0;
  width:100%;
  height:100%;
  font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,Arial,Helvetica,sans-serif;
  background: var(--bg);
  color: var(--text);
}

body{
  min-height:100vh;
  display:flex;
  align-items:center;
  justify-content:center;
  padding: 24px;
  overflow:auto;

  background:
    radial-gradient(1200px 760px at 78% 28%, rgba(255,255,255,.08), transparent 60%),
    radial-gradient(900px 620px at 20% 18%, rgba(255,255,255,.06), transparent 62%),
    radial-gradient(900px 520px at 88% 82%, rgba(255,255,255,.04), transparent 58%),
    linear-gradient(180deg, rgba(0,0,0,.58), rgba(0,0,0,.92));
}

.bgPoster{
  position:fixed;
  inset:0;
  z-index:0;
  pointer-events:none;
  background-image:
    url("api/img/fundo_login.jpg"),
    radial-gradient(1200px 760px at 78% 28%, rgba(255,255,255,.08), transparent 60%),
    radial-gradient(900px 620px at 20% 18%, rgba(255,255,255,.06), transparent 62%),
    radial-gradient(900px 520px at 88% 82%, rgba(255,255,255,.04), transparent 58%),
    linear-gradient(180deg, rgba(0,0,0,.58), rgba(0,0,0,.92));
  background-size: cover;
  background-position:center;
  background-repeat:no-repeat;
  filter: saturate(1.05) contrast(1.05);
  opacity:.28;
}

.vignette{
  position:fixed;
  inset:0;
  z-index:1;
  pointer-events:none;
  background:
    radial-gradient(circle at 60% 30%, transparent 0%, rgba(0,0,0,.22) 40%, rgba(0,0,0,.82) 86%, rgba(0,0,0,.94) 100%);
  opacity:.95;
}

.noise{
  position:fixed;
  inset:0;
  z-index:2;
  pointer-events:none;
  background-image: radial-gradient(rgba(255,255,255,.05) 1px, transparent 1px);
  background-size: 3px 3px;
  opacity:.06;
  mix-blend-mode: overlay;
}

.login-box{
  width:100%;
  max-width: 420px;
  padding: 28px;
  border-radius: var(--radius);
  background:
    radial-gradient(circle at 18% 18%, rgba(255,255,255,.07), transparent 55%),
    linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.06));
  border: 1px solid rgba(255,255,255,.12);
  box-shadow: var(--shadow);
  position:relative;
  z-index:3;
  backdrop-filter: blur(18px);
}

.logo{
  display:flex;
  justify-content:center;
  align-items:center;
  gap: 12px;
  width:100%;
  margin-bottom: 6px;
}

.logoBox{
  width: 64px;
  height: 64px;
  border-radius: 22px;
  display:flex;
  align-items:center;
  justify-content:center;
  background:
    radial-gradient(circle at 30% 18%, rgba(255,255,255,.20), transparent 60%),
    linear-gradient(135deg, rgba(255,255,255,.96), rgba(255,255,255,.10));
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 20px 50px rgba(255,255,255,.12);
  overflow:hidden;
}

.logoBox img{
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.title{
  text-align:center;
  margin: 10px 0 10px 0;
  font-size: 22px;
  font-weight: 900;
  letter-spacing:.3px;
}

.subtitle{
  text-align:center;
  margin: 0 0 18px 0;
  font-size: 13px;
  color: rgba(255,255,255,.72);
}

.badge{
  margin: 0 auto 14px auto;
  width: fit-content;
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.12);
  background: rgba(0,0,0,.32);
  font-size: 12px;
  font-weight: 800;
  letter-spacing:.2px;
  color: rgba(255,255,255,.92);
  display:flex;
  align-items:center;
  gap: 10px;
}

.dot{
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: var(--white);
  box-shadow: 0 0 0 7px rgba(255,255,255,.14);
}

.form{
  margin-top: 6px;
}

input{
  width:100%;
  padding: 14px 14px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,.10);
  margin-bottom: 12px;
  background: rgba(0,0,0,.42);
  color:white;
  font-size: 15px;
  outline:none;
  transition: box-shadow var(--speed) var(--ease), border-color var(--speed) var(--ease), transform var(--speed) var(--ease);
}

input::placeholder{
  color: rgba(255,255,255,.48);
}

input:focus{
  border-color: rgba(255,255,255,.72);
  box-shadow: 0 0 0 4px rgba(255,255,255,.18), 0 16px 40px rgba(0,0,0,.45);
  transform: translateY(-1px);
}

button{
  width:100%;
  padding: 14px;
  border:none;
  border-radius: 14px;
  background: linear-gradient(90deg, rgba(255,255,255,.96), rgba(255,255,255,.18));
  border: 1px solid rgba(255,255,255,.12);
  color:#000;
  font-size: 16px;
  font-weight: 900;
  cursor:pointer;
  outline:none;
  transition: transform var(--speed) var(--ease),
              box-shadow var(--speed) var(--ease),
              border-color var(--speed) var(--ease),
              opacity var(--speed) var(--ease);
}

button:hover{ opacity:.95; }
button:active{ transform: scale(.992); }
button:focus{
  box-shadow: 0 0 0 4px rgba(255,255,255,.22), 0 20px 55px rgba(0,0,0,.55);
  border-color: rgba(255,255,255,.75);
}

.error{
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(255,255,255,.35);
  padding: 10px 12px;
  border-radius: 14px;
  text-align:center;
  margin-bottom: 14px;
  font-weight: 800;
  color: #fff;
}

.footer{
  text-align:center;
  margin-top: 18px;
  font-size: 12px;
  opacity:.72;
}

@media (max-width: 520px){
  body{ padding: 16px; }
  .login-box{ padding: 20px; border-radius: 20px; }
  .title{ font-size: 20px; }
}
</style>

</head>

<body>
<div class="bgPoster"></div>
<div class="noise"></div>
<div class="vignette"></div>

<div class="login-box">
  <div class="logo">
    <div class="logoBox">
      <img src="api/img/logo.png?v=<?= safeText($panelLogoVersion) ?>" alt="<?= safeText($panelName) ?>">
    </div>
  </div>

  <div class="title">Painel <?= safeText($panelName) ?></div>
  <div class="subtitle">Acesso premium • protegido • rápido</div>

  <div class="badge"><span class="dot"></span> Login seguro</div>

  <?php if($error!=""){ ?>
  <div class="error"><?= safeText($error) ?></div>
  <?php } ?>

  <form method="post" class="form" autocomplete="off">
    <input type="hidden" name="csrf_token" value="<?= safeText(csrf_token()) ?>">
    <input type="text" name="username" placeholder="Usuário" required autofocus autocomplete="username">
    <input type="password" name="password" placeholder="Senha" required autocomplete="current-password">
    <button name="login" value="1">Entrar</button>
  </form>

  <div class="footer">
    © <?= date("Y") ?> <?= safeText($panelName) ?>
  </div>
</div>

</body>
</html>
