<?php

namespace Modules\User\Services;

use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Modules\MainService\Views\ViewFactory;
use Modules\Order\Services\CartService;
use Modules\User\Enums\AccountStatusEnum;
use Modules\User\Enums\UserActivationEnum;
use Modules\User\Enums\UserRoleEnum;
use Modules\User\Interfaces\UserRepositoryInterface;
use Modules\User\Models\User;
use Modules\User\Enums\UserTargetEnum;
use App\Jobs\SendMailJob;
use Modules\User\Mails\ManagerAssignMail;
use Modules\User\Mails\TargetAchievedMail;
use Modules\User\Mails\NotTargetAchievedMail;

class UserService
{
    private string $veiwDirectoryMail = 'admin.users.mails.';
    public function __construct(
        private UserRepositoryInterface $userRepository,
        private ViewFactory $viewFactory
    ){}

    public function renderView($request = [])
    {
        $request['users'] = $this->get($request);
        return $this->render($request);
    }

    public function render($request = [])
    {
        return $this->viewFactory
            ->render($request['view'])
            ->renderView($request);
    }

    public function get(array $request = [])
    {
        $builder = $this->userRepository->get($request);

        if (@$request['id'])
        {
            $builder->where('id', $request['id']);
        }
        if (@$request['not_id'])
        {
            $builder->where('id','!=', $request['not_id']);
        }
        if (@$request['name'])
        {
            $builder->where('name', 'LIKE', '%'.$request['name'].'%');
        }
        if (@$request['email'])
        {
            $builder->where('email', $request['email']);
        }
        if (@$request['phone'])
        {
            $builder->where('phone', $request['phone']);
        }
        

        if(@$request['employeeFilter'])
        {
            if($request['employeeFilter']->role == UserRoleEnum::Head_Department->value)
            {
                    $builder->where('id', $request['employeeFilter']->id)
                    ->orWhere('manager_id', $request['employeeFilter']->id);
            }
            else
            {
                $builder->where('id',$request['employeeFilter']->id);
            }
        }

        if (@$request['sector_id'])
        {

            $builder->whereHas('sectors',function ($query) use ($request){
                $query->where('sector_id',$request['sector_id']);
            });
        }
        if (isset($request['roles']))
        {
            $builder->whereIn('role', $request['roles']);
        }
        if (isset($request['role']))
        {
            if (is_array($request['role']))
            {
                $builder->whereIn('role', $request['role']);
            }
            else
            {
                $builder->where('role', $request['role']);
            }
        }
        if (@$request['date_from'])
        {
            $builder->whereDate('created_at', '>=', $request['date_from']);
        }

        if (@$request['date_to'])
        {
            $builder->whereDate('created_at', '<=', $request['date_to']);
        }

        if (isset($request['status']))
        {
            if (@$request['status'] == 0)
            {
                $builder->onlyTrashed();
            }
        }

        if (@$request['orderBy'])
        {
            $builder->orderBy($request['orderBy']['key'],$request['orderBy']['value']);
        }
        else
        {
            $builder->orderBy('id','DESC');
        }


        if (@$request['paginate'])
        {
            $users= $builder->paginate(50);
        }
        else
        {
            $users=$builder->cursor();
        }
        return $users;
    }
    public function checkItem($id)
    {
        $user = $this->userRepository->checkItem($id);
        return $user;
    }

    public function getItem($id)
    {
        return $this->userRepository->getItem($id);
    }

    public function getItemTrashed($id)
    {
        $user = $this->userRepository->getItemTrashed($id);
        return $user;
    }

    public function getItemByEmail($email)
    {
        return $this->userRepository->getItemByEmail($email);
    }

