<?php
namespace App\Controllers;

use App\Core\Database;

class ConferenceSelectController
{
    protected function db()
    {
        return Database::getInstance();
    }

    private function startSession(): void
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }
    }

    private function requireLogin(): void
    {
        $this->startSession();

        if (empty($_SESSION['user_id'])) {
            header("Location: /easychair/login");
            exit;
        }
    }

    private function role(): string
    {
        return (string)($_SESSION['role'] ?? $_SESSION['user_role'] ?? '');
    }

    public function index()
    {
        $this->requireLogin();

        $db = $this->db();

        $role = $this->role();
        $userId = (int)$_SESSION['user_id'];
        $orgFilter = (int)($_GET['org_id'] ?? 0);
        $q = trim((string)($_GET['q'] ?? ''));
        $status = trim((string)($_GET['status'] ?? ''));

        $organizations = [];

        if ($role === 'super_admin') {
            $organizations = $db->query("
                SELECT id, name
                FROM organizations
                ORDER BY name ASC, id ASC
            ")->fetchAll(\PDO::FETCH_ASSOC);
        }

        if ($role === 'super_admin') {
            $where = " WHERE 1=1 ";
            $params = [];

            if ($orgFilter > 0) {
                $where .= " AND c.org_id = ? ";
                $params[] = $orgFilter;
            }

            if ($q !== '') {
                $where .= " AND (
                    c.short_name LIKE ?
                    OR c.title_ar LIKE ?
                    OR c.title_en LIKE ?
                    OR o.name LIKE ?
                ) ";
                $like = '%' . $q . '%';
                array_push($params, $like, $like, $like, $like);
            }

            if ($status !== '') {
                $where .= " AND c.status = ? ";
                $params[] = $status;
            }

            $stmt = $db->prepare("
                SELECT
                    c.*,
                    o.name AS org_name,
                    p.conference_id AS current_conference_id,
                    COUNT(DISTINCT s.id) AS submissions_count,
                    COUNT(DISTINCT uc.user_id) AS members_count
                FROM conferences c
                LEFT JOIN organizations o ON o.id = c.org_id
                LEFT JOIN org_conference_policy p ON p.org_id = c.org_id
                LEFT JOIN submissions s ON s.conference_id = c.id
                LEFT JOIN user_conferences uc ON uc.conference_id = c.id
                {$where}
                GROUP BY c.id, o.name, p.conference_id
                ORDER BY c.org_id ASC, c.id DESC
            ");
            $stmt->execute($params);
            $conferences = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        } else {
            $where = " WHERE uc.user_id = ? ";
            $params = [$userId];

            if ($q !== '') {
                $where .= " AND (
                    c.short_name LIKE ?
                    OR c.title_ar LIKE ?
                    OR c.title_en LIKE ?
                    OR o.name LIKE ?
                ) ";
                $like = '%' . $q . '%';
                array_push($params, $like, $like, $like, $like);
            }

            if ($status !== '') {
                $where .= " AND c.status = ? ";
                $params[] = $status;
            }

            /*
             * Normal users only see assigned conferences.
             * If org policy exists, only current org conference is shown.
             */
            $stmt = $db->prepare("
                SELECT
                    c.*,
                    o.name AS org_name,
                    p.conference_id AS current_conference_id,
                    r.code AS membership_role_code,
                    uc.role_id AS membership_role_id
                FROM user_conferences uc
                JOIN conferences c ON c.id = uc.conference_id
                LEFT JOIN organizations o ON o.id = c.org_id
                LEFT JOIN org_conference_policy p ON p.org_id = c.org_id
                LEFT JOIN roles r ON r.id = uc.role_id
                {$where}
                  AND c.id = COALESCE(p.conference_id, c.id)
                ORDER BY c.id DESC
            ");
            $stmt->execute($params);
            $conferences = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        }

        ob_start();
        require BASE_PATH . '/app/views/conference/select.php';
        $content = ob_get_clean();

        require BASE_PATH . '/app/views/layouts/header.php';
        echo $content;
        require BASE_PATH . '/app/views/layouts/footer.php';
    }

    public function select()
    {
        $this->requireLogin();

        $db = $this->db();

        $conferenceId = (int)($_POST['conference_id'] ?? $_GET['conference_id'] ?? 0);

        if ($conferenceId <= 0) {
            exit("Conference is required.");
        }

        $stmt = $db->prepare("
            SELECT *
            FROM conferences
            WHERE id = ?
            LIMIT 1
        ");
        $stmt->execute([$conferenceId]);
        $conference = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$conference) {
            exit("Conference not found.");
        }

        $role = $this->role();

        if ($role !== 'super_admin') {
            $stmt = $db->prepare("
                SELECT uc.*, r.code AS role_code
                FROM user_conferences uc
                LEFT JOIN roles r ON r.id = uc.role_id
                WHERE uc.user_id = ?
                  AND uc.conference_id = ?
                LIMIT 1
            ");
            $stmt->execute([(int)$_SESSION['user_id'], $conferenceId]);
            $membership = $stmt->fetch(\PDO::FETCH_ASSOC);

            if (!$membership) {
                http_response_code(403);
                exit("You are not assigned to this conference.");
            }

            $stmt = $db->prepare("
                SELECT conference_id
                FROM org_conference_policy
                WHERE org_id = ?
                LIMIT 1
            ");
            $stmt->execute([(int)$conference['org_id']]);
            $currentConferenceId = (int)$stmt->fetchColumn();

            if ($currentConferenceId > 0 && $currentConferenceId !== $conferenceId) {
                http_response_code(403);
                exit("This is not the current conference for your organization.");
            }

            $_SESSION['conference_role_id'] = (int)($membership['role_id'] ?? 0);
            $_SESSION['conference_role'] = (string)($membership['role_code'] ?? '');
        }

        $_SESSION['conference_id'] = $conferenceId;
        $_SESSION['org_id'] = (int)$conference['org_id'];

        if (!isset($_SESSION['conference_list']) || !is_array($_SESSION['conference_list'])) {
            $_SESSION['conference_list'] = [];
        }

        if (!in_array($conferenceId, $_SESSION['conference_list'], true)) {
            $_SESSION['conference_list'][] = $conferenceId;
        }

        $redirect = '/easychair/dashboard';

        $effectiveRole = $_SESSION['conference_role'] ?? $_SESSION['role'] ?? $_SESSION['user_role'] ?? '';

        if (in_array($effectiveRole, ['super_admin','org_admin','admin','organizer','conference_chair','track_chair'], true)) {
            $redirect = '/easychair/admin/dashboard';
        } elseif ($effectiveRole === 'reviewer') {
            $redirect = '/easychair/reviewer/dashboard';
        } else {
            $redirect = '/easychair/author/dashboard';
        }

        header("Location: " . $redirect);
        exit;
    }
}
