<?php

namespace twa\ecomauth\repositories;

use Carbon\Carbon;
use twa\apilibs\controllers\PhoneFunctionsController;
use twa\ecomauth\models\EcomUsersModel;
use twa\ecomauth\models\EcomUsersTokenModel;

class AuthenticateRepository
{

    public function getUserById($id)
    {
        return EcomUsersModel::query()
            ->where('guest_user', 0)
            ->where('cancelled', 0)
            ->where('id', $id)
            ->first();
    }

    public function getUserByPhone($phone)
    {
        return EcomUsersModel::query()
            ->where('guest_user', 0)
            ->where('cancelled', 0)
            ->where('phone', $phone)
            ->first();
    }

    public function getVerifiedUserByPhone($phone)
    {
        return EcomUsersModel::query()
            ->where('guest_user', 0)
            ->where('cancelled', 0)
            ->where('phone', $phone)
            ->where('phone_verified' , 1)
            ->first();
    }

    public function getUserByEmail($email)
    {
        return EcomUsersModel::query()
            ->where('guest_user', 0)
            ->where('cancelled', 0)
            ->where('email', $email)
            ->first();
    }

    public function getVerifiedUserByEmail($email)
    {
        return EcomUsersModel::query()
            ->where('guest_user', 0)
            ->where('cancelled', 0)
            ->where('email', $email)
            ->where('email_verified' , 1)
            ->first();
    }

    public function checkEmailTaken($email){
        return EcomUsersModel::query()
            ->where('guest_user', 0)
            ->where('cancelled', 0)
            ->where('email', $email)
            ->where('email_verified' , 1)
            ->first();
    }

    public function checkPhoneTaken($phone){
        return EcomUsersModel::query()
            ->where('guest_user', 0)
            ->where('cancelled', 0)
            ->where('phone', $phone)
            ->where('phone_verified' , 1)
            ->first();
    }

    public function checkPassword($user_id , $password){

        $encrypted_password = md5($password);

        $count_users = EcomUsersModel::query()
            ->where('id', $user_id)
            ->where('password', $encrypted_password)
            ->count();

        if($count_users == 0){
            return false;
        }

        return true;
    }

    public function getUserByPhoneAndEmail($phone , $email){
        return EcomUsersModel::query()
            ->where('guest_user', 0)
            ->where('cancelled', 0)
            ->where('email', $email)
            ->where('phone', $phone)
            ->first();
    }

    public function getVerifiedUserByPhoneOrEmail($phone , $email){
        return EcomUsersModel::query()
            ->where('guest_user', 0)
            ->where('cancelled', 0)
            ->where(function($q) use($phone , $email){
                $q->orWhere(function($q1) use ($phone){
                    $q1->where('phone', $phone);
                    $q1->where('phone_verified' , 1);
                });
                $q->orWhere(function($q2) use ($email){
                    $q2->where('email', $email);
                    $q2->where('email_verified' , 1);
                });
            })
            ->first();
    }

    public function createUserByPhone($full_phone , $original_phone , $phone_country_code)
    {

        $user = new EcomUsersModel();
        $user->phone = $full_phone;
        $user->phone_original = $original_phone;
        $user->phone_country_code = $phone_country_code;
        $user->guest_user = 0;
        $user->save();

        return $user;

    }

    public function createUserByEmail($email){
        $user = new EcomUsersModel();
        $user->email = $email;
        $user->guest_user = 0;
        $user->save();

        return $user;
    }

    public function createUserByPhoneAndEmail($full_phone , $original_phone , $phone_country_code , $email)
    {

        $user = new EcomUsersModel();
        $user->phone = $full_phone;
        $user->phone_original = $original_phone;
        $user->phone_country_code = strtoupper($phone_country_code);
        $user->email = $email;
        $user->guest_user = 0;
        $user->save();

        return $user;

    }

    public function updateUserNotVerifiedField($user , $full_phone , $original_phone , $phone_country_code , $email)
    {

        if($user->phone_verified == 1){
            if($user->email != $email) {
                $user->email = $email;
                $user->email_verified = 0;
            }
        }

        if($user->email_verified == 1) {
            if ($user->phone != $full_phone) {
                $user->phone_original = $original_phone;
                $user->phone = $full_phone;
                $user->phone_country_code = strtoupper($phone_country_code);
                $user->phone_verified = 0;
            }
        }

        $user->verified = $user->phone_verified == 1 && $user->email_verified == 1 ? 1 : 0;
        $user->save();

        return $user;
    }

