<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Arr;

use App\Models\Permission;
use App\Http\Requests\PermissionValidation;

use App\Models\User;
use App\Models\Role;
use App\Models\Page;

class PermissionsController extends Controller
{
    public function pages()
    {
        if (!auth()->user()->can('viewAny', Permission::class)) {
            return redirect('/')->with(['error' => 'You do not have permission to view that page']);
        }

        return view('permissions.pages');
    }

    public function load()
    {
        if (!auth()->user()->can('viewAny', Permission::class)) {
            return response()->json(['error' => 'You do not have permission to view page accesses'], 403);
        }

        $objectables = collect();
        foreach (requestInput('objectables') as $objectable_data) {
            $objectable = Permission::findObjectable($objectable_data);
            $objectable = $this->loadAttributes($objectable);
            $objectables->push($objectable);
        }

        return response()->json([
            'objectables' => $objectables,
        ]);
    }

    public function store(PermissionValidation $request)
    {
        $objectables = collect();
        $errors = collect();

        foreach (requestInput('objectables') as $objectable_data) {
            $objectable = Permission::findObjectable($objectable_data);
            $action = requestInput('action');

            if ($objectable->getPolicyMethods()->contains($action)) {
                if (requestInput('users')) {
                    foreach (requestInput('users') as $user) {
                        $user = User::findOrFail(Arr::get($user, 'id'));
                        $objectable->createPermission($action, $user);
                    }
                }

                if (requestInput('roles')) {
                    foreach (requestInput('roles') as $role) {
                        $role = Role::findOrFail(Arr::get($role, 'id'));
                        $objectable->createPermission($action, $role);
                    }
                }
            } else {
                $errors->push('No '.$action.' permission available');
            }

            $objectable = $this->loadAttributes($objectable);

            $objectables->push($objectable);
        }

        return response()->json([
            'success' => 'Permissions Saved',
            'errors' => ['action' => $errors],
            'objectables' => $objectables->each->load('permissions', 'permissions.accessable'),
            //'objectable' => $objectable->refresh()->load('permissions', 'permissions.accessable'),
        ]);
    }

    public function destroy($id)
    {
        $permission = Permission::findOrFail($id);

        if (!auth()->user()->can('delete', $permission)) {
            return response()->json(['error' => 'You do not have permission to remove page accesses'], 403);
        }

        $permission->delete();

        return response()->json(['success' => 'Permission Removed']);
    }

    protected function loadAttributes($objectable)
    {
        $objectable->load('permissions', 'permissions.accessable');
        $objectable->available_actions = $objectable->getPolicyMethods();

        if (method_exists($objectable, 'appendAttributes')) {
            $objectable->appendAttributes();
        }

        return $objectable;
    }
}
