<?php

namespace Modules\User\Controllers\Admin;

/** Ajax Request */

use App\Services\Response\ResponseService;
use Exception;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Country\Services\CountryService;
use Modules\MainService\Enums\ViewEnum;
use Modules\Sector\Services\SectorService;
use Modules\User\Enums\UserRoleEnum;
use Modules\User\Enums\UserTargetEnum;
use Modules\User\Exports\EmployeeExport;
use Modules\User\Requests\Admin\EmployeeRequest;
use Modules\User\Services\UserService;
use Modules\Deal\Services\DealService;
use Modules\User\Services\ModuleService;

class EmployeeController extends Controller
{

    /** Redirect to this path after each operation success*/
    private $redirectSuccessPath= '/admin/employees';
    /** View folder */
    private $viewDirectory= 'admin.employees.';
    private $viewDirectoryTargets= 'admin.employees.targets.';
    private $viewDirectoryManagers= 'admin.employees.managers.';
    //

    public function __construct(
        private UserService $userService,
        private CountryService $countryService,
        private SectorService $sectorService,
        private DealService $dealService,
        private ModuleService $moduleService,
    )
    {}

    /**
     * Display a listing of the users.
     *
     * @param Request $request
     * @return View
     */
    public function index(Request $request) :View
    {
        $data =
            [
                'head'=>__('employees.head'),
                'view' => ViewEnum::INDEX->value,
                'route'=>$this->viewDirectory,
                'request' => $request,
            ];
        return $this->userService->render($data);
    }

    /**
     * return data of the users.
     *
     * @param Request $request
     * @return View
     */
    public function grid(Request $request)
    {
        if(isset($request->orderBy))
        {
            $orderBy = json_decode($request->orderBy, true);
            $request->merge(['orderBy'=>['key'=>$orderBy['key'], 'value'=>$orderBy['value']]]);
        }
        if ($request->export)
        {
            $data = $request->all();
            $data['roles']=UserRoleEnum::employees();
            $users = $this->userService->get($data);
            return Excel::download(new EmployeeExport($users,Auth::user()), 'employees.xlsx');
        }
        $request->merge([
            'paginate' => true,
            'route' => $this->viewDirectory,
            'view' => ViewEnum::LIST->value,
            'request'=>$request,
            'roles'=> UserRoleEnum::employees(),
            'sectors' => $this->sectorService->get(),
        ]);
        return $this->userService->renderView($request->all());
    }

    public function fetchManagers(Request $request)
    {
        $roles = [UserRoleEnum::Head_Department->value];
        // if($request->role == UserRoleEnum::Business_Development_Manager->value)
        // {
        //     array_push($roles,UserRoleEnum::Senior_Business_Development_Manager->value);
        // }
        // if($request->role == UserRoleEnum::Business_Development_Executive->value)
        // {
        //     array_push($roles,UserRoleEnum::Senior_Business_Development_Executive->value);
        // }
        $roles = array_merge($roles, UserRoleEnum::admins());
        $i = $request->role - 1;
        while($i > UserRoleEnum::Head_Department->value)
        {
            array_push($roles,$i);
            $i--;
        }

        $managers = $this->userService->get([
            'roles'=>$roles,
            'not_id'=>$request->employee_id ?? null,
        ]);
        $request->merge([
            'route' => $this->viewDirectoryManagers,
            'view' => ViewEnum::INDEX->value,
            'request'=>$request,
            'managers' => $managers,
        ]);
        return $this->userService->renderView($request->all());
    }


    public function lock($id)
    {
        $employee = $this->userService->getItem($id);
        if (!$employee)
        {
            abort(404);
        }
        $this->userService->updateLock($id);
        session()->flash('message', __('dashboard.saveDone'));
        return redirect()->back();
    }

    /**
     * Show the form for creating a new User.
     *
     * @return View
     */
    public function create() :View
    {
        $data =
        [
            'head'=>__('employees.new'),
            'action' => route('employees.store'),
            'view' => ViewEnum::FORM->value,
            'route'=> $this->viewDirectory,
            'sectors' => $this->sectorService->get(),
            'countries' => $this->countryService->get(),
            'modules' => $this->moduleService->get(['group'=>true,'dashboard'=>'employee']),
            'manager'=>UserRoleEnum::Head_Department->value,
            'managers'=>$this->userService->get(['roles'=>UserRoleEnum::employees()]),
            'roles'=> UserRoleEnum::employees(),
            'user_sectors'=>[],
            'targets' =>UserTargetEnum::values(),
            'user_modules' => [],
        ];
        return $this->userService->render($data);
    }

    /**
     * Store a newly created User in storage.
     * @param EmployeeRequest $request
     * @return JsonResponse
     */
    public function store(EmployeeRequest $request) :JsonResponse
    {
        $data = $request->validated();
        if(!isset($data['modules']))
        {
            $data['modules'] = [
                17,18,19,20,21,22,23,24,29,30,31,32
            ];
        }
        $this->userService->create($data);

        session()->flash('message', __('dashboard.saveDone'));
        $response = [
            'status'=>200,
            'message'=>__('web.success'),
            'data'=> route('employees.index'),
        ];
        return ResponseService::response($response);
    }

