<?php
declare(strict_types=1);
require_once __DIR__ . '/db.php';

define('LK_AUTH_COOKIE',  'lk_admin_token');
define('LK_AUTH_DAYS',    30);
define('LK_SESSION_NAME', 'LK_ADMIN');
define('LK_CSRF_KEY',     'lk_csrf_token');

if (session_status() === PHP_SESSION_NONE) {
    session_name(LK_SESSION_NAME);
    session_set_cookie_params([
        'lifetime' => 0,
        'path'     => '/',
        'secure'   => true,
        'httponly' => true,
        'samesite' => 'Lax',
    ]);
    session_start();
}

function lk_csrf_token(): string {
    if (empty($_SESSION[LK_CSRF_KEY])) {
        $_SESSION[LK_CSRF_KEY] = bin2hex(random_bytes(24));
    }
    return $_SESSION[LK_CSRF_KEY];
}

function lk_csrf_check(): void {
    $tok = (string)($_POST['csrf'] ?? '');
    if (!hash_equals(lk_csrf_token(), $tok)) {
        http_response_code(403);
        die('CSRF check failed');
    }
}

function lk_ua_hash(): string {
    return hash('sha256', ($_SERVER['HTTP_USER_AGENT'] ?? '') . ($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? ''));
}

function lk_client_ip(): string {
    foreach (['HTTP_CF_CONNECTING_IP','HTTP_X_REAL_IP','HTTP_X_FORWARDED_FOR','REMOTE_ADDR'] as $k) {
        $v = trim((string)($_SERVER[$k] ?? ''));
        if ($v !== '') {
            $v = explode(',', $v)[0];
            $v = trim($v);
            if (filter_var($v, FILTER_VALIDATE_IP)) return $v;
        }
    }
    return '0.0.0.0';
}

function lk_is_admin(): bool {
    // Session check
    if (!empty($_SESSION['lk_admin_id']) && !empty($_SESSION['lk_admin_ua'])) {
        if ($_SESSION['lk_admin_ua'] === lk_ua_hash()) return true;
        session_destroy();
        return false;
    }
    // Remember-me cookie check
    $cookie = $_COOKIE[LK_AUTH_COOKIE] ?? '';
    if ($cookie === '') return false;

    try {
        $pdo = lk_pdo();
        $st  = $pdo->prepare("
            SELECT t.admin_id, t.user_agent
            FROM admin_tokens t
            WHERE t.token_hash=? AND t.expires_at > NOW()
            LIMIT 1
        ");
        $st->execute([$cookie]);
        $row = $st->fetch(PDO::FETCH_ASSOC);
        if (!$row) return false;
        // Restore session
        $_SESSION['lk_admin_id'] = (int)$row['admin_id'];
        $_SESSION['lk_admin_ua'] = lk_ua_hash();
        return true;
    } catch (Throwable $e) {
        return false;
    }
}

function require_admin(): void {
    if (!lk_is_admin()) {
        header('Location: /login.php');
        exit;
    }
}

function lk_login(string $username, string $password, bool $remember = false): bool {
    try {
        $pdo = lk_pdo();
        $st  = $pdo->prepare("SELECT id, password_hash, allowed_ip, is_active FROM admins WHERE username=? LIMIT 1");
        $st->execute([$username]);
        $row = $st->fetch(PDO::FETCH_ASSOC);

        if (!$row) return false;
        if ((int)$row['is_active'] !== 1) return false;
        if (!password_verify($password, (string)$row['password_hash'])) return false;

        // IP check — if allowed_ip is set and not empty
        $allowedIp = trim((string)($row['allowed_ip'] ?? ''));
        if ($allowedIp !== '' && $allowedIp !== '0.0.0.0') {
            if (lk_client_ip() !== $allowedIp) return false;
        }

        session_regenerate_id(true);
        $_SESSION['lk_admin_id'] = (int)$row['id'];
        $_SESSION['lk_admin_ua'] = lk_ua_hash();

        if ($remember) {
            $token   = bin2hex(random_bytes(32));
            $expires = date('Y-m-d H:i:s', time() + LK_AUTH_DAYS * 86400);
            $ip      = lk_client_ip();
            $ua      = substr((string)($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 255);
            $pdo->prepare("INSERT INTO admin_tokens (admin_id, token_hash, ip, user_agent, expires_at) VALUES (?,?,?,?,?)")
                ->execute([(int)$row['id'], $token, $ip, $ua, $expires]);
            setcookie(LK_AUTH_COOKIE, $token, [
                'expires'  => time() + LK_AUTH_DAYS * 86400,
                'path'     => '/',
                'secure'   => true,
                'httponly' => true,
                'samesite' => 'Lax',
            ]);
        }
        return true;
    } catch (Throwable $e) {
        return false;
    }
}

function lk_logout(): void {
    $cookie = $_COOKIE[LK_AUTH_COOKIE] ?? '';
    if ($cookie !== '') {
        try {
            lk_pdo()->prepare("DELETE FROM admin_tokens WHERE token_hash=?")->execute([$cookie]);
        } catch (Throwable $e) {}
        setcookie(LK_AUTH_COOKIE, '', ['expires' => time() - 3600, 'path' => '/']);
    }
    $_SESSION = [];
    session_destroy();
}
