<?php

namespace twa\ecomauth\controllers\v1;

use App\Http\Controllers\Controller;
use Carbon\Carbon;
use twa\apilibs\traits\APITrait;

use twa\ecomauth\repositories\AuthenticateRepository;
use twa\ecomauth\repositories\CommonRepository;
use twa\ecomauth\repositories\OTPRepository;

use twa\apilibs\controllers\PhoneFunctionsController;
use Laravel\Socialite\Facades\Socialite;
use Validator;
use Cookie;

class AuthenticateController extends Controller
{
    use APITrait;

    public function __construct()
    {
        $this->AuthenticateRepository = new AuthenticateRepository();
        $this->CommonRepository = new CommonRepository();
        $this->OTPRepository = new OTPRepository();
    }


    public function render($store, $lang , $type = null)
    {

        if(request()->has('temporary-token')){
            twaSetCookie('offlineToken_v2',request()->input('temporary-token') , time()-3600);
        }

        session(["email" => null, "phone" => null]);
        $slug = $type;
        $config = config('ecom-auth');
        $type = $type ? $type : $config['primary'];
        if(!is_array($type)){ $types = [$type]; }else{ $types = $type; }

        $otp_primary = $config['otp_primary'];

        $auth_types = $config["auth_types"];
        $available_login_methods = collect($config['providers'])->where('active' , true)->map(function($provider){
            $domain = !isset($provider['domain']) ? env('APP_URL') : $provider['domain'];
            $href= $domain."/ecom/users/login/".$provider['provider']."/redirect";

            if(isset($provider['generalAuthenticator']) && $provider['generalAuthenticator']==true){
                $href='https://auth.twalab.live/authenticate?url='.env('APP_URL').'/users/login/data/callback'.'&method='.$provider['provider'];
            }
            return [
                    'icon' => $provider['provider'],
                    'label' => ___($provider['label']),
                    'href' =>$href,
                    'target' => '_parent',
                    'class' => 'twa-social'
                ];
        })->filter()->values();

        $alternative_types = array_diff($config['auth_types'], $types);
        foreach($alternative_types as $alternative_type) {
            try {
                $available_login_methods->push([
                    'icon' => $alternative_type,
                    'label' => ___('authentication.login_' . $alternative_type),
                    'href' => route('account-auth', ['type' => $alternative_type]),
                    'class' => ''
                ]);
            }catch(\Throwable $th){

            }
        }

        $country_code = $this->CommonRepository->getCountryCode();

        $enabled_recaptcha = $this->CommonRepository->checkRecaptcha();

        return view('EcomAuthViews::v1.authentication', compact('country_code','enabled_recaptcha','slug', 'available_login_methods', 'types' , 'otp_primary'));
    }

