<?php
declare(strict_types=1);

require_once __DIR__ . DIRECTORY_SEPARATOR . 'bootstrap.php';
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'admin_member_auth.php';
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'fate_member_session_bridge.php';

function fate_admin_configured(): bool
{
    return fate_admin_member_auth_ready();
}

/**
 * 可選：環境變數 FATE_ADMIN_IP_ALLOWLIST（逗號分隔 IPv4/IPv6）。
 * 未設定時不限制；設定後僅列出的 IP 可進入 admin/（登入頁亦同）。
 */
function fate_admin_ip_access_allowed(): bool
{
    $raw = getenv('FATE_ADMIN_IP_ALLOWLIST');
    if (!is_string($raw) || trim($raw) === '') {
        return true;
    }
    $client = isset($_SERVER['REMOTE_ADDR']) ? trim((string) $_SERVER['REMOTE_ADDR']) : '';
    if ($client === '' || filter_var($client, FILTER_VALIDATE_IP) === false) {
        return false;
    }
    foreach (preg_split('/\s*,\s*/', trim($raw)) as $entry) {
        $entry = trim((string) $entry);
        if ($entry !== '' && strcasecmp($entry, $client) === 0) {
            return true;
        }
    }

    return false;
}

/**
 * 登入後可安全導回的後台相對路徑（例如 members.php?review=pending&edit=3）。
 */
function fate_admin_safe_next(?string $next): string
{
    $next = is_string($next) ? trim($next) : '';
    if ($next === '' || $next === '/') {
        return 'index.php';
    }

    $scriptDir = str_replace('\\', '/', dirname((string) ($_SERVER['SCRIPT_NAME'] ?? '/admin')));
    $scriptDir = rtrim($scriptDir, '/');
    if ($scriptDir !== '' && $scriptDir !== '.' && str_starts_with($next, $scriptDir . '/')) {
        $next = substr($next, strlen($scriptDir) + 1);
    }
    if (str_starts_with($next, '/admin/')) {
        $next = substr($next, 7);
    }
    if (str_starts_with($next, 'admin/')) {
        $next = substr($next, 6);
    }

    if (preg_match('#^login\.php#i', $next) === 1) {
        return 'index.php';
    }

    if (preg_match('#^[a-zA-Z0-9_-]+\.php(?:\?[\w&=%.\-+:]*)?$#', $next) === 1) {
        return $next;
    }

    return 'index.php';
}

/**
 * 後台登入成功：寫入 Session、同步前台、刷新 Cookie 後再導頁。
 *
 * @param array{id:int,username:string,display_name:string} $member
 */
function fate_admin_complete_login(array $member, bool $remember): void
{
    $lifetime = $remember ? fate_session_lifetime_sec() : fate_session_short_lifetime_sec();
    fate_session_assign_cookie_lifetime($lifetime);

    if (session_status() === PHP_SESSION_ACTIVE && session_name() !== 'fate_admin') {
        session_write_close();
    }

    fate_admin_session_start();
    session_regenerate_id(true);
    fate_admin_member_bind_session($member);
    $_SESSION['fate_cookie_lifetime'] = $lifetime;
    fate_session_touch_cookie();

    fate_member_bridge_sync_after_admin_login($member);

    fate_admin_session_start();
    if (!fate_admin_is_logged_in()) {
        fate_admin_member_bind_session($member);
        $_SESSION['fate_cookie_lifetime'] = $lifetime;
    }
    fate_session_touch_cookie();
    session_write_close();
}

/** 工作階段過期後開啟登入頁時，清除殘留的空白 admin Session，避免無法重新登入。 */
function fate_admin_get_pdo(?string &$connectError = null): ?PDO
{
    require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'fate_db.php';

    return fate_bootstrap_pdo($connectError);
}

function fate_admin_reset_login_session_if_needed(string $reason): void
{
    if ($reason !== 'session' || $_SERVER['REQUEST_METHOD'] === 'POST') {
        return;
    }
    if (fate_admin_is_logged_in()) {
        return;
    }

    fate_admin_session_start();
    $_SESSION = [];
    if (empty($_SESSION['fate_admin_csrf'])) {
        $_SESSION['fate_admin_csrf'] = bin2hex(random_bytes(24));
    }
    session_regenerate_id(true);
    fate_session_touch_cookie();
}

/** 目前請求對應的後台相對路徑（供登入後導回）。 */
function fate_admin_login_return_path(): string
{
    $script = basename((string) ($_SERVER['SCRIPT_NAME'] ?? 'index.php'));
    if (strcasecmp($script, 'login.php') === 0) {
        return 'index.php';
    }

    $uri = (string) ($_SERVER['REQUEST_URI'] ?? '');
    if ($uri === '') {
        $qs = isset($_SERVER['QUERY_STRING']) && (string) $_SERVER['QUERY_STRING'] !== ''
            ? '?' . (string) $_SERVER['QUERY_STRING']
            : '';

        return fate_admin_safe_next($script . $qs);
    }

    return fate_admin_safe_next($uri);
}

function fate_admin_require_login(): void
{
    require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'fate_install.php';
    fate_install_maybe_redirect();

    if (!fate_admin_ip_access_allowed()) {
        http_response_code(403);
        header('Content-Type: text/html; charset=UTF-8');
        echo '<!DOCTYPE html><html lang="zh-Hant"><head><meta charset="UTF-8"><title>403 Forbidden</title></head><body>';
        echo '<p>此管理後台僅允許指定 IP 存取。</p></body></html>';
        exit;
    }

    if (!fate_admin_configured()) {
        header('Location: login.php?reason=badconfig', true, 302);
        exit;
    }
    if (!fate_admin_is_logged_in() && !fate_member_bridge_try_restore_admin_from_site()) {
        $next = fate_admin_login_return_path();
        header('Location: login.php?next=' . rawurlencode($next) . '&reason=session', true, 302);
        exit;
    }
}

/** JSON API 用：未登入時不轉址，回 401／503 JSON */
function fate_admin_require_login_api(): void
{
    header('Content-Type: application/json; charset=UTF-8');
    if (!fate_admin_configured()) {
        http_response_code(503);
        echo json_encode(['ok' => false, 'error' => 'admin_not_configured'], JSON_UNESCAPED_UNICODE);
        exit;
    }
    if (!fate_admin_is_logged_in() && !fate_member_bridge_try_restore_admin_from_site()) {
        http_response_code(401);
        echo json_encode(['ok' => false, 'error' => 'not_logged_in'], JSON_UNESCAPED_UNICODE);
        exit;
    }
}

function fate_admin_csrf_token(): string
{
    if (empty($_SESSION['fate_admin_csrf'])) {
        $_SESSION['fate_admin_csrf'] = bin2hex(random_bytes(24));
    }
    return (string) $_SESSION['fate_admin_csrf'];
}

function fate_admin_csrf_check(?string $token): bool
{
    return is_string($token) && isset($_SESSION['fate_admin_csrf'])
        && hash_equals((string) $_SESSION['fate_admin_csrf'], $token);
}
