<?php

namespace Modules\User\Services;

use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Modules\Order\Services\CartService;
use Modules\Unit\Repositories\UnitRepository;
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;

class UserService
{
    public function __construct(
        private UserRepositoryInterface $userRepository,
        private UnitRepository $unitRepository,
    ){}

    public function get(array $request)
    {
        // GET MOST ACTIVE PROVIDERS
        $mostActiveUserIdThisMonth= $this->unitRepository->mostActiveUserIdThisMonth();
        
        $builder = $this->userRepository->get($request);

        if (@$request['name'])
        {
            $builder->where('name', 'LIKE', '%'.$request['name'].'%');
        }
        if (@$request['email'])
        {
            $builder->where('email', $request['email']);
        }
        if (@$request['store_id'])
        {
            $builder->where('store_id', $request['store_id']);
        }
        if (@$request['phone'])
        {
            $builder->where('phone', $request['phone']);
        }
        if (isset($request['role']))
        {
            if ((is_array($request['role']) && in_array(UserRoleEnum::PROVIDER->value, $request['role']) || UserRoleEnum::PROVIDER->value == $request['role']))
            {
                $builder->with('providerProfile');
                $builder->withCount(['units as total_units', 'soldUnits as total_sold']);
                $builder->addSelect(DB::raw("(
                    CASE 
                        WHEN `users`.`id` = '{$mostActiveUserIdThisMonth}'
                        THEN 1 ELSE 0 
                    END
                ) AS is_most_active"));

            }

            if (is_array($request['role']))
            {
                $builder->whereIn('role', $request['role']);
            }
            else
            {
                $builder->where('role', $request['role']);
            }
        }
        if (isset($request['roles']))
        {
            $builder->whereIn('role', $request['roles']);
        }
        if (isset($request['codes']))
        {
            $builder->whereIn('code', $request['codes']);
        }
        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 (isset($request['user_status']) && $request['user_status'])
        {
            $builder->whereIn('id', function ($query) use ($request) {
                $query->select('user_id')
                    ->from('user_provider_profiles')
                    ->where('status', $request['user_status']);
            });
        }

        if (isset($request['badge']) && $request['badge'])
        {
            switch ($request['badge']) {
                case 'top':
                case 'reliable':
                    $builder->whereIn('id', function ($query) use ($request) {
                        $query->select('user_id')->from('user_provider_profiles');
                        switch ($request['badge']) {
                            case 'top':
                                $query->where('is_top', 1);
                                break;
                            case 'reliable':
                                $query->where('is_reliable', 1);
                                break;
                        }
                    });
                    break;
                case 'most_active_user_units_month':
                    $builder->where('id', $mostActiveUserIdThisMonth);
                    break;
            }
        }

        if (@$request['orderBy'])
        {
            $builder->orderBy($request['orderBy']['key'],$request['orderBy']['value']);
        }
        else
        {
            $builder->orderBy('id','DESC');
        }
        DB::enableQueryLog();
        if (@$request['paginate']) {
            $users= $builder->paginate(50);
        }else{
            $users=$builder->get();
        }
        // dd(DB::getQueryLog());
        return $users;
    }
    public function checkItem($id)
    {
        $user = $this->userRepository->checkItem($id);
        return $user;
    }

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

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

    public function getItemByCode($code)
    {
        $user= $this->userRepository->getItemByCode($code);
        if ($user && $user->role == UserRoleEnum::PROVIDER->value)
        {
            // Load provider profile and stats
            $user->load('providerProfile');
            $user->loadCount(['units as total_units', 'soldUnits as total_sold']);
            $user->is_most_active = $user->id == $this->unitRepository->mostActiveUserIdThisMonth();
        }
        // dd($user);
        return $user;
    }

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

    public function createCard(array $request)
    {
        return $this->userRepository->createCard($request);
    }
    public function getCard($id)
    {
        return $this->userRepository->getCard($id);
    }

    public function updateCard(array $request , int $id)
    {
        $card = $this->getCard($id);
        return $this->userRepository->updateCard($request,$card);
    }

    public function deleteCard($id)
    {
        $card = $this->getCard($id);
        if($card)
        {
            if ($card->user_id == auth()->user()->id)
            {
                $this->userRepository->deleteCard($card);
            }
        }
    }

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

    public function create(array $request): User
    {
        // DB::enableQueryLog();
        $user = $this->userRepository->create($request);
        $this->saveData($request,$user);
        // dd(DB::getQueryLog());
        
        return $user;
    }
    public function update(array $request,int $id): User
    {
        $user = $this->checkItem($id);
        $user = $this->userRepository->update($request,$user);
        $this->saveData($request,$user);
        return $user;
    }
    //
    
    private function saveData($request, $user){
        if ($user->role == UserRoleEnum::SUB_ADMIN->value) {
            $this->userRepository->saveModules($request, $user);
        } elseif ($user->role == UserRoleEnum::PROVIDER->value) {
            $this->userRepository->saveProfile($request, $user);
        }
        
    }
    public function destroy(string $code): void
    {
        $user = $this->getItemByCode($code);
        if ($user)
        {
            if ($user->disable_delete) {
                return;
            }
            $this->userRepository->destroy($user);
        }
        else
        {
            $user = $this->getItemTrashed($code);
            $this->userRepository->restore($user);
        }
    }
    public function destroyAll(array $request): void
    {
        // DB::enableQueryLog();
        // DB::flushQueryLog();
        if ($request['status'] == 1)
        {
            $this->userRepository->destroyAll($request['ids']);
        }
        else
        {
            $this->userRepository->restoreAll($request['ids']);
        }
        // dd(DB::getQueryLog());
    }
    public function logout()
    {
        $this->update(['api_token'=>null],Auth::user()->id);
        Auth::logout();
    }
    public function deactivate()
    {
        $this->update(['api_token'=>null,'activation'=> UserActivationEnum::INACTIVE->value],Auth::user()->id);
        Auth::logout();
    }
    public function activate()
    {
        $this->update(['activation'=> UserActivationEnum::ACTIVE->value],Auth::user()->id);
    }
    public function sendCode(array $request)
    {
        $request['user'] = $request['email'];
        $request['code'] = 1234;
        $this->userRepository->sendCode($request);
    }
    public function checkCode(array $request)
    {
        $now = Carbon::now()->format('Y-m-d H:i:s');
        $code = $this->userRepository->checkCode($request);
        if (!$code)
        {
            return null;
        }
        $expire_time = Carbon::createFromFormat('Y-m-d H:i:s', $code->created_at)->addMinutes(5)->format('Y-m-d H:i:s');
        if ($now > $expire_time)
        {
            return null;
        }
        return  $code;
    }
    public function getItemByEmail(string $email)
    {
        return $this->userRepository->getItemByEmail($email);
    }
    
    public function getItemByToken(string $token)
    {
        return $this->userRepository->getItemByToken($token);
    }
    public function getVisitorByDeviceToken(string $token)
    {
        return $this->userRepository->getVisitorByDeviceToken($token);
    }

    public function createUser(array $request)
    {
        $request['role'] = UserRoleEnum::USER->value;
        $user = $this->create($request);
        $address = $this->addressService->createDefault($user->id,AccountStatusEnum::USER->value);
        $this->update([
            'address_id'=>$address->id
        ],$user->id);
        return $user;
    }

    public function createToken(User $user)
    {
        $user = $this->userRepository->createToken($user);
        return $user;
    }

    public function login(User $user)
    {
        $visitor = $this->accountService->getAccount();
        $this->createToken($user);
        Auth::login($user);
        $this->cartService->changeCart($visitor , [
            'status'=>AccountStatusEnum::USER->value,
            'user'=>$user
        ]);
    }
}
