<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Auth;
use App\Core\Csrf;
use App\Core\DB;
use App\Core\Request;
use App\Core\Response;
use App\Repositories\RoleRepository;
use App\Services\RoleService;
use App\Shared\Security\RbacSupport;
use Throwable;

final class RoleController
{
    private \PDO $pdo;
    private RoleRepository $roles;
    private RoleService $service;

    public function __construct()
    {
        $this->pdo = DB::pdo();
        $this->roles = new RoleRepository($this->pdo);
        $this->service = new RoleService($this->pdo, $this->roles);
    }

    public function handle(): void
    {
        Auth::requireLogin();

        if (!rbac_enabled($this->pdo)) {
            Response::flash('danger', 'يجب تشغيل ملف التحديث: sql/migrate_v1_19_auth_admin.sql');
            Response::view('pages/admin/roles', ['rbac_ready' => false]);
            return;
        }

        require_permission('roles.view');

        $action = (string) Request::input('action', '');
        $roleId = Request::int('role_id');

        try {
            if ($action === 'create' && Request::isPost()) {
                $this->create();
                return;
            }

            if ($action === 'save_perms' && Request::isPost()) {
                $this->savePermissions();
                return;
            }

            if ($action === 'delete' && Request::isPost() && $roleId > 0) {
                $this->delete($roleId);
                return;
            }
        } catch (Throwable $e) {
            if ($this->pdo->inTransaction()) {
                $this->pdo->rollBack();
            }
            Response::flash('danger', 'خطأ: ' . $e->getMessage());
            Response::redirect('/admin/roles');
            return;
        }

        $this->index($action, $roleId);
    }

    private function index(string $action, int $roleId): void
    {
        RbacSupport::ensurePermissionsSeed($this->pdo);
        $roles = $this->roles->allRoles();
        $permsByModule = $this->roles->allPermissionsGroupedByModule();

        $editRole = null;
        $assigned = [];
        if (($action === 'edit' || $roleId > 0) && $roleId > 0) {
            $editRole = $this->roles->findRole($roleId);
            if ($editRole) {
                $assigned = $this->roles->assignedPermissionCodes($roleId);
            }
        }

        Response::view('pages/admin/roles', [
            'rbac_ready' => true,
            'roles' => $roles,
            'permsByModule' => $permsByModule,
            'editRole' => $editRole,
            'assigned' => $assigned,
        ]);
    }

    private function create(): void
    {
        Csrf::verify();
        require_permission('roles.edit');
        $name = trim((string) Request::post('name', ''));
        $newRoleId = $this->service->create($name);
        audit_log('ROLE_CREATE', 'roles', $newRoleId, ['name' => $name]);
        Response::flash('success', 'تم إنشاء الدور');
        Response::redirect('/admin/roles?role_id=' . $newRoleId . '&action=edit');
    }

    private function savePermissions(): void
    {
        Csrf::verify();
        require_permission('roles.edit');
        $roleId = (int) Request::post('role_id', 0);
        if ($roleId <= 0) {
            Response::flash('danger', 'دور غير صحيح');
            Response::redirect('/admin/roles');
            return;
        }

        $this->service->savePermissions($roleId, Request::post('perms', []));
        audit_log('ROLE_PERMS_UPDATE', 'roles', $roleId, ['perms' => Request::post('perms', [])]);
        Response::flash('success', 'تم حفظ الصلاحيات');
        Response::redirect('/admin/roles?role_id=' . $roleId . '&action=edit');
    }

    private function delete(int $roleId): void
    {
        Csrf::verify();
        require_permission('roles.edit');
        $this->service->delete($roleId);
        audit_log('ROLE_DELETE', 'roles', $roleId, []);
        Response::flash('success', 'تم حذف الدور');
        Response::redirect('/admin/roles');
    }
}
