<?php
/*=========================================================================================
    App Name  : eCase File PTUN Jakarta
    File Name : RoleController
    --------------------------------------------------------------------------------------
    Author    : Fuad Auliya Rohman
    Email     : fuad.dev16@gmail.com
==========================================================================================*/

namespace Modules\Role\Http\Controllers;

use Exception;
use App\Models\User;
use Illuminate\Http\Request;
use Modules\Role\Entities\Role;
use Illuminate\Routing\Controller;
use Spatie\Permission\Models\Permission;
use Illuminate\Contracts\Support\Renderable;
use Modules\Role\Services\RoleServiceInterface;

class RoleController extends Controller
{
    protected $view = 'role::';

    protected $table = 'RoleTable';

    private $dataRole = [
        '1' => 'superadmin',
        '2'  => 'ketua_wakil',
        '3'  => 'ketua_wakil',
        '4'  => 'ketua_wakil',
        '5'  => 'ketua_wakil',
        '6'  => 'panitera',
        '7'  => 'panmud_perkara',
        '8'  => 'panmud_hukum',
        '9'  => 'panitera',
        '10' => 'panmud_perkara',
        '11' => 'panmud_hukum',
        '12' => 'user',
    ];

    protected $roleService;

    public function __construct(RoleServiceInterface $roleService)
    {
        $this->roleService = $roleService;
    }

    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index()
    {
        $Roles = $this->roleService->all();

        $bc = breadcrumb(array(['link' => '#', 'page' => __('lang.groups')]));
        return view($this->view . 'index', [
            'Roles' => $Roles,
            'bc' => $bc,
            'table' => $this->table,
        ]);
    }

    /**
     * Show the form for creating a new resource.
     * @return Renderable
     */
    public function create()
    {
        return response()->json([
            'html' => view($this->view . 'modal', [
                'table' => $this->table,
                'method' => 'createRole',
                'updateMode' => false,
            ])->render(),
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function edit(string $hash_id)
    {
        $role = $this->roleService->findOr(decryptString($hash_id));

        return response()->json([
            'html' => view($this->view . 'modal', [
                'table' => $this->table,
                'method' => 'updateRole',
                'updateMode' => true,
                'data' => $role,
            ])->render(),
        ]);
    }

    public function permission(string $hash_id)
    {
        $id = decryptString($hash_id);

        $rolePermissions = Permission::join("role_has_permissions", "role_has_permissions.permission_id", "=", "permissions.id")
                                    ->where("role_has_permissions.role_id", $id)->get();

        $permissions = [];
        foreach ($rolePermissions as $value) {
            $permissions[] = $value->name;
        }

        return response()->json([
            'html' => view($this->view . 'permission', [
                'table' => $this->table,
                'method' => 'updatePermission',
                'updateMode' => true,
                'permissions' => $permissions,
                'dataRole' => $this->dataRole[$id],
                'role_id' => $id,
            ])->render(),
        ]);
    }

    public function setPermission(Request $request, string $hash_id)
    {
        $id = decryptString($hash_id);

        $role = Role::firstOrCreate(['id' => $id]);

        if ($request->has('lihat_' . $request->role )) {
            $permission = Permission::firstOrCreate(['name' => 'lihat_' . $request->role ,]);
            if (!$role->hasPermissionTo('lihat_' . $request->role )) {
                $role->givePermissionTo($permission);
            }
        } else {
            $role->revokePermissionTo('lihat_' . $request->role );
        }

        if ($request->has('tambah_' . $request->role)) {
            $permission = Permission::firstOrCreate(['name' => 'tambah_' . $request->role]);
            if (!$role->hasPermissionTo('tambah_' . $request->role )) {
                $role->givePermissionTo($permission);
            }
        } else {
            $role->revokePermissionTo('tambah_' . $request->role );
        }

        if ($request->has('edit_' . $request->role)) {
            $permission = Permission::firstOrCreate(['name' => 'edit_' . $request->role]);
            if (!$role->hasPermissionTo('edit_' . $request->role)) {
                $role->givePermissionTo($permission);
            }
        } else {
            $role->revokePermissionTo('edit_' . $request->role);
        }

        if ($request->has('hapus_' . $request->role)) {
            $permission = Permission::firstOrCreate(['name' => 'hapus_' . $request->role]);
            if (!$role->hasPermissionTo('hapus_' . $request->role)) {
                $role->givePermissionTo($permission);
            }
        } else {
            $role->revokePermissionTo('hapus_' . $request->role);
        }

        if ($request->has('notification_read')) {
            $permission = Permission::firstOrCreate(['name' => 'notification_read',]);
            if (!$role->hasPermissionTo('notification_read')) {
                $role->givePermissionTo($permission);
            }
        } else {
            $role->revokePermissionTo('notification_read');
        }

        return redirect()->route('roles.index')->with("success", __('messages.update_success', ['action' => __('lang.permissions'),]));
    }

    /**
     * Remove the specified resource from storage.
     * @param int $id
     * @return Renderable
     */
    public function destroy(string $hash_id)
    {
        try {
            // DECODE ID
            $id = decryptString($hash_id);

            // GET ROLE DATA
            $role = $this->roleService->findOr($id);

            $userCount = $this->roleService->countUserRole($id);

            if ($userCount > 0) {
                writeAppLog(__('messages.delete_failed_have_foreign', ['name' => $role->name, 'table' => __('lang.users'),]));

                return response()->json([
                    'status' => false,
                    'message' => __('messages.delete_failed_have_foreign', ['name' => $role->name, 'table' => __('lang.users'),]),
                ]);
            }

            if ($role->delete()) {
                return response()->json([
                    'status' => true,
                    'message' => __('messages.delete_success', ['name' => $role->name,]),
                ]);
            }
        } catch (\Exception $e) {
            writeAppLog($e->getMessage(), 'alert');

            return response()->json([
                'status' => false,
                'message' => __('messages.delete_failed', ['action' => __('lang.groups'),]),
            ]);
        }
    }

    public function bulkDelete(Request $request)
    {
        if (!empty($request->val)) {
            $data = [];
            foreach ($request->val as $hash_id) {
                // DECODE ID
                $id = decryptString($hash_id);

                // GET ROLE DATA
                $role = Role::find($id);

                $count = Role::withCount(['user' => fn ($query) => $query->where('role_id', $id)])
                    ->get()->find($id);

                if ($count->user_count > 0) {
                    $data[] = [
                        'status' => false,
                        'message' => __('messages.delete_failed_have_foreign', ['name' => $role->name, 'table' => __('lang.users'),]),
                    ];

                    writeAppLog(__('messages.delete_failed_have_foreign', ['name' => $role->name, 'table' => __('lang.users'),]));
                } else {
                    if (!$role->delete()) {
                        $data[] = [
                            'status' => false,
                            'message' => __('messages.delete_failed', ['action' => __('lang.groups'),]),
                        ];
                    } else {
                        $data[] = [
                            'status' => true,
                            'message' => __('messages.delete_success', ['name' => $role->name,]),
                        ];
                    }
                }
            }
            return response()->json($data);
        }
    }

    public function datatable(Request $request)
    {
        if ($request->ajax()) {
            return $this->roleService->datatable();
        }
    }
}