    /**
     * Show the form for editing the specified User.
     *
     * @param  int $id
     * @return View
     */
    public function edit(int $id) :View
    {
        $employee = $this->userService->getItem($id);
        if (!$employee)
        {
            abort(404);
        }
        $data =
        [
            'head'=>__('users.edit'),
            'action' => route('employees.update', $employee->id),
            'view' => ViewEnum::FORM->value,
            'route'=> $this->viewDirectory,
            'countries' => $this->countryService->get(),
            'sectors' => $this->sectorService->get(),
            'targets' =>UserTargetEnum::values(),
            'roles'=> UserRoleEnum::employees(),
            'user_sectors'=>$this->userService->sectors($id)->pluck('sector_id')->toArray(),
            'user_modules' => $this->moduleService->get(['user_id'=>$id])->pluck('id')->toArray(),
            'managers'=>$this->userService->get(['roles'=>UserRoleEnum::employees(),'not_id'=>$id]),
            'manager'=>UserRoleEnum::Head_Department->value,
            'modules' => $this->moduleService->get(['group'=>true,'dashboard'=>'employee']),
            'employee'=>$employee
        ];
        return $this->userService->render($data);
    }

    public function show(int $id) :View
    {
        $employee = $this->userService->getItem($id);
        if (!$employee)
        {
            abort(404);
        }
        $data =
        [
            'head'=>__('users.show'),
            'view' => ViewEnum::SHOW->value,
            'route'=> $this->viewDirectory,
            'manager'=>UserRoleEnum::Head_Department->value,
            'user_sectors'=>$this->userService->sectors($id)->pluck('sector_id')->toArray(),
            'user_modules' => $this->moduleService->get(['user_id'=>$id])->pluck('id')->toArray(),
            'modules' => $this->moduleService->get(['group'=>true,'dashboard'=>'employee']),
            'sectors' => $this->sectorService->get(),
            'employee'=>$employee
        ];
        return $this->userService->render($data);
    }

    public function target(int $id) :View
    {
        $employee = $this->userService->getItem($id);
        if (!$employee)
        {
            abort(404);
        }
        $dates = $this->userService->employeeDates($id);
        $deals = $this->dealService->get([
            'done_dates'=>[
                'start_date'=>$dates['start_date'],
                'end_date'=>$dates['end_date']
            ],
            'employeeId'=>$id
        ]);
        $data =
        [
            'head'=>__('employees.all_target'),
            'view' => ViewEnum::INDEX->value,
            'route'=> $this->viewDirectoryTargets,
            'deals' => $deals,
            'employee'=>$employee
        ];
        return $this->userService->render($data);
    }

    /**
     * Update the specified User in storage.
     * @param EmployeeRequest $request
     * @param int $id
     * @return JsonResponse
     */
    public function update(EmployeeRequest $request, int $id) :JsonResponse
    {
        $user = $this->userService->checkItem($id);
        if (!$user)
        {
            abort(404);
        }
        $data = $request->validated();
        if(!isset($data['modules']))
        {
            $data['modules'] = [
                17,18,19,20,21,22,23,24,29,30,31,32
            ];
        }
        $this->userService->update($data, $id);
        session()->flash('message', __('dashboard.saveDone'));
        $response = [
            'status'=>200,
            'message'=>__('web.success'),
            'data'=> route('employees.index'),
        ];
        return ResponseService::response($response);
    }

    /**
     * Remove the specified User from storage.
     * @param int $id
     * @return JsonResponse
     * @throws Exception
     */
    public function destroy(int $id) :JsonResponse
    {
        $this->userService->destroy($id);
        session()->flash('message', __('dashboard.saveDone'));
        $response = [
            'status'=>200,
            'message'=>__('web.success'),
            'data'=> route('employees.index'),
        ];
        return ResponseService::response($response);
    }

    /**
     * Remove several users by IDs.
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function destroyAll(Request $request) :JsonResponse
    {
        $this->userService->destroyAll([
            'ids' => $request->ids,
            'status' => 1
        ]);
        $response = [
            'status'=>200,
            'message'=>__('web.success'),
            'data'=> route('employees.index'),
        ];
        return ResponseService::response($response);
    }

    /**
     * Restore the specified User from storage.
     *
     * @param int $id
     * @return JsonResponse
     */
    public function restore(int $id) :JsonResponse
    {
        $this->userService->destroy($id);
        $response = [
            'status'=>200,
            'message'=>__('web.success'),
            'data'=> route('employees.index'),
        ];
        return ResponseService::response($response);
    }

    /**
     * Restore several users by IDs.
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function restoreAll(Request $request) :JsonResponse
    {
        $this->userService->destroyAll([
            'ids' => $request->ids,
            'status' => 0
        ]);
        $response = [
            'status'=>200,
            'message'=>__('web.success'),
            'data'=> route('employees.index'),
        ];
        return ResponseService::response($response);
    }
}
