<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Http\Requests\API\Role\CreateOrUpdateRequest;
use App\Http\Resources\API\MenuResource;
use App\Http\Resources\API\RoleResource;
use App\Http\Resources\API\RoleSimpleResource;
use App\Models\Menu;
use App\Models\Role;
use App\Models\User;
use Illuminate\Http\Request;

class RoleController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $roles = Role::query()->filter($request->all())->get();
        $roles->transform(function (Role $role) {
            $role->display_id = $role->id;
            return $role;
        });
        return RoleResource::collection($roles);
    }

    /**
     * Display a listing of the resource.
     */
    public function publicSearch(Request $request)
    {
        $roles = Role::query()->filter($request->all())->get();

        return RoleSimpleResource::collection($roles);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(CreateOrUpdateRequest $request)
    {
        Role::create([
            ...$request->only(['name', 'description']),
            'guard_name' => 'api',
        ]);

        return $this->created();
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        //
        $role=Role::query()->findOrFail($id);

        return new RoleResource($role);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(CreateOrUpdateRequest $request, string $id)
    {
        $role = Role::query()->findOrFail($id);

        $role->update($request->only([
            'name', 'description'
        ]));

        return $this->noContent();
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        Role::destroy($id);

        return $this->noContent();
    }

    public function permissions(string $id)
    {
        $role = Role::query()->findOrFail($id);

        return $this->success([
            'data' => $role->permissions?->pluck('name'),
        ]);
    }

    public function assignPermissions(string $id, Request $request)
    {
        $role = Role::query()->findOrFail($id);

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

        return $this->noContent();
    }

    public function menus(string $id)
    {
        $role = Role::query()->findOrFail($id);

        $menus = Menu::query()->where("group", \request("group", "web"))
            ->get();

        $rolePermission=$role->permissions->pluck('name')->toArray();

        $flattenedPaths = [];
        foreach ($menus as $index=> $menu) {
            if(in_array($menu->permission,$rolePermission)){
                $individualPaths = explode(',', $menu->path);
                $flattenedPaths = array_merge($flattenedPaths, $individualPaths);
            }
        }

        $roleHasMenu=Menu::query()->whereIn('id',$flattenedPaths)->get();

        return MenuResource::collection($roleHasMenu);

    }


    public function assignMenusPermissions(string $id, Request $request)
    {
        $role = Role::query()->findOrFail($id);

        //获取菜单所有权限
        $menusPermission=Menu::query()->where("group", \request("group", "web"))->pluck('permission')->toArray();

        //通过获取用户拥有的菜单权限
        $roleMenusPermissions=$role->permissions->filter(function ($permission) use ($menusPermission) {
                return in_array($permission->name, $menusPermission);
            })->pluck('name')->toArray();


        $permissions=$request->input('permissions');

        // 找出需要新增的权限
        $extraPermissions = array_diff($permissions, $roleMenusPermissions);

        if(!empty($extraPermissions)&&count($extraPermissions)!=0){
            foreach ($extraPermissions as $extraPermission){
                $role->givePermissionTo($extraPermission);
            }
        }

        // 找出需要剔除的权限
        $missingPermissions = array_diff($roleMenusPermissions, $permissions);
        if(!empty($missingPermissions)&&count($missingPermissions)!=0){
            foreach ($missingPermissions as $missingPermission){
                $role->revokePermissionTo($missingPermission);
            }
        }

        return $this->noContent();
    }
}