<?php

use App\Core\Database;

if (!function_exists('ec_scope_session')) {
    function ec_scope_session(): void
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            @session_start();
        }
    }
}

if (!function_exists('ec_scope_table_exists')) {
    function ec_scope_table_exists(PDO $db, string $table): bool
    {
        try {
            $stmt = $db->prepare("SHOW TABLES LIKE ?");
            $stmt->execute([$table]);
            return (bool)$stmt->fetchColumn();
        } catch (Throwable $e) {
            return false;
        }
    }
}

if (!function_exists('ec_scope_columns')) {
    function ec_scope_columns(PDO $db, string $table): array
    {
        try {
            $stmt = $db->query("DESCRIBE `$table`");
            return array_map(fn($r) => $r['Field'], $stmt->fetchAll(PDO::FETCH_ASSOC));
        } catch (Throwable $e) {
            return [];
        }
    }
}

if (!function_exists('ec_scope_first_col')) {
    function ec_scope_first_col(array $cols, array $names): ?string
    {
        foreach ($names as $n) {
            if (in_array($n, $cols, true)) return $n;
        }
        return null;
    }
}

if (!function_exists('ec_scope_user_row')) {
    function ec_scope_user_row(): ?array
    {
        ec_scope_session();

        $uid = (int)($_SESSION['user_id'] ?? 0);
        if ($uid <= 0) return null;

        try {
            $db = Database::getInstance();
            $stmt = $db->prepare("SELECT * FROM users WHERE id=? LIMIT 1");
            $stmt->execute([$uid]);
            $u = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$u) return null;

            if (empty($_SESSION['email']) && !empty($u['email'])) {
                $_SESSION['email'] = $u['email'];
            }

            if (empty($_SESSION['org_id']) && isset($u['org_id'])) {
                $_SESSION['org_id'] = (int)$u['org_id'];
            }

            foreach (['role', 'role_code', 'user_role', 'type'] as $col) {
                if (!empty($u[$col])) {
                    $__normalizedRole = function_exists('ec_scope_normalize_role') ? ec_scope_normalize_role((string)$u[$col], (string)($u['email'] ?? ($_SESSION['email'] ?? ''))) : (string)$u[$col];
                    if (empty($_SESSION['role'])) $_SESSION['role'] = $__normalizedRole;
                    if (empty($_SESSION['user_role'])) $_SESSION['user_role'] = $__normalizedRole;
                    if (empty($_SESSION['conference_role'])) $_SESSION['conference_role'] = $__normalizedRole;
                    break;
                }
            }

            return $u;
        } catch (Throwable $e) {
            return null;
        }
    }
}


if (!function_exists('ec_scope_normalize_role')) {
    function ec_scope_normalize_role(string $role, string $email = ''): string
    {
        $role = trim($role);
        $email = strtolower(trim($email));

        /*
         * Seed/test accounts: email is more reliable than legacy copied role values.
         */
        if ($email !== '') {
            if (str_contains($email, 'superadmin') || str_contains($email, 'super.admin')) return 'superadmin';
            if (str_contains($email, 'orgadmin') || str_contains($email, 'org.admin')) return 'org_admin';
            if (str_contains($email, 'organizer')) return 'organizer';
            if (str_contains($email, 'reviewer')) return 'reviewer';
            if (str_contains($email, 'author')) return 'author';
            if (str_contains($email, 'chair')) return 'conference_chair';
        }

        $map = [
            'superadmin' => 'superadmin',
            'super-admin' => 'superadmin',
            'orgadmin' => 'org_admin',
            'org-admin' => 'org_admin',
            'chair' => 'conference_chair',
            'conference chair' => 'conference_chair',
            'track chair' => 'track_chair',
            'section editor' => 'section_editor',
        ];

        $k = strtolower(str_replace('_', ' ', $role));
        return $map[$k] ?? $role;
    }
}

if (!function_exists('ec_scope_role')) {
    function ec_scope_role(): string
{
    if (session_status() !== PHP_SESSION_ACTIVE) {
        session_start();
    }

    /* 🔥 SUPERADMIN ALWAYS WINS */
    if (!empty($_SESSION['role']) && $_SESSION['role'] === 'superadmin') {
        return 'superadmin';
    }

    /* Otherwise use conference role */
    if (!empty($_SESSION['conference_role'])) {
        return $_SESSION['conference_role'];
    }

    /* fallback */
    if (!empty($_SESSION['role'])) {
        return $_SESSION['role'];
    }

    return 'guest';
}
}

