<?php

declare(strict_types=1);

namespace App\Modules\Administration\Controllers;

use App\Controllers\Controller;
use App\Modules\Administration\Services\AuthenticationService;
use App\Modules\Administration\Services\PermissionService;
use RuntimeException;
use System\Http\Request;
use System\View\View;
use App\Modules\Administration\Services\AuthorizationService;

final class PermissionController extends Controller
{
public function __construct(
    private AuthenticationService $authentication,
    private AuthorizationService $authorization,
    private PermissionService $permissionService,
    private Request $request,
    View $view
) {
    parent::__construct($view);
}
private function requirePermission(
    string $permission
): void {
    if (!$this->authorization->can($permission)) {

        header(
            'Location: /public/403'
        );

        exit;
    }
}
    private function protect(): void
    {
        if (!$this->authentication->check()) {

            header(
                'Location: /public/login'
            );

            exit;
        }
    }

    public function index(): void
    {
        $this->protect();
// index()
$this->requirePermission(
    'permissions.view'
);

// create, store, edit, update, toggleStatus
$this->requirePermission(
    'permissions.manage'
);
        $this->render(
            'permissions/index',
            [
                'title' =>
                    'Permission Management',

                'permissions' =>
                    $this->permissionService->all(),

                'created' =>
                    $this->request->input(
                        'created'
                    ),

                'updated' =>
                    $this->request->input(
                        'updated'
                    ),

                'statusChanged' =>
                    $this->request->input(
                        'status_changed'
                    ),

                'error' =>
                    $this->request->input(
                        'error'
                    )
            ]
        );
    }

    public function create(): void
    {
        $this->protect();

        $this->render(
            'permissions/create',
            [
                'title' =>
                    'Create Permission'
            ]
        );
    }

    public function store(): void
    {
        $this->protect();

        try {

            $this->permissionService->create(
                $this->request->all()
            );

            header(
                'Location: /public/permissions?created=1'
            );

            exit;

        } catch (\Throwable $exception) {

            $this->render(
                'permissions/create',
                [
                    'title' =>
                        'Create Permission',

                    'error' =>
                        $exception->getMessage(),

                    'old' =>
                        $this->request->all()
                ]
            );
        }
    }

    public function edit(): void
    {
        $this->protect();

        $id = (int) $this->request->input(
            'id',
            0
        );

        $permission =
            $this->permissionService->find(
                $id
            );

        if ($permission === null) {
            throw new RuntimeException(
                'Permission not found.'
            );
        }

        $this->render(
            'permissions/edit',
            [
                'title' =>
                    'Edit Permission',

                'permission' =>
                    $permission
            ]
        );
    }

    public function update(): void
    {
        $this->protect();

        $id = (int) $this->request->input(
            'id',
            0
        );

        try {

            $this->permissionService->update(
                $id,
                $this->request->all()
            );

            header(
                'Location: /public/permissions?updated=1'
            );

            exit;

        } catch (\Throwable $exception) {

            $this->render(
                'permissions/edit',
                [
                    'title' =>
                        'Edit Permission',

                    'permission' =>
                        $this->permissionService
                            ->find($id),

                    'error' =>
                        $exception->getMessage()
                ]
            );
        }
    }

    public function toggleStatus(): void
    {
        $this->protect();

        $id = (int) $this->request->input(
            'id',
            0
        );

        try {

            $this->permissionService
                ->toggleStatus($id);

            header(
                'Location: /public/permissions?status_changed=1'
            );

        } catch (\Throwable $exception) {

            header(
                'Location: /public/permissions?error=' .
                urlencode(
                    $exception->getMessage()
                )
            );
        }

        exit;
    }
}