<?php

namespace App\Http\Services;

use App\Http\Enums\AuthStrategies;
use App\Http\Resources\UserResource;
use Illuminate\Support\Facades\Hash;
use App\Http\Repositories\UserRepository;
use App\Http\Strategies\AuthVerification\AuthVerificationStrategy;
use App\Http\Strategies\PasswordRecovery\PasswordRecoveryStrategy;


class AuthService extends Services
{
    public function __construct(
        protected UserRepository $userRepository,
        protected PasswordRecoveryStrategy $passwordRecoveryStrategy,
        protected AuthVerificationStrategy $authVerificationStrategy
    ) {
    }

    public function register($data)
    {
        $user = $this->userRepository->createUser([
            "name" => $data['name'],
            "email" => $data['email'],
            'password' => $data['password'],
            "phone_country_code" => '966',
            "phone" => $data['phone'],
            'gender' => $data['gender'],
            'city_id' => $data['city_id'],
            'region_id' => $data['region_id'],
        ]);

        $this->authVerificationStrategy->phone()->request($user['phone']);

        return [
            'user' => $user,
            'token' => $user->createToken('auth token')->plainTextToken
        ];
    }

    public function identifierVerificationActive($data)
    {
        return $this->authVerificationStrategy->strategy(AuthStrategies::Phone->value)->active($data['identifier'], $data['code']);
    }

    public function identifierVerificationRequest($data)
    {
        return $this->authVerificationStrategy->strategy(AuthStrategies::Phone->value)->request($data['identifier']);
    }

    public function passwordRecoveryForgot($data)
    {
        return $this->passwordRecoveryStrategy->strategy(AuthStrategies::Phone->value)->forgot($data['identifier']);
    }

    public function passwordRecoveryCheck($data)
    {
        return $this->passwordRecoveryStrategy->strategy(AuthStrategies::Phone->value)->check($data['identifier'], $data['code']);
    }

    public function passwordRecoveryReset($data)
    {
        return $this->passwordRecoveryStrategy->strategy(AuthStrategies::Phone->value)->reset($data['identifier'], $data['code'], $data['password']);
    }

    public function login($data)
    {
        $user = $this->userRepository->userByPhone($data['identifier']);

        $user = ($user && $user->hasRole($data['role'])) ? $user : null;

        $data['identifier_type'] = 'phone';

        if (!$user)
            respond()->unauthorized(
                message: __('The provided :identifier_type is incorrect', ['identifier_type' => 'phone']),
                data: ["credentials_is_correct" => false]
            )->throwResponse();

        if (!$user || !Hash::check($data['password'], $user->password))
            respond()->unauthorized(
                message: __('The provided password is incorrect'),
                data: ["credentials_is_correct" => false]
            )->throwResponse();

        if ($data['identifier_type'] == 'phone' && is_null($user->phone_verified_at))
            respond()->unauthorized(
                message: __('Phone is not activated'),
                data: ["credentials_is_correct" => true]
            )->throwResponse();

        return [
            'user' => new UserResource($user),
            'token' => $user->createToken('auth token')->plainTextToken
        ];
    }

    public function logout()
    {
        auth()->user()->tokens()->delete();
    }

    public function updateUserById($user_id, $data)
    {
        $existingUser = $this->userRepository->findUserById($user_id);

        if (isset($data['phone']) && $data['phone'] && $data['phone'] !== $existingUser->phone)
            $data['phone_verified_at'] = null;

        $user = $this->userRepository->updateUserById($user_id, $data);

        $this->authVerificationStrategy->phone()->request($data['phone']);

        if (isset($data['phone']) && $data['phone'] !== $existingUser->phone)
            $this->logout();

        return $user;
    }

}
