<?php

declare(strict_types=1);

class AdminController
{
    private static string $loginBase = '/admin/login';

    public static function routes(): void
    {
         
        $customSlug = trim(Setting::get('admin_login_slug', ''));
        if ($customSlug !== '') {
            self::$loginBase = '/' . $customSlug;
            Router::addNoPrefixPath('/' . $customSlug);
        }

        Router::get('/admin', [self::class, 'dashboard']);
        Router::post('/admin/dashboard/save-layout', [self::class, 'saveLayout']);
        Router::post('/admin/dashboard/reset-layout', [self::class, 'resetLayout']);
        Router::get('/admin/announcements/feed', [self::class, 'announcementsFeed']);
        Router::get(self::$loginBase, [self::class, 'loginForm']);
        Router::post(self::$loginBase, [self::class, 'login']);
        Router::get(self::$loginBase . '/logout', [self::class, 'logout']);
        Router::get(self::$loginBase . '/2fa', [self::class, 'twoFactorForm']);
        Router::post(self::$loginBase . '/2fa', [self::class, 'twoFactorVerify']);
    }

    

    public static function loginUrl(): string
    {
        return self::$loginBase;
    }

    public static function dashboard(): void
    {
        Auth::requireAdmin();

        $user = Auth::user();
        $userId = (int) $user['id'];

        $layout = DashboardManager::getLayout($userId);
        $widgetData = DashboardManager::fetchData($layout);
        $allWidgets = DashboardManager::allWidgets();

        Router::render('admin/dashboard', [
            'pageTitle' => 'Dashboard',
            'activeMenu' => 'dashboard',
            'contentTemplate' => '_dashboard',
            'layout' => $layout,
            'widgetData' => $widgetData,
            'allWidgets' => $allWidgets,
        ]);
    }

    public static function saveLayout(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) {
            Router::json(['error' => 'Invalid CSRF token'], 403);
        }

        $input = json_decode(file_get_contents('php://input'), true);
        if (!is_array($input) || !isset($input['layout'])) {
            Router::json(['error' => 'Invalid payload'], 400);
        }

        $user = Auth::user();
        DashboardManager::saveLayout((int) $user['id'], $input['layout']);
        Router::json(['success' => true]);
    }

    public static function resetLayout(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) {
            Router::json(['error' => 'Invalid CSRF token'], 403);
        }

        $user = Auth::user();
        DashboardManager::resetLayout((int) $user['id']);
        Router::json(['success' => true]);
    }

    

    public static function announcementsFeed(): void
    {
        Auth::requireAdmin();
        session_write_close();
        try {
            $list = AnnouncementService::refreshAndGet();
            Router::json([
                'html' => AnnouncementService::renderBar($list),
                'sig'  => AnnouncementService::signature($list),
            ]);
        } catch (\Throwable $e) {
            Router::json(['html' => '', 'sig' => '']);
        }
    }

    public static function loginForm(): void
    {
        if (Auth::isAdmin()) {
            Router::redirect('/admin');
        }
        Router::render('admin/login', ['error' => null]);
    }

    public static function login(): void
    {
        if (!Router::verifyCsrf()) {
            Router::render('admin/login', ['error' => 'Your session has expired. Please refresh the page and try again.']);
            return;
        }

        if (!RateLimiter::throttle('admin_login', 5, 20)) {
            Router::render('admin/login', ['error' => 'Too many login attempts. Please try again later.']);
            return;
        }

        $result = Auth::login($_POST['email'] ?? $_POST['login'] ?? '', $_POST['password'] ?? '');

        if ($result['success'] && Auth::isAdmin()) {
            $user = Auth::user();
            if (!empty($user['totp_secret'])) {
                $_SESSION['2fa_pending'] = true;
                unset($_SESSION['2fa_verified']);
                Router::redirect(self::$loginBase . '/2fa');
            } else {
                $_SESSION['2fa_verified'] = true;
                Router::redirect('/admin');
            }
        } elseif ($result['success']) {
            Auth::logout();
            Router::render('admin/login', ['error' => 'Access restricted to administrators.']);
        } else {
            Router::render('admin/login', ['error' => $result['error']]);
        }
    }

    public static function twoFactorForm(): void
    {
        $user = Auth::user();
        if (!Auth::isAdmin() || empty($user['totp_secret']) || !empty($_SESSION['2fa_verified'])) {
            Router::redirect(self::$loginBase);
            return;
        }
        Router::render('admin/2fa', ['error' => null]);
    }

    public static function twoFactorVerify(): void
    {
        $user = Auth::user();
        if (!Auth::isAdmin() || empty($user['totp_secret']) || !empty($_SESSION['2fa_verified'])) {
            Router::redirect(self::$loginBase);
            return;
        }

        if (!Router::verifyCsrf()) {
            Router::render('admin/2fa', ['error' => 'Your session has expired. Please try again.']);
            return;
        }

        if (!RateLimiter::throttle('admin_2fa', 5, 20)) {
            Router::render('admin/2fa', ['error' => 'Too many attempts. Please try again later.']);
            return;
        }

        $code = trim($_POST['code'] ?? '');

        $matchedCounter = TwoFactor::verify(
            $user['totp_secret'],
            $code,
            1,
            isset($user['totp_last_counter']) ? (int) $user['totp_last_counter'] : null
        );
        if ($matchedCounter) {
            Database::update('users', ['totp_last_counter' => $matchedCounter], 'id = ?', [(int) $user['id']]);
            unset($_SESSION['2fa_pending']);
            $_SESSION['2fa_verified'] = true;
            session_regenerate_id(true);
            Router::redirect('/admin');
        } else {
            Router::render('admin/2fa', ['error' => 'Invalid verification code. Please try again.']);
        }
    }

    public static function logout(): void
    {
        Auth::logout();
        Router::redirect(self::$loginBase);
    }
}
