<?php
namespace App\Core;

use App\Core\Database;

class TenantGuard
{
    public static function start(): void
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }
    }

    
public static function requireLogin(): void
{
    /* PACK894 SESSION TIMEOUT */

    $timeout = 7200;

    if(
        isset($_SESSION['LAST_ACTIVITY'])
        &&
        (time() - $_SESSION['LAST_ACTIVITY']) > $timeout
    ){
        session_unset();
        session_destroy();

        header(
            'Location: /easychair/login?expired=1'
        );
        exit;
    }

    $_SESSION['LAST_ACTIVITY']=time();

    self::start();

    /*
    |--------------------------------------------------------------------------
    | PUBLIC CONFERENCE / PAPER PAGES
    |--------------------------------------------------------------------------
    */

    $path =
        parse_url(
            $_SERVER['REQUEST_URI'] ?? '/',
            PHP_URL_PATH
        );

    $isPublicConference =
        preg_match(
            '#^/easychair/conference/[a-zA-Z0-9\-_]+$#',
            $path
        );

    $isPublicPaper =
        preg_match(
            '#^/easychair/paper/[0-9]+$#',
            $path
        );

    /*
    PUBLIC ACCESS
    */

    if (
        $isPublicConference
        || $isPublicPaper
    ) {

        return;

    }

    /*
    NORMAL LOGIN ENFORCEMENT
    */

    if (empty($_SESSION['user_id'])) {
error_log(
    'TENANTGUARD REDIRECT >>> ' .
    ($_SERVER['REQUEST_URI'] ?? '')
);
        header("Location: /easychair/login");
        exit;
    }
}
    public static function role(): string
    {
        self::start();
        return (string)($_SESSION['role'] ?? $_SESSION['user_role'] ?? '');
    }

    public static function isSuperAdmin(): bool
    {
        return self::role() === 'superadmin';
    }

    public static function currentOrgId(): int
    {
        self::start();
        return (int)($_SESSION['org_id'] ?? 0);
    }

    public static function currentConferenceId(): int
    {
        self::start();
        return (int)($_SESSION['conference_id'] ?? $_SESSION['current_conference_id'] ?? 0);
    }

    public static function conferenceIds(): array
    {
        self::start();

        $ids = $_SESSION['conference_list'] ?? [];
        $ids = array_values(array_unique(array_filter(array_map('intval', $ids))));

        return $ids;
    }

    public static function requireConference(): void
    {
        self::requireLogin();

        if (self::isSuperAdmin()) {
            return;
        }

        $cid = self::currentConferenceId();

        if ($cid <= 0) {
            if (empty($_SESSION['user_id'])) {
                header("Location: /easychair/login?expired=1");
                exit;
            }

            header("Location: /easychair/select-conference");
            exit;
        }

        self::assertConferenceAccess($cid);
    }

    public static function assertConferenceAccess(int $conferenceId): void
    {
        self::requireLogin();

        if (self::isSuperAdmin()) {
            return;
        }

        $allowed = self::conferenceIds();

        if (!in_array($conferenceId, $allowed, true)) {
            http_response_code(403);
            if (empty($_SESSION['user_id'])) {
                header("Location: /easychair/login?expired=1");
                exit;
            }

            header("Location: /easychair/select-conference");
            exit;
        }

        $orgId = self::currentOrgId();

        if ($orgId > 0) {
            $db = Database::getInstance();

            $stmt = $db->prepare("
                SELECT id
                FROM conferences
                WHERE id = ?
                  AND org_id = ?
                LIMIT 1
            ");
            $stmt->execute([$conferenceId, $orgId]);

            if (!$stmt->fetchColumn()) {
                http_response_code(403);
                exit("Conference does not belong to the selected organization.");
            }
        }
    }

    public static function enforceOrgFilter(string $tableAlias = ''): string
    {
        self::start();

        if (self::isSuperAdmin()) {
            return '';
        }

        $orgId = self::currentOrgId();

        if ($orgId <= 0) {
            return " AND 1=0 ";
        }

        $prefix = $tableAlias ? $tableAlias . '.' : '';

        return " AND {$prefix}org_id = " . (int)$orgId . " ";
    }

    public static function enforceConferenceFilter(string $tableAlias = ''): string
    {
        self::start();

        if (self::isSuperAdmin()) {
            return '';
        }

        $cid = self::currentConferenceId();

        if ($cid <= 0) {
            return " AND 1=0 ";
        }

        $prefix = $tableAlias ? $tableAlias . '.' : '';

        return " AND {$prefix}conference_id = " . (int)$cid . " ";
    }

    public static function conferenceWhere(string $alias = 'c'): string
    {
        self::start();

        $where = " WHERE 1=1 ";

        if (!self::isSuperAdmin()) {
            $cid = self::currentConferenceId();
            $orgId = self::currentOrgId();

            if ($cid > 0) {
                $where .= " AND {$alias}.id = " . (int)$cid . " ";
            } else {
                $ids = self::conferenceIds();
                if ($ids) {
                    $where .= " AND {$alias}.id IN (" . implode(',', $ids) . ") ";
                } else {
                    $where .= " AND 1=0 ";
                }
            }

            if ($orgId > 0) {
                $where .= " AND {$alias}.org_id = " . (int)$orgId . " ";
            }
        }

        return $where;
    }

    public static function adminRoles(): array
    {
        return [
            'superadmin',
            'org_admin',
            'conference_chair',
            'track_chair',
            'tpc',
            'admin'
        ];
    }

    public static function requireAdmin(): void
    {
        self::requireLogin();

        if (!in_array(self::role(), self::adminRoles(), true)) {
            http_response_code(403);
            exit("ACCESS DENIED => " . __FILE__ . ":" . __LINE__);
        }

        if (!self::isSuperAdmin()) {
            self::requireConference();
        }
    }
}