    public function authenticate($store , $lang , $type = null){

        $config= config('ecom-auth');

        $type = $type;
        $type = $type ? $type : $config['primary'];
        if(!is_array($type)){ $types = [$type]; }else{ $types = $type; }

        $auth_types = $config['auth_types'];
        $type = implode("-",$types);

        session(['guest' => request()->input('guest') , 'rm' => request()->input('remember_me' , 0)]);

        $enabled_recaptcha = $this->CommonRepository->checkRecaptcha();

        switch ($type) {
            case 'phone':

                $PhoneValidation = null;

                $validator = Validator::make(request()->all(), [
                    'phone_country_code' => 'required',
                    'phone' => 'required',
                    'g-recaptcha-response' => (!str_contains(request()->getHost(),'.test')) && $enabled_recaptcha ? 'required|captcha' : 'captcha'
                ])->after(function ($validator) use(&$PhoneValidation){
                    $PhoneValidation = \twa\apilibs\controllers\PhoneFunctionsController::validatePhoneNumber(request()->input('phone'), request()->input('phone_country_code'));
                    if (!$PhoneValidation['valid']) {
                        $validator->errors()->add('phone', 'Please enter a valid phone number');
                    }
                })->validate();

                $user = $this->AuthenticateRepository->getUserByPhone($PhoneValidation['phone']);

                if (!$user) {
                    session([$type => ['phone_original' => request()->phone, 'phone_country_code' => request()->phone_country_code]]);

                    $new_user = $this->AuthenticateRepository->createUserByPhone($PhoneValidation['phone'], request()->phone, request()->phone_country_code);

                    $challenge = $this->OTPRepository->sendChallenge($new_user , 'phone');

                    if(!$challenge){
                        return $this->CommonRepository->redirectAsError('limit-exceeded-verifications');
                    }

                    if(!in_array($type , $config['auth_verifications'])) {
                        session(["login" => $this->AuthenticateRepository->getProfile($new_user)]);
                        return redirect()->route('redirect-login');
                    }

                    session(['challenge' => $challenge]);
                    return redirect()->route('account-login', ['login_type' => 'otp', 'type_slug' => $type, 'token' => md5($new_user['id'])]);

                }



                break;

            case 'email':

                request()->validate([
                    'email' => 'required|email',
                    'g-recaptcha-response' => (!str_contains(request()->getHost(),'.test')) && $enabled_recaptcha ? 'required|captcha' : 'captcha'
                    ]);

                $email = request()->email;

                $user = $this->AuthenticateRepository->getUserByEmail($email);

                if (!$user) {
                    session([$type => ['email' => $email]]);

                    $new_user = $this->AuthenticateRepository->createUserByEmail($email);

                    $challenge = $this->OTPRepository->sendChallenge($new_user , 'email');

                    if(!$challenge){
                        return $this->CommonRepository->redirectAsError('limit-exceeded-verifications');
                    }


                    if(!in_array($type , $config['auth_verifications'])) {
                        session(["login" => $this->AuthenticateRepository->getProfile($new_user)]);
                        return redirect()->route('redirect-login');
                    }

                    session(['challenge' => $challenge]);
                    return redirect()->route('account-login', ['login_type' => 'otp', 'type_slug' => $type, 'token' => md5($new_user['id'])]);


                }


                break;

            case 'email-phone':
            case 'phone-email':

            $PhoneValidation = null;

            $validator = Validator::make(request()->all(), [
                'phone_country_code' => 'required',
                'phone' => 'required',
                'email' => 'required|email',
                'g-recaptcha-response' => (!str_contains(request()->getHost(),'.test')) && $enabled_recaptcha ? 'required|captcha' : 'captcha'
                ])->after(function ($validator) use(&$PhoneValidation){
                        $PhoneValidation = \twa\apilibs\controllers\PhoneFunctionsController::validatePhoneNumber(request()->input('phone'), request()->input('phone_country_code'));
                        if (!$PhoneValidation['valid']) {
                            $validator->errors()->add('phone', 'Please enter a valid phone number');
                        }
                    })->validate();

            $user = $this->AuthenticateRepository->getUserByPhoneAndEmail($PhoneValidation['phone'], request()->email);

            if(!$user){
                $user = $this->AuthenticateRepository->getVerifiedUserByPhoneOrEmail($PhoneValidation['phone'], request()->email);
            }

            session([
                "phone" => ['phone_original' => request()->phone, 'phone_country_code' => request()->phone_country_code],
                "email" => ["email" => request()->email]
            ]);


            if(!$user){
                $user = $this->AuthenticateRepository->createUserByPhoneAndEmail($PhoneValidation['phone'], request()->phone, request()->phone_country_code, request()->email);
            }else{
                $user = $this->AuthenticateRepository->updateUserNotVerifiedField($user , $PhoneValidation['phone'], request()->phone, request()->phone_country_code, request()->email);
            }

        }


        $action = $this->CommonRepository->getLoginAction($user , $type);

        switch($action){
            case "otp_login" :

                $challenge = $this->OTPRepository->sendChallenge($user, in_array($type , ["email" , "phone"]) ? $type : null);

                if(!$challenge){
                    return $this->CommonRepository->redirectAsError('limit-exceeded-verifications');
                }

                session(['challenge' => $challenge ]);

                return redirect()->route('account-login', ['login_type' => 'otp', 'token' => md5($user['id'])  , 'type_slug' => $type]);

            case "password_login":

                session(['auth_login_user' => $user]);

                return redirect()->route('account-login', ['login_type' => 'password', 'token' => md5($user['id'] ) , 'type_slug' => $type]);

            case "direct_login" :

                session(["login" => $this->AuthenticateRepository->getProfile($user)]);
                return redirect()->route('redirect-login');


            case "render_profile":
                $user->email_verified=1;
                $user->phone_verified=1;
                $user->verified=1;
                $user->verified_at=Carbon::now();
                $user->save();
                session(['login'=>$this->AuthenticateRepository->getProfile($user)]);

                return redirect()->route('redirect-login');

        }

    }


}
