<?php

namespace App\Http\Controllers\AccessManagement\GroupManagement;

use Activity;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use App\Models\AccessManagement\GroupManagement\ModelHasRole;
use App\Models\AccessManagement\GroupManagement\Role;
use App\Models\User;
use App\Traits\Logs\HasCustomLogs;
use Illuminate\Support\Facades\Auth;
use Suiterus\Dms\Enums\Log\GroupLogType;

class ModelHasRoleController extends Controller
{

    use HasCustomLogs;

    public function create(Request $request)
    {

        DB::beginTransaction();
        try {

            $members = [];
            $index = 0;
            $deletedMember = [];
            $oldMembers = [];

            foreach ($request->group_members as $member) {
                if ($index == 0) {
                    $oldMembers = ModelHasRole::where('role_id', $member['role_id'])->without(['user'])->with('role')->get()->pluck('model_id')->toArray();

                    $deletedMembers = $this->getRemovedMembers($oldMembers, collect($request->group_members)->pluck('user_id')->toArray());

                    foreach ($deletedMembers as $deletedMember) {
                        $deletedMemberModel = User::without([
                            'roles',
                            'permissions',
                            'storage',
                            'employeeMetaInfo',
                            'supervisor',
                            'exitInterview',
                            'userProfilePicture',
                            'profileBasicInfo'
                        ])->where('id', $deletedMember)->first();

                        $role = Role::where('id', $member['role_id'])->without([
                            'roleLeader',
                            'sectionAccess',
                            'member'
                        ])->with(['roleHasSystem' => function($query) {
                            $query->without(['role']);
                        }])->first();

                        $deletedMemberModel->role = $role;

                        $this->logCustomMessage(
                            'remove_group_member',
                            $deletedMemberModel,
                            Auth::user()->name . ' removed ' . $deletedMemberModel->name . ' from group ' . $role->name,
                            $deletedMemberModel,
                            GroupLogType::REMOVE_GROUP_MEMBER,
                            new Activity()
                        );
                    }

                    ModelHasRole::where('role_id', $member['role_id'])->delete();
                }
                array_push($members, [
                    'role_id' => $member['role_id'],
                    'model_type' => "App\Models\User",
                    'model_id' => $member['user_id']
                ]);

                if (!in_array($member['user_id'], $oldMembers)) {
                    $newMemberModel = User::without([
                        'roles',
                        'permissions',
                        'storage',
                        'employeeMetaInfo',
                        'supervisor',
                        'exitInterview',
                        'userProfilePicture',
                        'profileBasicInfo'
                    ])->where('id', $member['user_id'])->first();

                    $role = Role::where('id', $member['role_id'])->without([
                        'roleLeader',
                        'sectionAccess',
                        'member'
                    ])->with(['roleHasSystem' => function($query) {
                        $query->without(['role']);
                    }])->first();

                    $newMemberModel->role = $role; 

                    $this->logCustomMessage(
                        'add_group_member',
                        $newMemberModel,
                        Auth::user()->name . ' added ' . $newMemberModel->name . ' to the group ' . $role->name,
                        $newMemberModel,
                        GroupLogType::ADD_GROUP_MEMBER,
                        new Activity()
                    );
                }
                $index++;
            }

            ModelHasRole::insert($members);

            DB::commit();
            return response()->json([
                'text'  =>  'Group members has been added.'
            ]);
        } catch (Exception $e) {
            DB::rollback();
            return $e;
            return response()->json([
                'errors'    =>  ['There is a problem in adding group members.'],
                'msg'       =>  $e->getMessage()
            ], 500);
        }
    }

    public function getRemovedMembers(array $oldMembers, array $members)
    {
        return array_filter($oldMembers, function ($member) use ($members) {
            return !in_array($member, $members);
        });
    }

    public function delete(Request $request)
    {
        $valid = Validator::make($request->all(), [
            'role_id' => 'required|exists:' . env('DB_CONNECTION') . '.roles,id',
            'user_id' => 'required|exists:' . env('DB_CONNECTION') . '.users,id'
        ]);
        if ($valid->fails()) {
            return response()->json([
                'errors'    =>  $valid->errors()
            ], 400);
        }
        DB::beginTransaction();
        try {

            ModelHasRole::where([
                ['role_id', $request->role_id],
                ['model_id', $request->user_id]
            ])->delete();

            DB::commit();
            return response()->json([
                'text'  =>  'Group member has been removed.'
            ]);
        } catch (Exception $e) {
            DB::rollback();
            return response()->json([
                'errors'    =>  ['There is a problem in removing group member.'],
                'msg'       =>  $e->getMessage()
            ], 500);
        }
    }

    public function fetchByRoleID(Request $request)
    {
        return ModelHasRole::where('role_id', $request->role_id)->get();
    }
}
