<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Validator;
use App\Responses;
use App\Helper;
use App\Models\Users;
use App\Models\Clients;
use App\Models\Vehicles;
use App\Models\Banks;
use App\Models\UsersMenuPermissions;
use Spatie\Permission\PermissionRegistrar;
use Illuminate\Support\Facades\Auth;
use App\Models\UserLogs;

class RolesController extends Controller
{
    public function view(Request $req)
    {
        $permissions = \Spatie\Permission\Models\Permission::all();

        $data = [
            "roles" => Users::listRoles($req->auth->role),
            "pernus" => UsersMenuPermissions::listPermissionsMenus([
                "is_active" => UsersMenuPermissions::IS_ACTIVE,
            ]),
            "vehicles" => Vehicles::getVehicles(),
            "banks" => Banks::listBanks(["is_active" => Banks::IS_ACTIVE]),
            "permission" => $permissions->groupBy(function ($perm) {
                return explode(".", $perm->name)[0];
            }),
        ];

		$log = [
			"module" => "Role",
			"action" => "View",
			"desc" => "Open Role menu",
		];
		UserLogs::insert(Auth::user()->id, $log);

        return view("menu_v1.roles", $data);
    }

    public function api_list(Request $req)
    {
        try {
            $list = DB::table("roles")->get();
            foreach ($list as $key => $row) {
                $list[$key]->DT_RowIndex = $key + 1;
                $list[$key]->count_trx = 0;
                $list[$key]->action = "-";
            }

            $apiResp = Responses::success("success list users");
            $apiResp["data"] = $list;
            $apiResp["count"] = count($list);
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_show(Request $req, $uid)
    {
        try {
            $input = ["uid" => $uid];
            $rulesInput = ["uid" => "required|integer|not_in:0"];

            $isValidInput = Validator::make($input, $rulesInput);
            if (!$isValidInput->passes()) {
                $apiResp = Responses::bad_input($isValidInput->messages()->first());
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $role = DB::table("roles")
                ->where("roles.id", $uid)
                ->get();
            if (count($role) < 1) {
                $apiResp = Responses::not_found("role not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $permissions = DB::table("role_has_permissions")
                ->where("role_id", $uid)
                ->pluck("permission_id")
                ->toArray();
            $role[0]->permissions = $permissions;

            $apiResp = Responses::success("success get detail role");
            $apiResp["data"] = $role[0];
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_add(Request $req)
    {
        try {
            DB::beginTransaction();

            $role_id = DB::table("roles")->insertGetId([
                "name" => $req->name,
                "guard_name" => "web",
                "created_at" => now(),
                "updated_at" => now(),
            ]);

            $role_has_permissions = [];
            foreach ($req->permissions as $_permission) {
                $role_has_permissions[] = [
                    "permission_id" => $_permission,
                    "role_id" => $role_id,
                ];
            }
            DB::table("role_has_permissions")->insert($role_has_permissions);

            DB::commit();

            app()[PermissionRegistrar::class]->forgetCachedPermissions();

            $apiResp = Responses::created("success add new role");

			$log = [
				"module" => "Role",
				"action" => "Create",
				"desc" => "Add new role : ".$req->name,
			];
			UserLogs::insert(Auth::user()->id, $log);

            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            DB::rollBack();
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_edit(Request $req)
    {
        try {
            DB::beginTransaction();

            DB::table("roles")
                ->where("id", $req->uid)
                ->update([
                    "name" => $req->name,
                    "updated_at" => now(),
                ]);

            DB::table("role_has_permissions")
                ->where("role_id", $req->uid)
                ->delete();

            $role_has_permissions = [];
            foreach ($req->permissions as $pid) {
                $role_has_permissions[] = [
                    "role_id" => $req->uid,
                    "permission_id" => $pid,
                ];
            }
            DB::table("role_has_permissions")->insert($role_has_permissions);

            DB::commit();

            app()[PermissionRegistrar::class]->forgetCachedPermissions();

            $apiResp = Responses::created("success update role");

			$log = [
				"module" => "Role",
				"action" => "Update",
				"desc" => "Update role : ".$req->name,
			];
			UserLogs::insert(Auth::user()->id, $log);
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            DB::rollBack();
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_del(Request $req)
    {
        try {
            $input = ["uid" => $req->uid];
            $rulesInput = ["uid" => "required|integer|not_in:0"];

            $isValidInput = Validator::make($input, $rulesInput);
            if (!$isValidInput->passes()) {
                $apiResp = Responses::bad_input($isValidInput->messages()->first());
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $role = DB::table("roles")
                ->where("id", $req->uid)
                ->get();
            if (count($role) < 1) {
                $apiResp = Responses::not_found("role not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            DB::beginTransaction();

            DB::table("role_has_permissions")
                ->where("role_id", $req->uid)
                ->delete();
            DB::table("roles")
                ->where("id", $req->uid)
                ->delete();

            DB::commit();

            app()[PermissionRegistrar::class]->forgetCachedPermissions();

            $apiResp = Responses::created("success delete role");

			$log = [
				"module" => "Role",
				"action" => "Delete",
				"desc" => "Delete role : ".$role[0]->name,
			];
			UserLogs::insert(Auth::user()->id, $log);
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            DB::rollBack();
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }

    public function api_search(Request $req)
    {
        try {
            DB::beginTransaction();

            $roles = Users::arrRoles();
            $input = [
                "name" => $req->name,
                "roles" => $req->roles,
            ];
            $rulesInput = [
                "name" => "required|string|max:125",
                "roles" => "nullable|integer|not_in:0",
            ];

            $isValidInput = Validator::make($input, $rulesInput);
            if (!$isValidInput->passes()) {
                $apiResp = Responses::bad_input($isValidInput->messages()->first());
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            if ($req->roles && !in_array($req->roles, $roles)) {
                $apiResp = Responses::bad_request("role not valid");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            $users = $req->roles ? Users::likeName($req->name, $req->roles) : Users::likeName($req->name);

            if (count($users) < 1) {
                $apiResp = Responses::not_found("user not found");
                return new Response($apiResp, $apiResp["meta"]["code"]);
            }

            foreach ($users as $k => $v) {
                unset($users[$k]->password);
            }

            DB::commit();

            $apiResp = Responses::success("success search user by name");
            $apiResp["data"] = $users;
            return new Response($apiResp, $apiResp["meta"]["code"]);
        } catch (\Exception $e) {
            DB::rollBack();
            $apiResp = Responses::error($e->getMessage());
            return new Response($apiResp, $apiResp["meta"]["code"]);
        }
    }
}
