<?php

namespace twa\ecomauth\controllers\v1;

use App\Http\Controllers\Controller;
use Carbon\Carbon;
use twa\apilibs\traits\APITrait;
use twa\ecomauth\models\EcomUsersTokenModel;
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;
use Laravel\Socialite\Facades\Socialite;

class SocialAuthenticateController extends Controller
{
    use APITrait;

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

    public function redirectToSocial($network){

        $provider = config('ecom-auth')['providers'][$network];

        $redirection = $this->getSocialRedirect($provider);

        return redirect($redirection);
    }

    public function getSocialRedirect($provider){

        $domain = !isset($provider['domain']) ? env('APP_URL') : $provider['domain'];
        $options = $provider['data'];

        if($options['redirect'][0] != "/"){
            $options['redirect'] = "/".$options['redirect'];
        }

        $options['redirect'] = $domain . $options['redirect'];
        $scope=false;
        switch($provider['provider']){
            case "facebook" : $class = \Laravel\Socialite\Two\FacebookProvider::class; break;
            case "google" : $class = \Laravel\Socialite\Two\GoogleProvider::class; break;
            default: $class = null; break;
        }

        if(!$class){
            return null;
        }

        if($scope){
            return Socialite::buildProvider($class, $options)->scopes(['first_name', 'email'])->redirect()->getTargetURL();
        }else{
            return Socialite::buildProvider($class, $options)->redirect()->getTargetURL();
        }
    }

    public function render($network)
    {
        switch ($network) {
            case "facebook":
                $response = $this->handleCallBackFacebook();
                break;
            case "google":
                $response = $this->handleCallBackGoogle();
                break;
            case "twitter":
                $response = $this->handleCallBackTwitter();
                break;
        }

        if($response->getStatusCode() != 200){
            $error_result = $response->getOriginalContent();

//           return $this->redirectFail($error_result['error']['title'] , $error_result['error']['message'] );

            return $this->redirectFail($error_result['error']['code']);

            //return \twa\ecomgeneral\controllers\HelpersController::processAPIError($response->getOriginalContent());
        }

        try{
            session([ "login" => collect($response->getOriginalContent())->recursive() ]);
            return (new CommonRepository)->redirectAsLoggedIn();
        }catch (\Throwable $e){
            return $this->redirectFail(48);
        }


        return (new CommonRepository)->redirectAsLoggedIn();
    }

    public function redirectFail($code){
        $url = session('auth_redirect_current');
        return redirect($url.'?notification='.$code);
    }

    public function handleCallBackFacebook()
    {
        try {
            $provider = config('ecom-auth')['providers']['facebook'];
            $class = \Laravel\Socialite\Two\FacebookProvider::class;
            $user = Socialite::buildProvider($class, $provider['data'])->stateless()->user();
        } catch (\Throwable $e) {
            return $this->APIDisplayResponse(48);
        }

        if(!$user->email){
            return $this->APIDisplayResponse(47);
        }

        $name = collect(explode(' ', $user->name));

        return $this->AuthenticateRepository->createOrUpdateUserByEmail($user->email, $name[0], $name->forget(0)->implode(' '), [ "facebook" => [ "id" => $user->id, "avatar" => $user->avatar ] ]);
    }

    public function handleCallBackGoogle()
    {
        try {
            $provider = config('ecom-auth')['providers']['google'];
            $class = \Laravel\Socialite\Two\GoogleProvider::class;
            $user = Socialite::buildProvider($class, $provider['data'])->user();
        } catch (\Throwable $e) {
            return $this->APIDisplayResponse(48);
        }

        if(!$user->email){
            return $this->APIDisplayResponse(47);
        }


        $name = collect(explode(' ', $user->name));


        return $this->AuthenticateRepository->createOrUpdateUserByEmail($user->email, $name[0], $name->forget(0)->implode(' '), [ "google" => [ "id" => $user->id, "avatar" => $user->avatar ] ]);

    }

    public function handleCallBackTwitter()
    {
        try {
            $user = \Socialite::driver('twitter')->user();
        } catch (\Throwable $e) {
            return $this->APIDisplayResponse(48);
        }

        if(!$user->email){
            return $this->APIDisplayResponse(47);
        }
        $name = collect(explode(' ', $user->name));

        return $this->AuthenticateRepository->createOrUpdateUserByEmail($user->email, $name[0], $name->forget(0)->implode(' '), [ "twitter" => [ "id" => $user->id, "avatar" => $user->avatar ] ]);

    }

    public function socialLogin($values = [])
    {
        $values = $this->ProcessValues($values);
        $Check = $this->ProcessRequired($values, [ 'first_name', 'last_name', 'email', 'token', 'provider', 'signature'  ]);
        if ($Check!==true) {
            return $Check;
        }

        if ($values->get('signature') != md5($values->get('provider').$values->get('token').$values->get('email'))) {
            return $this->APIDisplayResponse(2);
        }

        $arr = [];
        if (strtolower($values->get('provider')) == "apple") {
            $arr["apple_token"] = md5($values->get('token'));
        }

        return $this->AuthenticateRepository->createOrUpdateUserByEmail($values->get('email'), $values->get('first_name'), $values->get('last_name'),$arr);
    }


    public function handleSocialLogin(){

        if(!request()->has('data')){
            return abort(404);
        }

        $uploadedFile=str_replace(['#_=_' , ' '], '', request()->input('data'));

        $key = substr($uploadedFile,0,32);
        $encrypter = new \Illuminate\Encryption\Encrypter($key, 'aes-256-cbc');
        $decrypted =$encrypter->decrypt(substr($uploadedFile,32));
        $decrypted=json_decode($decrypted,true);

        $response = $this->AuthenticateRepository->createOrUpdateUserByEmail($decrypted['email'], $decrypted['name'][0], collect($decrypted['name'])->forget(0)->implode(' '), [ $decrypted['method'] => [ "id" => $decrypted['id'], "avatar" => $decrypted['avatar'] ] ]);


        if($response->getStatusCode() != 200){
            $error_result = $response->getOriginalContent();
            return $this->redirectFail($error_result['error']['code']);
        }

        try{
            session([ "login" => collect($response->getOriginalContent())->recursive() ]);
        }catch (\Throwable $e){

        }

        return (new CommonRepository)->redirectAsLoggedIn();
    }

}
