<?php

namespace Modules\Roles\Controllers;

use App\Controllers\BaseController;
use App\Models\PermissionModel;
use App\Models\RoleModel;
use App\Models\RolePermissionModel;
use Modules\Roles\Services\RoleService;

class RoleController extends BaseController
{
    protected RoleModel $roles;
    protected RoleService $service;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->roles   = new RoleModel();
        $this->service = new RoleService();
    }

    public function index()
    {
        $roles = $this->roles->orderBy('name', 'ASC')->findAll();
        $rolePermissions = new RolePermissionModel();

        $counts = [];
        foreach ($roles as $r) {
            $counts[$r['id']] = count($rolePermissions->permissionIdsForRole($r['id']));
        }

        return view('Modules\Roles\Views\roles_index', array_merge($this->baseViewData(), [
            'title'       => 'Roles',
            'breadcrumbs' => ['Dashboard' => base_url('dashboard'), 'Roles'],
            'roles'       => $roles,
            'permCounts'  => $counts,
        ]));
    }

    public function createForm()
    {
        return view('Modules\Roles\Views\role_create', array_merge($this->baseViewData(), [
            'title'       => 'Add Role',
            'breadcrumbs' => ['Dashboard' => base_url('dashboard'), 'Roles' => base_url('roles'), 'Add Role'],
        ]));
    }

    public function store()
    {
        if (! $this->validate(['name' => 'required|min_length[2]|max_length[100]'])) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $result = $this->service->create($this->request->getPost(), (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->back()->withInput()->with('errors', $result['errors']);
        }

        return redirect()->to('/roles')->with('success', 'Role created.');
    }

    public function editForm(int $id)
    {
        $role = $this->roles->find($id);
        if (! $role) {
            return redirect()->to('/roles')->with('error', 'Role not found.');
        }

        $grouped     = (new PermissionModel())->grouped();
        $assignedIds = (new RolePermissionModel())->permissionIdsForRole($id);

        return view('Modules\Roles\Views\role_edit', array_merge($this->baseViewData(), [
            'title'         => 'Edit Role',
            'breadcrumbs'   => ['Dashboard' => base_url('dashboard'), 'Roles' => base_url('roles'), 'Edit Role'],
            'role'          => $role,
            'groupedPerms'  => $grouped,
            'assignedIds'   => $assignedIds,
        ]));
    }

    public function update(int $id)
    {
        if (! $this->validate(['name' => 'required|min_length[2]|max_length[100]'])) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $result = $this->service->update($id, $this->request->getPost(), (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->back()->withInput()->with('errors', $result['errors']);
        }

        return redirect()->to('/roles')->with('success', 'Role updated.');
    }

    public function updatePermissions(int $id)
    {
        $permissionIds = (array) $this->request->getPost('permissions');
        $this->service->syncPermissions($id, $permissionIds, (int) $this->session->get('user_id'));

        return redirect()->to('/roles/' . $id . '/edit')->with('success', 'Permission matrix updated.');
    }

    public function destroy(int $id)
    {
        $result = $this->service->delete($id, (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->to('/roles')->with('error', $result['error']);
        }

        return redirect()->to('/roles')->with('success', 'Role deleted.');
    }
}
