<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\ApiBaseController;
use App\Http\Requests\Api\Role\IndexRequest;
use App\Http\Requests\Api\Role\StoreRequest;
use App\Http\Requests\Api\Role\UpdateRequest;
use App\Http\Requests\Api\Role\DeleteRequest;
use App\Models\Role;
use Examyou\RestAPI\Exceptions\ApiException;

class RolesController extends ApiBaseController
{
    /**
     * The model associated with the controller.
     *
     * @var string
     */
    protected $model = Role::class;

    /**
     * The request class for index operations.
     *
     * @var string
     */
    protected $indexRequest = IndexRequest::class;

    /**
     * The request class for store operations.
     *
     * @var string
     */
    protected $storeRequest = StoreRequest::class;

    /**
     * The request class for update operations.
     *
     * @var string
     */
    protected $updateRequest = UpdateRequest::class;

    /**
     * The request class for delete operations.
     *
     * @var string
     */
    protected $deleteRequest = DeleteRequest::class;

    /**
     * Hook: After storing a new role
     * Sync permissions for the role
     *
     * @param Role $role
     * @return Role
     */
    public function stored(Role $role)
    {
        return $this->saveAndUpdatePermissions($role);
    }

    /**
     * Hook: Before updating a role
     * Prevent editing admin role
     *
     * @param Role $role
     * @return Role
     * @throws ApiException
     */
    public function updating(Role $role)
    {
        if ($role->name == 'admin') {
            throw new ApiException('Admin role cannot be edited');
        }

        return $role;
    }

    /**
     * Hook: After updating a role
     * Sync permissions for the role
     *
     * @param Role $role
     * @return Role
     */
    public function updated(Role $role)
    {
        return $this->saveAndUpdatePermissions($role);
    }

    /**
     * Hook: Before destroying a role
     * Prevent deleting admin role
     *
     * @param Role $role
     * @return Role
     * @throws ApiException
     */
    public function destroying(Role $role)
    {
        if ($role->name == 'admin') {
            throw new ApiException('Admin role cannot be deleted');
        }

        return $role;
    }

    /**
     * Save and update permissions for a role
     *
     * @param Role $role
     * @return Role
     */
    public function saveAndUpdatePermissions($role)
    {
        $request = request();

        if ($request->has('permissions')) {
            $permissions = [];
            $allPermissions = $request->permissions;

            foreach ($allPermissions as $allPermission) {
                $permissions[] = $this->getIdFromHash($allPermission);
            }

            $role->savePermissions($permissions);
        }

        return $role;
    }
}
