<?php

namespace App\Controllers;

use App\Core\Database;
use App\Services\RoleAssignmentService;

class AdminRolesController
{
    private function db()
    {
        return Database::getInstance();
    }

    /*
    -----------------------------------------
    SAFE ORGANIZATION RESOLVER
    -----------------------------------------
    */

    private function orgId(): int
    {
        $orgId = (int)($_SESSION['org_id'] ?? 0);

        if (
            $orgId <= 0 &&
            (
                ($_SESSION['role'] ?? '') === 'super_admin'
                || ($_SESSION['user_role'] ?? '') === 'super_admin'
                || ($_SESSION['conference_role'] ?? '') === 'super_admin'
                || (($_SESSION['user']['role_id'] ?? 0) == 1)
            )
        ) {

            $orgId = (int)(
                $_SESSION['user']['org_id']
                ?? 1
            );

            $_SESSION['org_id'] = $orgId;
        }

        return $orgId;
    }

    /*
    -----------------------------------------
    ACCESS
    -----------------------------------------
    */

    private function requireAccess()
    {
        if (
            ($_SESSION['role'] ?? '')
            !==
            'super_admin'
        ) {
            die("Access denied.");
        }
    }

    /*
    -----------------------------------------
    INDEX
    -----------------------------------------
    */

