<?php

namespace QUI\WebsiteLocker;

use QUI;
use QUI\Exception;
use QUI\Rewrite;
use QUI\System\Log;
use QUI\WebsiteLocker\Controls\WebsiteLocker;
use Symfony\Component\HttpFoundation\Response;

use function class_exists;
use function in_array;

class EventHandler
{
    protected static ?string $instanceLockPassword = null;

    /**
     * @param Rewrite $Rewrite
     * @param string $url
     *
     * @return void
     * @throws \Exception
     */
    public static function onRequest(Rewrite $Rewrite, string $url): void
    {
        try {
            $Project = $Rewrite->getProject();

            if ($Project === null) {
                return;
            }

            $conf = $Project->getConfig();
        } catch (Exception $Exception) {
            Log::writeException($Exception);

            return;
        }

        // pass module is off
        if (!isset($conf['WebsiteLocker.locked']) || !$conf['WebsiteLocker.locked']) {
            return;
        }

        if (self::isTechnicalRequest($url)) {
            return;
        }

        $Session = QUI::getSession();

        // password is correct
        if ($Session->get('website-locker-pass') === $conf['WebsiteLocker.passwd']) {
            return;
        }

        if (
            isset($_REQUEST['website-locker-pass'])
            && $_REQUEST['website-locker-pass'] === $conf['WebsiteLocker.passwd']
        ) {
            // login
            $Session->set('website-locker-pass', $_REQUEST['website-locker-pass']);

            return;
        }

        $Response = QUI::getGlobalResponse();

        if (!isset($conf['WebsiteLocker.placeholder'])) {
            $conf['WebsiteLocker.placeholder'] = '';
        }

        $Control = new WebsiteLocker([
            'interactiveBackground' => $conf['WebsiteLocker.interactiveBackground'],
            'backgroundColor' => $conf['WebsiteLocker.backgroundColor'],
            'backgroundImage' => $conf['WebsiteLocker.backgroundImage'],
            'logo' => $conf['WebsiteLocker.logo']
        ]);

        $Response->setStatusCode(Response::HTTP_UNAUTHORIZED);
        $Response->setContent($Control->create());
        $Response->send();
        exit;
    }

    protected static function isTechnicalRequest(string $url): bool
    {
        if (self::isMcpRequest($url)) {
            return true;
        }

        return self::isRestRequest();
    }

    protected static function isMcpRequest(string $url): bool
    {
        if (!QUI::getPackageManager()->isInstalled("quiqqer/ai-mcp")) {
            return false;
        }

        $url = trim($url, "/");

        return in_array($url, [
            "mcp",
            "authorize",
            "callback",
            "token"
        ], true);
    }

    protected static function isRestRequest(): bool
    {
        if (!QUI::getPackageManager()->isInstalled("quiqqer/rest")) {
            return false;
        }

        try {
            $Request = QUI::getRequest();
            $Package = QUI::getPackage("quiqqer/rest");
            $Config = $Package->getConfig();

            if ($Config === null) {
                return false;
            }

            $basePath = $Config->getValue("general", "basePath");
            $baseHost = $Config->getValue("general", "baseHost");
        } catch (\Throwable $Exception) {
            Log::writeException($Exception);

            return false;
        }

        if (!is_string($basePath)) {
            $basePath = "";
        }

        if (!is_string($baseHost)) {
            $baseHost = "";
        } else {
            $baseHost = str_replace(["http://", "https://"], "", $baseHost);
            $baseHost = rtrim($baseHost, "/");
        }

        if (!empty($baseHost) && $Request->getHost() !== $baseHost) {
            return false;
        }

        $uri = $Request->getRequestUri() . "/";

        return !empty($basePath) && mb_strpos($uri, $basePath) !== false;
    }

    /**
     * @throws \Exception
     */
    public static function onSiteStart(): void
    {
        try {
            $Site = QUI::getRewrite()->getSite();
        } catch (Exception $Exception) {
            Log::writeException($Exception);

            return;
        }

        if ($Site === null) {
            return;
        }

        if (!$Site->getAttribute('quiqqer.website.locker.status')) {
            return;
        }

        $Site->setAttribute('nocache', true);

        // password
        $password = $Site->getAttribute('quiqqer.website.locker.password');

        if (empty($password)) {
            $conf = $Site->getProject()->getConfig();

            if (empty($conf['WebsiteLocker.locked'])) {
                return;
            }

            $password = $conf['WebsiteLocker.locked'];
        }

        $Session = QUI::getSession();

        // password input
        if (
            isset($_POST['site-lock-' . $Site->getId()])
            && isset($_POST['password'])
            && $_POST['password'] == $password
        ) {
            $Session->set('website-locker-pass-' . $Site->getId(), $password);
        }

        // password
        if ($Session->get('website-locker-pass-' . $Site->getId()) === $password) {
            return;
        }

        $Control = new QUI\WebsiteLocker\Controls\SiteLock([
            'title' => $Site->getAttribute('quiqqer.website.locker.title'),
            'description' => $Site->getAttribute('quiqqer.website.locker.description'),
            'Site' => $Site,
            'backgroundImage' => $Site->getAttribute('quiqqer.website.locker.background')
        ]);


        $Response = QUI::getGlobalResponse();
        $Response->setContent($Control->create());
        $Response->setStatusCode(Response::HTTP_FORBIDDEN);
        $Response->prepare(QUI::getRequest());
        $Response->send();

        exit;
    }

    /**
     * @param array<string, mixed> $config
     * @param array<string, mixed> $sentConfigParams
     */
    public static function onProjectConfigSave(string $projectName, array $config, array $sentConfigParams): void
    {
        if (!QUI::getPackageManager()->isInstalled('quiqqer/cache')) {
            return;
        }

        if (class_exists('QUI\Cache\Handler')) {
            QUI\Cache\Handler::init()->clearCache();
        }
    }

    //region user login / logout

    public static function onUserLogoutBegin(QUI\Interfaces\Users\User $User): void
    {
        $Session = QUI::getSession();

        $password = $Session->get('website-locker-pass');

        if (!empty($password)) {
            self::$instanceLockPassword = $password;
        }
    }

    public static function onUserLoginStart(): void
    {
        $Session = QUI::getSession();

        $password = $Session->get('website-locker-pass');

        if (!empty($password)) {
            self::$instanceLockPassword = $password;
        }
    }

    public static function onUserLogout(QUI\Interfaces\Users\User $User): void
    {
        $Session = QUI::getSession();

        if (!empty(self::$instanceLockPassword)) {
            $Session->set('website-locker-pass', self::$instanceLockPassword);
        }
    }

    public static function onUserLogin(): void
    {
        $Session = QUI::getSession();

        if (!empty(self::$instanceLockPassword)) {
            $Session->set('website-locker-pass', self::$instanceLockPassword);
        }
    }

    //endregion
}
