<?php

namespace twa\ecomauth\controllers\v1;

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

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

use twa\ecomgeneral\models\EcomUsersModel;
use Validator;

class LoginController 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_slug ,  $login_type , $token){

        $challenge = null;
        $config = config('ecom-auth');
        $password_exist = $this->CommonRepository->passwordEnabled();
        $other_auth_methods = [];

        switch ($login_type) {
            case "otp" :
                $challenge = session('challenge');
                if (!$challenge) { return redirect()->route('redirect-login');  }

                $user_id = $challenge->ecom_users_id;
                if (md5($user_id) != $token) {return redirect()->route('redirect-login');  }

                $user = $this->AuthenticateRepository->getUserById($user_id);
                if (!$user) { return redirect()->route('redirect-login');  }

                $sent_to = $this->CommonRepository->getChallengeSentTo($challenge , $user);

                return view('EcomAuthViews::v1.verify-pin' , [
                    'type' => in_array($type_slug , ["phone" , "email"]) ? $type_slug : null,
                    'target' => route('account-login' , ['type_slug' => $type_slug , 'login_type' => $login_type ,'token' => $token ] ),
                    'sent_to' => $sent_to,
                    'resend_target' => route('redirect-otp' , ['type_slug' => $type_slug  , 'token' => $token] ),
                    'expires_after' => Carbon::now()->diffInSeconds(Carbon::parse($challenge->expires_at))
                ]);


            case "password" :

                $user = session('auth_login_user');

                if (!$user) { return abort("404"); }

                $auth_by = [];

                if($type_slug == "email" && $user->email){
                    $auth_by [] = ['icon' => 'envelope' , 'value' => $user->email ];
                }elseif($type_slug == "phone" && $user->phone){
                    $auth_by [] = ['icon' => 'phone' , 'value' => $user->phone ];
                }else{
                    if($user->email){ $auth_by [] = ['icon' => 'envelope' , 'value' => $user->email ]; }
                    if($user->phone){ $auth_by [] = ['icon' => 'phone' , 'value' => $user->phone ]; }
                }

                return view('EcomAuthViews::v1.password-login' , [
                    'type_slug' => $type_slug,
                    'auth_by' => $auth_by
                ]);
        }
    }

    public function login($store , $lang , $type_slug , $login_type , $token){

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

        $type = in_array($type_slug , ["phone" , "email"]) ? $type_slug : null;

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

        switch ($login_type){
            case "otp" :

                $result = null;

                $challenge = session('challenge');

                if(!$challenge){ return redirect()->route('redirect-login'); }

                Validator::make(request()->all(), [
                    'code' => 'required'
                ])->after(function($validator) use (&$result , $challenge){
                    $challenge_code = $challenge->challenge;
                    
                    try{
                        $code = json_decode(json_encode(request()->input('code')),1);
                    }catch(\Throwable $th){
                        $code = [];
                    }

                    if(!is_array($code)){
                        $validator->errors()->add('code', 'Your pin is incorrect. Please enter a valid one or resend');
                    }

                    $code = implode("", $code);
                    $result = $this->OTPRepository->verify($challenge_code , $code);

                    if(!$result){
                        $validator->errors()->add('code', 'Something went wrong, try again later');
                    }else {
                        if (!$result['verification']) {
                            $validator->errors()->add('code', 'Your pin is incorrect. Please enter a valid one or resend');
                        }
                    }

                })->validate();


                $user = $result['user'];
                $user->verified = 0;


                if($result['verification'] == "email_verified"){
                    $user->email_verified = 1;
                    $user->verified = $user->phone_verified;
                }elseif($result['verification'] == "phone_verified"){
                    $user->phone_verified = 1;
                    $user->verified = $user->email_verified;
                }
                $user->save();



                session(["login" => $this->AuthenticateRepository->getProfile($user) , 'challenge' => null]);

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

            break;

            case "password":

                $user = session('auth_login_user');

                if(!$user){ return redirect()->route('redirect-login');  }


                Validator::make(request()->all(), [
                    'password' => 'required',
                ])->after(function($validator) use ($user){
                    $check = $this->AuthenticateRepository->checkPassword($user["id"] , request()->input("password"));

                    if(!$check){
                        $validator->errors()->add('password', "You have entered an incorrect password");
                    }
                })->validate();

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

            break;
        }


        return false;

    }


    public function redirectToOTP($store , $lang, $type_slug , $token)
    {

        $challenge = session('challenge');

        if (!$challenge) {
            return redirect()->route('redirect-login');
        }

        $user_id = $challenge->ecom_users_id;

        if (md5($user_id) != $token) {
            return redirect()->route('redirect-login');
        }

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

        $user = $this->AuthenticateRepository->getUserById($user_id);

        if (!$user) {
            return redirect()->route('redirect-login');
        }

        if($type_slug && in_array($type_slug , ['email' , 'phone'])){
            $challenge = $this->OTPRepository->sendChallenge($user , $type_slug);
        }else{
            $challenge = $this->OTPRepository->sendChallenge($user);
        }

        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_slug]);

    }


    public function redirectAsLoggedIn(){
        return $this->CommonRepository->redirectAsLoggedIn();
    }

}
