<?php

namespace App\Http\Controllers\API\v1;

use App\Http\Controllers\Controller;
use App\Models\Permission;
use App\Models\RolePermission;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Throwable;

class PermissionController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     */
    public function index(Request $request)
    {

        $perPage = $request->input('per_page',PHP_INT_MAX);

        $keyword = $request->input('keyword', '');

        $data = Permission::where(function ($query) use ($keyword) {
            $query->where('code', 'like', '%'.$keyword.'%')
            ->orWhere('name', 'like', '%'.$keyword.'%')
            ->orWhere('description', 'like', '%'.$keyword.'%');
        })->orderBy('name')->paginate($perPage);

        return response()->json($data);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        /** Validate the incoming request data */
        $validator = Validator::make($request->only(['code', 'name']), [
            'code' => [
                'required',
                'max:20',
                Rule::unique('permissions')->whereNull('deleted_at'),
            ],
            'name' => [
                'required',
                Rule::unique('permissions')->whereNull('deleted_at')
            ],
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();
            $first = $errors->getMessages();
            return response()->json([
                'status'  => false,
                'message' => (reset($first))[0],
                'errors'  => $errors
            ], Response::HTTP_UNROCESSABLE_ENTITY);
        }

        DB::connection()->beginTransaction();

        try {
            $permission = Permission::create([
                'code'          => $request->code,
                'name'          => strtoupper($request->name),
                'description'   => $request->description,
                'active'        => $request->active,
                'created_by_id' => $request->created_by_id,
                'created_at'    => $this->current_datetime,
                'updated_at'    => $this->current_datetime
            ]);

            DB::connection()->commit();

            return response()->json([
                'status'  => true,
                'message' => 'Saved successfully!',
                'data'    => $permission
            ], 201);

        } catch (Throwable $e) {

            DB::connection()->rollback();
            return response()->json([
                'status'  => false,
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ]);
        }

    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        return response()->json([
            'status'  => true,
            'message' => 'Permission info',
            'data'    => Permission::find($id)
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        /** Validate the incoming request data */
        $validator = Validator::make(array_merge($request->only(['code', 'name']), ['id' => $id]), [
            'id'   => 'required|exists:permissions,id',
            'code' => [
                'required',
                'max:20',
                Rule::unique('permissions')->ignore($id)->whereNull('deleted_at')
            ],
            'name' => [
                'required',
                Rule::unique('permissions')->ignore($id)->whereNull('deleted_at')
            ],
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();
            $first = $errors->getMessages();
            return response()->json([
                'status'  => false,
                'message' => (reset($first))[0],
                'errors'  => $errors
            ], Response::HTTP_UNROCESSABLE_ENTITY);
        }

        DB::connection()->beginTransaction();

        try {

            // update
            $permission = Permission::find($id);

            $permission->code       = $request->code;
            $permission->name       = strtoupper($request->name);

            if($request->description)
                $permission->description       = $request->description;

            if($request->is_active)
                $permission->is_active  = $request->is_active;


            $permission->updated_at = $this->current_datetime;
            $permission->save();

            DB::connection()->commit();

            return response()->json([
                'status'  => true,
                'message' => 'Updated successfully!',
                'data'    => $permission
            ], 201);

        } catch (Throwable $e) {

            DB::connection()->rollback();
            return response()->json([
                'status'  => false,
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ]);
        }
    }

    public function SaveRolePermissions(Request $request) {

        $validator = Validator::make($request->only(['id']), [
            'id' => "required|exists:roles,id"
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();
            $first = $errors->getMessages();
            return response()->json([
                'status'  => false,
                'message' => (reset($first))[0],
                'errors'  => $errors
            ], Response::HTTP_UNPROCESSABLE_ENTITY);
        }

        DB::connection()->beginTransaction();

        try {

            //check if has role permissions
            $rolePermission = RolePermission::where([
                'role_id' => $request->id,
                'company_id' => $request->company_id,
            ]);
            if($request->dealership_id) {
                $rolePermission->where(fn($query) =>
                    $query->where('dealership_id', $request->dealership_id)
                    ->orWhere('dealership_id', 0)
                );
            }
            // if($request->department_id) {
            //     $rolePermission->where(fn ($query) =>
            //         $query->where('department_id', $request->department_id)
            //         ->orWhere('department_id', 0)
            //     );
            // }
            if($request->system_id) {
                $rolePermission->whereHas('module', fn ($query) =>
                    $query->where('system_id', $request->system_id)
                );
            }
            $rolePermission->delete();

            $role_permission = [];
                foreach($request->modules as $module) {
                    foreach($module['permissions'] as $permission) {
                        $role_permission[] = array(
                            'role_id'=>$request->id,
                            'company_id'=>$request->company_id,
                            'dealership_id'=>$request->dealership_id ?? 0,
                            'department_id'=>$request->department_id ?? 0,
                            'module_id'=>$module['id'],
                            'permission_id'=>$permission['id'],
                            'created_at'=>$this->current_datetime,
                            'updated_at'=>$this->current_datetime,
                        );
                    }
                }

            RolePermission::insert($role_permission);

            DB::connection()->commit();

            return response()->json([
                'message' => 'Saved successfully!',
                'data'    => $request->id
            ], 201);


        } catch (Throwable $e) {

            DB::connection()->rollback();
            return response()->json([
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ], Response::HTTP_UNPROCESSABLE_ENTITY);
        }

    }

    function getAllRolePermissions(Request $request) {

        try {
            $rolePermission = RolePermission::all();
            return response()->json([
                'status'  => true,
                'data'    => $rolePermission
            ]);
        } catch (Throwable $e) {
            return response()->json([
                'status'  => false,
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ]);
        }
    }

    function getRolePermissions(string $role_id) {

        try {
            $rolePermission = RolePermission::where('role_id', $role_id)->get();
            return response()->json([
                'data'    => $rolePermission
            ],200);

        } catch (Throwable $e) {
            return response()->json([
                'status'  => false,
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ]);
        }
    }

    function CompanyPermissions(Request $request) {
        try {
            DB::enableQueryLog();
            $rolePermission = collect();
            $roles = \App\Models\Role::with(['company_access'])->whereIn('id', $request->roles)->get();
            // dd($roles->toArray());
            foreach($roles->toArray() as $role) {
                $role_id = $role['id'];
                foreach($role['company_access'] as $access) {
                    $company_id = $access['company_id'];
                    $dealership_id = $access['dealership_id'];
                    // DB::enableQueryLog();
                    $permission = RolePermission::with(['module','permission'])
                    ->where('role_id', $role_id)
                    ->where('company_id', $company_id)
                    ->where(fn($q) =>$q->where('dealership_id', $dealership_id)->orWhere('dealership_id','0'))
                    ->get();
                        // dd(DB::getQueryLog());
                    if($permission) $rolePermission = $rolePermission->merge($permission);
                }            }
            return response()->json([
                'data'    => $rolePermission
            ]);

        } catch (Throwable $e) {
            return response()->json([
                'status'  => false,
                'message' => 'Unable to process request. Please try again.',
                'data'    => $e->getMessage()
            ]);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(int $id)
    {
        $data = Permission::find($id);

        if(!$data) {
            return response()->json(['message' => 'Record not found!'],204);
        }

        $data->delete();

        DB::connection()->commit();

        return response()->json([
            'message' => 'Record Successfully deleted!',
        ], 200);
    }

}