    public function index()
    {
        requirePermission(
            'roles.manage',
            'view'
        );

        $db = $this->db();

        /*
        -----------------------------------------
        ORGANIZATION CONTEXT
        -----------------------------------------
        */

        $orgId = $this->orgId();

        if ($orgId <= 0) {
            die("Organization context missing.");
        }

        /*
        -----------------------------------------
        LOAD ROLES
        -----------------------------------------
        */

        $roles =
            $db->query("
                SELECT
                    r.id,
                    r.name,
                    r.code,

                    COUNT(DISTINCT u.id)
                        AS global_users_count,

                    COUNT(DISTINCT cur.user_id)
                        AS conference_users_count

                FROM roles r

                LEFT JOIN users u
                    ON u.role_id = r.id

                LEFT JOIN conference_user_roles cur
                    ON cur.role_code = r.code

                GROUP BY
                    r.id,
                    r.name,
                    r.code

                ORDER BY r.id
            ")
            ->fetchAll(\PDO::FETCH_ASSOC);

        /*
        -----------------------------------------
        LOAD USERS
        -----------------------------------------
        */

        $users =
            $db->query("
                SELECT
                    id,
                    first_name,
                    last_name,
                    email
                FROM users
                ORDER BY first_name
            ")
            ->fetchAll(\PDO::FETCH_ASSOC);

        /*
        -----------------------------------------
        LOAD ORGANIZATION
        -----------------------------------------
        */

        $stmt =
            $db->prepare("
                SELECT
                    id,
                    name
                FROM organizations
                WHERE id = ?
                LIMIT 1
            ");

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

        $organizations =
            $stmt->fetchAll(
                \PDO::FETCH_ASSOC
            );

        /*
        -----------------------------------------
        LOAD CONFERENCES
        -----------------------------------------
        */

        $lang =
            $_SESSION['lang']
            ?? 'ar';

        $titleField =
            $lang === 'en'
            ? 'title_en'
            : 'title_ar';

        $stmt =
            $db->prepare("
                SELECT
                    id,
                    {$titleField} AS title,
                    org_id
                FROM conferences
                WHERE org_id = ?
                ORDER BY id DESC
            ");

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

        $conferences =
            $stmt->fetchAll(
                \PDO::FETCH_ASSOC
            );

        /*
        -----------------------------------------
        DEBUG
        -----------------------------------------
        */

        error_log(
            "ROLES PAGE: org="
            . $orgId
            . " conferences="
            . count($conferences)
        );

        /*
        -----------------------------------------
        ROLE MATRIX
        -----------------------------------------
        */

        $matrix = [

            'super_admin' => [
                'Full system access',
                'All organizations',
                'All conferences',
                'All data'
            ],

            'org_admin' => [
                'Organization administration',
                'Users in organization',
                'Conference management'
            ],

            'conference_chair' => [
                'Review workflow',
                'Assignments',
                'Decisions'
            ],

            'organizer' => [
                'Operational management',
                'Submissions',
                'Reviewers'
            ],

            'track_chair' => [
                'Track workflow',
                'Assignments'
            ],

            'reviewer' => [
                'Assigned reviews only'
            ],

            'author' => [
                'Own submissions'
            ],
        ];

        /*
        -----------------------------------------
        RENDER
        -----------------------------------------
        */

        ob_start();

        require BASE_PATH .
            '/app/views/admin/roles/index.php';

        $content = ob_get_clean();

        require BASE_PATH .
            '/app/views/layouts/admin_layout.php';
    }

    /*
    -----------------------------------------
    ASSIGN USER ROLE
    -----------------------------------------
    */

    public function assignUserRole()
    {
        requirePermission(
            'roles.manage',
            'view'
        );

        $userId =
            (int)($_POST['user_id'] ?? 0);

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

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

        $orgId = $this->orgId();

        if (
            !$userId
            ||
            !$conferenceId
            ||
            !$roleCode
        ) {
            die("Invalid role assignment.");
        }

        RoleAssignmentService::assignRole(

            $userId,

            $conferenceId,

            $roleCode,

            $orgId,

            (int)$_SESSION['user_id']
        );

        header(
            "Location: /easychair/admin/roles"
        );

        exit;
    }

    /*
    -----------------------------------------
    REVOKE ROLE
    -----------------------------------------
    */

    public function revokeUserRole()
    {
        requirePermission(
            'roles.manage',
            'view'
        );

        $roleId =
            (int)($_POST['role_id'] ?? 0);

        if (!$roleId) {
            die("Invalid role.");
        }

        $this->db()->prepare("
            DELETE
            FROM conference_user_roles
            WHERE id = ?
        ")
        ->execute([
            $roleId
        ]);

        error_log(
            "ROLE REMOVED: "
            . $roleId
        );

        header(
            "Location: /easychair/admin/roles"
        );

        exit;
    }

    /*
    -----------------------------------------
    TEMP ASSIGN
    -----------------------------------------
    */

    public function assign()
    {
        $this->requireAccess();

        $db = $this->db();

        $orgId = $this->orgId();

        $userId =
            (int)($_POST['user_id'] ?? 0);

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

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

        if (
            !$userId
            ||
            !$conferenceId
            ||
            !$roleCode
        ) {
            die("Invalid assignment.");
        }

        /*
        Validate conference ownership
        */

        $stmt =
            $db->prepare("
                SELECT id
                FROM conferences
                WHERE id = ?
                AND org_id = ?
            ");

        $stmt->execute([
            $conferenceId,
            $orgId
        ]);

        if (!$stmt->fetchColumn()) {

            die(
                "Invalid conference for organization."
            );
        }

        /*
        Assign role
        */

        RoleAssignmentService::assignRole(

            $userId,

            $conferenceId,

            $roleCode,

            $orgId,

            (int)$_SESSION['user_id']
        );

        header(
            "Location: /easychair/admin/roles"
        );

        exit;
    }

    public function edit()
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

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

        $id =
            (int)($_GET['id'] ?? 0);

        $stmt = $db->prepare("

            SELECT *
            FROM roles
            WHERE id = ?
            LIMIT 1

        ");

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

        $role =
            $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$role) {

            die('Role not found.');
        }

        require BASE_PATH .
            '/app/views/admin/roles/edit.php';
    }

    public function update()
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

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

        $id =
            (int)($_POST['id'] ?? 0);

        $stmt = $db->prepare("

            UPDATE roles

            SET

            name = ?,
            code = ?

            WHERE id = ?

        ");

        $stmt->execute([

            trim($_POST['name'] ?? ''),

            trim($_POST['code'] ?? ''),

            $id

        ]);

        header(
            'Location: /easychair/admin/roles'
        );

        exit;
    }

    public function delete()
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

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

        $id =
            (int)($_GET['id'] ?? 0);

        $stmt = $db->prepare("

            SELECT *
            FROM roles
            WHERE id = ?
            LIMIT 1

        ");

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

        $role =
            $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$role) {

            die('Role not found.');
        }

        $protected = [

            'super_admin',
            'admin',
            'author',
            'reviewer',
            'organizer'

        ];

        if (
            in_array(
                $role['code'],
                $protected,
                true
            )
        ) {

            die('Protected role.');
        }

        $stmt = $db->prepare("

            DELETE FROM roles
            WHERE id = ?
            LIMIT 1

        ");

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

        header(
            'Location: /easychair/admin/roles'
        );

        exit;
    }

}