    public function employeeDates(int $id)
    {
        $now = Carbon::now();
        $employee = $this->getItem($id);
        if($employee->target_status == UserTargetEnum::QUARTERYEAR->value)
        {
            $year = $now->year;
            $quarter = ceil($now->month / 3);

            $startMonth = ($quarter - 1) * 3 + 1;
            $endMonth = $startMonth + 2;

            $startDate = Carbon::create($year, $startMonth, 1)->toDateString();
            $endDate = Carbon::create($year, $endMonth, 1)->endOfMonth()->toDateString();

            $dates =
            [
                'start_date'=>$startDate,
                'end_date'=>$endDate,
            ];
        }
        elseif($employee->target_status == UserTargetEnum::HALFYEAR->value)
        {
            $year = $now->year;
            $halfYear = date('m') > 6;

            $startDate = $halfYear
                ? Carbon::create($year, 7, 1)->toDateString()
                : Carbon::create($year, 1, 1)->toDateString();

            $endDate = $halfYear
                ? $now->endOfYear()->toDateString()
                : Carbon::create($year, 6, 30)->toDateString();

            $dates = [
                'start_date' => $startDate,
                'end_date'   => $endDate,
            ];
        }
        elseif($employee->target_status == UserTargetEnum::FULLYEAR->value)
        {
            $dates =
            [
                'start_date'=>Carbon::now()->startOfYear()->toDateString(),
                'end_date'=>Carbon::now()->endOfYear()->toDateString(),
            ];
        }
        else
        {
            $dates =
            [
                'start_date'=>Carbon::now()->startOfMonth()->toDateString(),
                'end_date'=>Carbon::now()->endOfMonth()->toDateString(),
            ];
        }
        return $dates;
    }

    public function sectors($user_id)
    {
        return $this->userRepository->sectors($user_id);
    }

    public function create(array $request): User
    {
        $user = $this->userRepository->create($request);
        $this->userRepository->saveData($request,$user->id);
        $this->userRepository->saveSectors($request,$user->id);
        if($user->manager_id)
        {
            $this->ManagerAssign($user,$user->email);
        }
        return $user;
    }
    public function update(array $request,int $id): User
    {
        $user = $this->checkItem($id);
        $old_manager_id = $user->manager_id;
        $user = $this->userRepository->update($request,$user);
        if(@$request['modules'])
        {
            $this->userRepository->saveData($request,$user->id);
        }
        if(@$request['sector_id'])
        {
            $this->userRepository->saveSectors($request,$user->id);
        }
        if($user->manager_id && $user->manager_id != $old_manager_id)
        {
            $this->ManagerAssign($user,$user->email);
        }
        return $user;
    }
    
    public function ManagerAssign($user,$email)
    {
        SendMailJob::dispatch
        (
            $email,
            ManagerAssignMail::class,
            $this->veiwDirectoryMail.'new_manager',
            'You Have Been Added to the Team Structure',
            $user,
        );
    }
    
    
    public function TargetAchieved($user,$target,$achieved)
    {
        SendMailJob::dispatch
        (
            $user->email,
            TargetAchievedMail::class,
            $this->veiwDirectoryMail.'target_achieved',
            'Congratulations! Target Achieved',
            [
                'employee'=>$user,
                'target'=>$target,
                'achieved'=>$achieved
            ],
        );
    }
    
    public function NotTargetAlarm($user,$target,$achieved)
    {
        SendMailJob::dispatch
        (
            $user->email,
            NotTargetAchievedMail::class,
            $this->veiwDirectoryMail.'not_target_achieved',
            'Target Not Achieved — Action Required',
            [
                'employee'=>$user,
                'target'=>$target,
                'achieved'=>$achieved
            ],
        );
    }

    public function disableColumn(array $request)
    {
        return $this->userRepository->disableColumn($request);
    }

    public function updateLock($id)
    {
        $user = $this->checkItem($id);
        $this->update(['lock'=>($user->lock?0:1)],$id);
    }
    public function destroy(int $id): void
    {
        $user = $this->checkItem($id);
        if ($user)
        {
            $this->userRepository->destroy($user);
        }
        else
        {
            $user = $this->getItemTrashed($id);
            $this->userRepository->restore($user);
        }
    }
    public function destroyAll(array $request): void
    {
        if ($request['status'] == 1)
        {
            $this->userRepository->destroyAll($request['ids']);
        }
        else
        {
            $this->userRepository->restoreAll($request['ids']);
        }
    }

    public function getItemColumn(array $request)
    {
        return $this->userRepository->disableColumn($request);
    }

    public function deleteColumn($item)
    {
        $this->userRepository->deleteColumn($item);
    }

    public function addColumn(array $request)
    {
        $this->userRepository->addColumn($request);
    }

    public function toggleColumn(array $request)
    {
        $item = $this->getItemColumn($request);
        if($item)
        {
            $this->deleteColumn($item);
        }
        else
        {
            $this->addColumn($request);
        }
    }

}
