<?php

namespace App\Http\Controllers;

use App\Models\LogHistory;
use Exception;
use App\Models\User;
use App\Models\User_details;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Spatie\Permission\Models\Role;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Auth;
use Spatie\Permission\Models\Permission;

class RolesController extends Controller
{

    public function __construct()
    {
        $this->middleware('permission:role_index|role_create|role_edit|role_destroy', ['only' => ['index', 'show']]);
        $this->middleware('permission:role_create', ['only' => ['create', 'store']]);
        $this->middleware('permission:role_edit', ['only' => ['edit', 'update']]);
        $this->middleware('permission:role_destroy', ['only' => ['destroy']]);
    }

    public function index()
    {
        $roles = Role::with('permissions')->where('name', '!=', 'SoftwareAdmin')->get();
        return view('role.roleList', [
            'list' => $roles
        ]);
    }

    public function create()
    {
        if (Auth::user()->email == 'admin@gmail.com') {
            return redirect()->back()->with('error_message', 'You can not Add New Role');
        }

        return view('role.createRole', [
            'page_title' => 'Create New Role'
        ]);
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|unique:roles',

        ]);
        Role::create(['name' => $request->name]);
        return redirect()->back()->with('success_message', 'Role Created successfully');
    }

    public function show($id)
    {
        //
    }

    public function edit($id)
    {
        return view('role.editRole', [
            'page_title' => 'Edit Role',
            'role'       => Role::find($id)
        ]);
    }

    public function update(Request $request, $id)
    {
        if (Auth::user()->email == 'admin@gmail.com') {
            return redirect()->back()->with('error_message', 'You can not Change Role Name');
        }

        $this->validate($request, [
            'name' => 'required|unique:roles,name,' . $id,
        ]);
        Role::whereId($id)->update([
            'name' => $request->name
        ]);

        return redirect()->back()->with('success_message', 'Role updated successfully');
    }

    public function destroy($id)
    {
        //
    }

    public function assignPermission($id)
    {
        return view('role.assignPermission', [
            'page_title'    => 'Assign Permission',
            'role'          => Role::find($id),
            'permisssions'  => Permission::where('status', 'enable')->get()
        ]);
    }

    public function permissionUpdate(Request $request)
    {
        if (Auth::user()->email == 'admin@gmail.com') {
            return redirect()->back()->with('error_message', 'You can not Change Permission');
        }

        $type = 'RolePermission';
        $role = Role::findOrFail($request->id);
        $oldPermissions = $role->permissions->pluck('name')->sort()->values()->toArray();

        $permissions = $request->permissions;
        $role->syncPermissions($permissions);

        // $newPermissions = $request->input('permissions', []);
        // $role->syncPermissions($newPermissions);

        $role->refresh();
        $updatedPermissions = $role->permissions->pluck('name')->sort()->values()->toArray();

        $addedPermissions = implode(', ', array_diff($updatedPermissions, $oldPermissions));
        $removedPermissions = implode(', ', array_diff($oldPermissions, $updatedPermissions));

        LogHistory::create([
            'log_type'   => $type,
            'log_id'     => $role->id,
            'old_info'   => json_encode(['permissions' => $removedPermissions]),
            'new_info'   => json_encode(['permissions'   => $addedPermissions]),
            'edit_by'    => Auth::user()->id
        ]);

        return redirect()->route('roles.index')->with('success_message', 'Permission Assigned for ' . $request->name);
    }

    public function userRole($email)
    {
        $list = User::where('email', $email)->first();
        return view('role.userRole', [
            'page_title' => 'Assign Role to User ',
            'roles'       => Role::where('name', '!=', 'SoftwareAdmin')->get(),
            'user'       => $list
        ]);
    }


    public function userRoleUpdate(Request $request)
    {
        $user = User::find($request->id);

        if (Auth::user()->email == 'admin@gmail.com') {
            if ($user->hasRole('Admin') || $user->hasRole('Software Admin')) {
                return redirect()->back()->with('error_message', 'You can not change Admin Role');
            } else {
                $user_detils = User_details::where('user_id', $user->id)->first();

                if ($user_detils != null) {
                    $user_detils->last_edit_by = Auth::user()->id;
                    $user_detils->save();
                    $user->syncRoles($request->role);
                } else {
                    return redirect()->back()->with('error_message', 'You can not change');
                }
                Artisan::call('cache:clear');
            }
        }

        $user_detils = User_details::where('user_id', $user->id)->first();
        // dd(auth()->user()->id);
        $user_detils->last_edit_by = auth()->user()->id;
        $user_detils->save();

        $user->syncRoles($request->role);
        Artisan::call('cache:clear');

        return redirect()->back()->with('success_message', 'Role Update Done');
    }
}