    public function createOrUpdateUserByEmail($email, $first_name, $last_name, $attributes){
        $UserCheck = \twa\ecomauth\models\EcomUsersModel::where('email', $email)->where('cancelled', 0)->first();
        if (!$UserCheck) {
            $UserCheck = new \twa\ecomauth\models\EcomUsersModel();
        }
        $UserCheck->email = $email;
        $UserCheck->first_name = $first_name;
        $UserCheck->last_name = $last_name;
        $UserCheck->verified = $UserCheck->phone_verified == 1 ? 1 : 0;
        $UserCheck->email_verified = 1;
        if (is_array($attributes)) {
            $old_attributes = $UserCheck->cms_attributes;
            $old_attributes = !is_array($old_attributes) ? [] : $old_attributes;
            $attributes = array_merge($attributes , $old_attributes);
            $UserCheck->cms_attributes = $attributes;
        }

        $UserCheck->token = md5(uniqid());
        $UserCheck->save();

        $this->createUserToken($UserCheck);

        return response()->json($this->getProfile($UserCheck), 200);
    }


    public function updateUser($User , $fields){

        $PossibleUpdates = ['first_name','last_name','phone','cms_attributes','phone_country_code','phone_original' , 'password' , 'email','birthdate'];
        if(isset($fields['day']) && isset($fields['month']) && isset($fields['year'])){
            $fields['birthdate']= Carbon::parse($fields['year'].'-'.$fields['month'].'-'.$fields['day']);
        }

        foreach ($PossibleUpdates as $PossibleUpdate) {
            if (isset($fields[$PossibleUpdate]) && !is_null($fields[$PossibleUpdate])) {

                $field_value = $fields[$PossibleUpdate];

                if ($PossibleUpdate == "phone" && isset($fields['phone_country_code'])) {
                    try {
                        $PhoneValidation = PhoneFunctionsController::validatePhoneNumber($field_value, $fields['phone_country_code']);
                    }catch(\Throwable $th){
                        continue;
                    }

                    if (!$PhoneValidation['valid']) { continue; }

                    $User->$PossibleUpdate = $PhoneValidation['phone'];
                    $User->phone_original = $field_value;

                }elseif($PossibleUpdate == "password"){
                    $User->$PossibleUpdate = md5($field_value);
                } else {

                    $User->$PossibleUpdate = $field_value;
                }
            }
        }
        $User->save();

        return $User;
    }

    public function getProfile($user){

        $user->forceUpdateProfile = 0;
        $requiredParams = [ "first_name", "last_name", "email", "phone", "cms_attributes" ];
        foreach ($requiredParams as $param) {
            if (!$user->{$param} || $user->{$param} == "" || $user->{$param} == null) {
                $user->forceUpdateProfile = 1;
            }
        }

        $Token = $this->getUserToken($user);
        if (!$Token) { $Token = $this->createUserToken($user); }


        if(session('rm') == 1){
            twaSetCookie('rmt', $Token->token , time()+(365*24*3600));
            session(['rm' => 0]);
        }



        unset($user->password);
        unset($user->created_at);
        unset($user->updated_at);
        unset($user->cancelled);
        unset($user->locked);
        unset($user->cms_attributes);
        $user->token = isset($Token->token) ? $Token->token : NULL;
        $user->preferred_lang =  $this->getPreferredLanguages($user);

        return collect($user)->recursive();
    }

    public function createUserToken($user){
        $Token =  new EcomUsersTokenModel();
        $Token->token = md5(uniqid());
        $Token->ecom_users_id = $user->id;
        $Token->disabled = 0;
        $Token->save();

        return  $Token;
    }

    public function getUserToken($user){
        return EcomUsersTokenModel::where('ecom_users_id', $user->id)->where('disabled', 0)->orderBy('id','DESC')->first();
    }

    public function getPreferredLanguages($user){
        $PreferredLangs = \twa\ecomauth\models\EcomUsersLanguagePreferencesModel::query()->select('lang','ecom_stores_id','created_at','updated_at')->where('ecom_users_id',$user['id'])->where('cancelled',0)->get()->toArray();
        $PreferredLangs = collect($PreferredLangs)->keyBy('ecom_stores_id');
        return $PreferredLangs;
    }
}