if (!function_exists('ec_scope_landing_url')) {
    function ec_scope_landing_url(?string $role = null): string
    {
        $role = $role ?: ec_scope_role();

        if ($role === 'superadmin') {
            return '/easychair/select-conference';
        }

        if ($role === 'author') {
            return '/easychair/author/dashboard';
        }

        if ($role === 'reviewer') {
            return '/easychair/reviewer/dashboard';
        }

        return '/easychair/admin/dashboard';
    }
}

if (!function_exists('ec_scope_role_for_conference')) {
    function ec_scope_role_for_conference(int $userId, int $conferenceId, string $fallback = ''): string
    {
        if ($userId <= 0 || $conferenceId <= 0) return $fallback;

        try {
            $db = Database::getInstance();

            foreach (['conference_user_roles', 'user_conference_roles', 'conference_users', 'user_roles'] as $table) {
                if (!ec_scope_table_exists($db, $table)) continue;

                $cols = ec_scope_columns($db, $table);
                $userCol = ec_scope_first_col($cols, ['user_id', 'userid', 'uid']);
                $confCol = ec_scope_first_col($cols, ['conference_id', 'conf_id']);
                $roleCol = ec_scope_first_col($cols, ['role_code', 'role', 'role_name', 'code']);
                $roleIdCol = ec_scope_first_col($cols, ['role_id', 'roleid']);

                if (!$userCol || !$confCol) continue;

                if ($roleCol) {
                    $stmt = $db->prepare("SELECT `$roleCol` FROM `$table` WHERE `$userCol`=? AND `$confCol`=? LIMIT 1");
                    $stmt->execute([$userId, $conferenceId]);
                    $role = (string)$stmt->fetchColumn();
                    if ($role !== '') return $role;
                }

                if ($roleIdCol && ec_scope_table_exists($db, 'roles')) {
                    $stmt = $db->prepare("
                        SELECT r.code
                        FROM `$table` t
                        JOIN roles r ON r.id=t.`$roleIdCol`
                        WHERE t.`$userCol`=? AND t.`$confCol`=?
                        LIMIT 1
                    ");
                    $stmt->execute([$userId, $conferenceId]);
                    $role = (string)$stmt->fetchColumn();
                    if ($role !== '') return $role;
                }
            }
        } catch (Throwable $e) {}

        return function_exists('ec_scope_normalize_role') ? ec_scope_normalize_role($fallback, (string)($_SESSION['email'] ?? '')) : $fallback;
    }
}

if (!function_exists('ec_scope_available_conferences')) {
    function ec_scope_available_conferences(): array
    {
        ec_scope_session();

        $uid = (int)($_SESSION['user_id'] ?? 0);
        if ($uid <= 0) return [];

        try {
            $db = Database::getInstance();
            $u = ec_scope_user_row() ?: [];
            $role = ec_scope_role();

            if ($role === 'superadmin') {
                $stmt = $db->query("
                    SELECT c.*, o.name AS org_name
                    FROM conferences c
                    LEFT JOIN organizations o ON o.id=c.org_id
                    ORDER BY c.org_id, c.id
                ");
                return $stmt->fetchAll(PDO::FETCH_ASSOC);
            }

            $found = [];

            foreach (['conference_user_roles', 'user_conference_roles', 'conference_users', 'user_roles'] as $table) {
                if (!ec_scope_table_exists($db, $table)) continue;

                $cols = ec_scope_columns($db, $table);
                $userCol = ec_scope_first_col($cols, ['user_id', 'userid', 'uid']);
                $confCol = ec_scope_first_col($cols, ['conference_id', 'conf_id']);

                if (!$userCol || !$confCol) continue;

                try {
                    $stmt = $db->prepare("
                        SELECT DISTINCT c.*, o.name AS org_name
                        FROM `$table` t
                        JOIN conferences c ON c.id=t.`$confCol`
                        LEFT JOIN organizations o ON o.id=c.org_id
                        WHERE t.`$userCol`=?
                        ORDER BY c.id
                    ");
                    $stmt->execute([$uid]);

                    foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $c) {
                        $found[(int)$c['id']] = $c;
                    }
                } catch (Throwable $e) {}
            }

            /*
             * Track Chair conference discovery
             */
            try {

                if (
                    ec_scope_role() === 'track_chair'
                    &&
                    ec_scope_table_exists($db,'track_chair_assignments')
                ) {

                    $stmt = $db->prepare("
                        SELECT DISTINCT
                            c.*,
                            o.name AS org_name
                        FROM track_chair_assignments a
                        INNER JOIN conferences c
                            ON c.id = a.conference_id
                        LEFT JOIN organizations o
                            ON o.id = c.org_id
                        WHERE a.user_id = ?
                          AND a.is_active = 1
                        ORDER BY c.id
                    ");

                    $stmt->execute([$uid]);

                    foreach (
                        $stmt->fetchAll(PDO::FETCH_ASSOC)
                        as $c
                    ) {
                        $found[(int)$c['id']] = $c;
                    }
                }

            } catch (Throwable $e) {}

            if ($found) return array_values($found);

            $orgId = (int)($_SESSION['org_id'] ?? ($u['org_id'] ?? 0));
            if ($orgId > 0) {
                $stmt = $db->prepare("
                    SELECT c.*, o.name AS org_name
                    FROM conferences c
                    LEFT JOIN organizations o ON o.id=c.org_id
                    WHERE c.org_id=?
                    ORDER BY c.id
                ");
                $stmt->execute([$orgId]);
                $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
                if ($rows) return $rows;
            }

            $stmt = $db->query("
                SELECT c.*, o.name AS org_name
                FROM conferences c
                LEFT JOIN organizations o ON o.id=c.org_id
                ORDER BY c.id
                LIMIT 1
            ");
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Throwable $e) {
            return [];
        }
    }
}

if (!function_exists('ec_scope_set_conference')) {
    function ec_scope_set_conference(array $conference, string $role = ''): void
    {
        ec_scope_session();

        $_SESSION['conference_id'] = (int)$conference['id'];
        $_SESSION['current_conference_id'] = (int)$conference['id'];
        $_SESSION['org_id'] = (int)($conference['org_id'] ?? ($_SESSION['org_id'] ?? 0));
        $_SESSION['conference_short_name'] = (string)($conference['short_name'] ?? '');

        if ($role !== '') {
            //$_SESSION['conference_role'] = $role;
if (($_SESSION['role'] ?? '') !== 'superadmin') {
    $_SESSION['conference_role'] = $role;
}
            $_SESSION['role'] = $role;
            $_SESSION['user_role'] = $role;
        }

        $ids = [];
        foreach (ec_scope_available_conferences() as $c) {
            $ids[] = (int)$c['id'];
        }
        $_SESSION['conference_list'] = array_values(array_unique($ids));
    }
}

if (!function_exists('ec_scope_auto_select_conference')) {
    function ec_scope_auto_select_conference(bool $force = false): bool
    {
        ec_scope_session();

        if (empty($_SESSION['user_id'])) return false;

        $role = ec_scope_role();

        if ($role === 'superadmin') return false;

        $available = ec_scope_available_conferences();
        if (!$available) return false;

        /*
         * Track Chair:
         * prefer conferences that have
         * active track assignments.
         */
        if (
            ec_scope_role() === 'track_chair'
            &&
            !empty($_SESSION['user_id'])
        ) {

            try {

                $db = \App\Core\Database::getInstance();

                $st = $db->prepare("
                    SELECT DISTINCT conference_id
                    FROM track_chair_assignments
                    WHERE user_id = ?
                    AND is_active = 1
                    ORDER BY conference_id
                ");

                $st->execute([
                    (int)$_SESSION['user_id']
                ]);

                $trackConfs =
                    array_map(
                        'intval',
                        $st->fetchAll(\PDO::FETCH_COLUMN)
                    );

                if (!empty($trackConfs)) {

                    foreach ($available as $idx => $c) {

                        if (
                            in_array(
                                (int)$c['id'],
                                $trackConfs,
                                true
                            )
                        ) {

                            $available =
                                array_merge(
                                    [$c],
                                    array_filter(
                                        $available,
                                        fn($x) =>
                                            (int)$x['id']
                                            !==
                                            (int)$c['id']
                                    )
                                );

                            break;
                        }
                    }
                }

            } catch (\Throwable $e) {}

        }

        $current = (int)($_SESSION['conference_id'] ?? 0);

        if (!$force && $current > 0) {
            foreach ($available as $c) {
                if ((int)$c['id'] === $current) {
                    $resolvedRole = ec_scope_role_for_conference((int)$_SESSION['user_id'], (int)$c['id'], $role);
                    ec_scope_set_conference($c, $resolvedRole);
                    return true;
                }
            }
        }

        $selected = $available[0];
        $resolvedRole = ec_scope_role_for_conference((int)$_SESSION['user_id'], (int)$selected['id'], $role);
        ec_scope_set_conference($selected, $resolvedRole);

        return true;
    }
}

if (!function_exists('ec_scope_ensure_for_current_user')) {
    function ec_scope_ensure_for_current_user(): void
    {
        ec_scope_session();

        if (empty($_SESSION['user_id'])) return;

        if (ec_scope_role() !== 'superadmin' && empty($_SESSION['conference_id'])) {
            ec_scope_auto_select_conference(true);
        }
    }
}
