<?php
namespace App\Controllers;

use App\Core\Database;

require_once BASE_PATH . '/app/helpers/permissions.php';

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

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

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

    private function requireAccess(string $action = 'view'): void
    {
        $this->startSession();

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

        if (empty($_SESSION['conference_id'])) {
            header("Location: /easychair/select-conference");
            exit;
        }

        if (!in_array($this->role(), ['super_admin','org_admin','admin'], true)) {
            http_response_code(403);
            exit(function_exists('ec_t') ? ec_t('msg.access_denied', 'Access denied.') : 'Access denied.');
        }

        if (function_exists('ec_require_action')) {
            ec_require_action('/easychair/admin/rbac-scope', $action);
        }
    }

    private function currentConference(): array
    {
        $stmt = $this->db()->prepare("
            SELECT c.*, o.name AS org_name
            FROM conferences c
            LEFT JOIN organizations o ON o.id=c.org_id
            WHERE c.id=?
            LIMIT 1
        ");
        $stmt->execute([(int)$_SESSION['conference_id']]);
        $c = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$c) {
            exit('Conference not found.');
        }

        if ($this->role() !== 'super_admin' && (int)$c['org_id'] !== (int)($_SESSION['org_id'] ?? 0)) {
            http_response_code(403);
            exit(function_exists('ec_t') ? ec_t('msg.access_denied', 'Access denied.') : 'Access denied.');
        }

        return $c;
    }

    public function index()
    {
        $this->requireAccess('view');
        $conference = $this->currentConference();

        if ($this->role() === 'super_admin') {
            $stmt = $this->db()->query("
                SELECT c.id, c.org_id, c.short_name, c.title_en, c.title_ar, 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
            ");
            $conferences = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        } else {
            $stmt = $this->db()->prepare("
                SELECT c.id, c.org_id, c.short_name, c.title_en, c.title_ar, 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([(int)$conference['org_id']]);
            $conferences = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        }

        $roles = $this->db()->query("
            SELECT id, code, name
            FROM roles
            WHERE code NOT IN ('super_admin')
            ORDER BY code
        ")->fetchAll(\PDO::FETCH_ASSOC);

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

        $summary = [];
        try {
            $stmt = $this->db()->prepare("
                SELECT r.code, COUNT(*) AS total,
                       SUM(CASE WHEN rp.is_allowed=1 AND rp.can_view=1 THEN 1 ELSE 0 END) AS visible
                FROM rbac_role_menu_permissions rp
                JOIN roles r ON r.id=rp.role_id
                WHERE rp.conference_id=?
                  AND rp.org_id=?
                GROUP BY r.code
                ORDER BY r.code
            ");
            $stmt->execute([(int)$conference['id'], (int)$conference['org_id']]);
            $summary = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        } catch (\Throwable $e) {
            $summary = [];
        }

        ob_start();
        require BASE_PATH . '/app/views/admin/rbac_scope/index.php';
        $content = ob_get_clean();

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

    public function copy()
    {
        $this->requireAccess('create');
        $current = $this->currentConference();

        $sourceId = (int)($_POST['source_conference_id'] ?? 0);
        $targetId = (int)($_POST['target_conference_id'] ?? 0);
        $roleIds = $_POST['role_ids'] ?? [];

        if ($sourceId <= 0 || $targetId <= 0 || $sourceId === $targetId || empty($roleIds)) {
            $_SESSION['flash_error'] = 'Please choose source, target, and at least one role.';
            header("Location: /easychair/admin/rbac-scope");
            exit;
        }

        $stmt = $this->db()->prepare("SELECT id, org_id FROM conferences WHERE id IN (?, ?)");
        $stmt->execute([$sourceId, $targetId]);
        $found = $stmt->fetchAll(\PDO::FETCH_ASSOC);

        if (count($found) < 2) {
            $_SESSION['flash_error'] = 'Invalid conference selection.';
            header("Location: /easychair/admin/rbac-scope");
            exit;
        }

        $orgs = [];
        foreach ($found as $c) {
            $orgs[(int)$c['id']] = (int)$c['org_id'];
        }

        if ($this->role() !== 'super_admin') {
            if ($orgs[$sourceId] !== (int)$current['org_id'] || $orgs[$targetId] !== (int)$current['org_id']) {
                http_response_code(403);
                exit(function_exists('ec_t') ? ec_t('msg.access_denied', 'Access denied.') : 'Access denied.');
            }
        }

        $sourceOrgId = $orgs[$sourceId];
        $targetOrgId = $orgs[$targetId];

        $roleIds = array_values(array_filter(array_map('intval', $roleIds)));

        if (!$roleIds) {
            $_SESSION['flash_error'] = 'No valid roles selected.';
            header("Location: /easychair/admin/rbac-scope");
            exit;
        }

        if ($this->role() !== 'super_admin') {
            $super = $this->db()->query("SELECT id FROM roles WHERE code='super_admin'")->fetchColumn();
            $roleIds = array_values(array_filter($roleIds, fn($id) => (int)$id !== (int)$super));
        }

        $in = implode(',', array_fill(0, count($roleIds), '?'));

        $this->db()->beginTransaction();

        try {
            $params = array_merge([$targetOrgId, $targetId], $roleIds);

            $del = $this->db()->prepare("
                DELETE FROM rbac_role_menu_permissions
                WHERE org_id=?
                  AND conference_id=?
                  AND role_id IN ($in)
            ");
            $del->execute($params);

            $params = array_merge([$targetOrgId, $targetId, (int)$_SESSION['user_id'], $sourceOrgId, $sourceId], $roleIds);

            $copy = $this->db()->prepare("
                INSERT INTO rbac_role_menu_permissions
                (org_id, conference_id, role_id, menu_item_id, is_allowed, can_view, can_create, can_update, can_delete, updated_by)
                SELECT
                    ?, ?, role_id, menu_item_id, is_allowed, can_view, can_create, can_update, can_delete, ?
                FROM rbac_role_menu_permissions
                WHERE org_id=?
                  AND conference_id=?
                  AND role_id IN ($in)
            ");
            $copy->execute($params);

            $this->db()->commit();

            $_SESSION['flash_success'] = 'Permissions copied successfully.';
        } catch (\Throwable $e) {
            $this->db()->rollBack();
            $_SESSION['flash_error'] = 'Copy failed: ' . $e->getMessage();
        }

        header("Location: /easychair/admin/rbac-scope");
        exit;
    }
}
