<?php

namespace App\Http\Controllers\Auth\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\FacebookLogin;
use App\Http\Requests\Api\RegisterUsersRequest;
use App\Http\Requests\Api\ResetUserPasswordRequest;
use App\Mail\Registration;
use App\Role;
use App\User;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Support\Facades\Auth;
use Mail;
use Socialite;

class SecurityController extends Controller
{
    public $successStatus = 200;

    /**
     * login api
     *
     * @return \Illuminate\Http\Response
     */
    public function login()
    {
        if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
            $user = Auth::user();
            if (!$user->email_verified_at) {
                return response()->json(['error' => 'Sorry your email wasn\'t verified.'], 401);
            }
            $userArray = $user->toArray();
            $userArray["image"] = $user->user_image;
            $success['token'] = $user->createToken('MyApp')->accessToken;

            return response()->json(["data" => ['success' => $success, 'user' => $userArray]], $this->successStatus);
        } else {
            return response()->json(['error' => 'Unauthorised'], 401);
        }
    }

    /**
     * Register api
     *
     * @param RegisterUsersRequest $request
     * @return \Illuminate\Http\Response
     */
    public function register(RegisterUsersRequest $request)
    {
        $date = new \DateTime();

        $input = $request->all();
        $input['password'] = bcrypt($input['password']);
        $input['remember_token'] = self::generateToken();
        $input['verification_token'] = self::generateRandomString(64);
        $input['role_id'] = Role::ROLE_USER;
        /** @var User $user */
        $user = User::create($input);

        Mail::to($user->email)->send(new Registration($user));

        return response()->json(["data" => ['user' => $user]], $this->successStatus);
    }

    /**
     *
     * Reset api
     * @param ResetUserPasswordRequest $request
     * @return \Illuminate\Http\Response
     */
    public function resetPassword(ResetUserPasswordRequest $request)
    {
        $input = $request->all();
        if ($user = User::whereEmail($input['email'])->first()) {
            $randPass = self::generateRandomString();
            $pass = bcrypt($randPass);
            $user->update(['password' => $pass]);
            $user->toJson();
            $mail = new PHPMailer(true);
            $mail->SMTPOptions = array(
                'ssl' => array(
                    'verify_peer' => false,
                    'verify_peer_name' => false,
                    'allow_self_signed' => true
                )
            );
            // Passing `true` enables exceptions
            try {
                //Server settings
                $mail->SMTPDebug = 2;                                 // Enable verbose debug output
                // $mail->isSMTP();                                      // Set mailer to use SMTP
                // $mail->Host = 'smtp.gmail.com';  // Specify main and backup SMTP servers
                $mail->Host = 'smtp.gmail.com';  // Specify main and backup SMTP servers
                $mail->SMTPAuth = true;                               // Enable SMTP authentication
                $mail->Username = 'barcelonaeventsfb@gmail.com';                 // SMTP username
                $mail->Password = 'G430524!';                           // SMTP password
                $mail->SMTPSecure = 'tls';                            // Enable TLS encryption, `ssl` also accepted
                $mail->Port = 587;                                    // TCP port to connect to
                //Recipients
                $mail->setFrom($input['email'], 'Barcelona Events');
                $mail->addAddress($input['email'], 'Event');     // Add a recipient
                $mail->addReplyTo($input['email'], 'Event Information');
                $mail->addCC($input['email']);
                $mail->addBCC($input['email']);
                //Content
                $mail->isHTML(true);                                  // Set email format to HTML
                $mail->Subject = 'Reset password';
                $mail->Body = "Your new password <b> $randPass </b>";//Переробити цю діч
                $mail->send();
            } catch (Exception $e) {
                return response()->json(['error' => $e->getMessage()], 401);
            }

            return response()->json(["data" => ['user' => $user]], $this->successStatus);
        } else {
            return response()->json(['error' => 'EmailNotFound'], 401);
        }
    }

    /**
     * FacebookLogin api
     * @param FacebookLogin $request
     * @return \Illuminate\Http\Response
     */
    public function facebookLogin(FacebookLogin $request)
    {
        $token = $request->get('access_token');//URL
        if (empty($token)) {
            $token = "";
        }
        try {
            $userSocial = Socialite::driver('facebook')->userFromToken($token);
        } catch (ClientException $exception) {
            return response()->json([
                    "error" => [
                        'message' => "The access token could not be decrypted",
                        'code' => 400
                    ]
                ], 400);
        }
        $id = $userSocial->getId();
        //Якщо такий Користувач існує
        if ($user = User::where("facebookId", $id)->first()) {
            $arrUser = $user->toArray();
            $arrUser["image"] = $userSocial->getAvatar();
            $success['token'] = $user->createToken('MyApp')->accessToken;

            return response()->json(["data" => ['success' => $success, 'user' => $arrUser]], $this->successStatus);
        } else {
            $input['name'] = $userSocial->getName();
            $input['facebookId'] = $id;//в міграціях перетворюємо на string
            $input['remember_token'] = self::generateToken();
            $input['role_id'] = Role::ROLE_USER;
            $input['email_verified_at'] = new \DateTime('now');
            $createUser = User::create($input);
            $success['token'] = $createUser->createToken('MyApp')->accessToken;
            $user = User::where("facebookId", $id)->first();
            $arrUser = $user->toArray();
            $arrUser["image"] = $userSocial->getAvatar();

            return response()->json(["data" => ['success' => $success, 'user' => $arrUser]], $this->successStatus);
        }
    }

    /**
     * FacebookLogin api
     * @param FacebookLogin $request
     * @return \Illuminate\Http\Response
     */
    public function googleLogin(FacebookLogin $request)
    {
        $token = $request->get('access_token');//URL
//        if (empty($token)) {
//            $token = "ya2.GlsEBxbSJJfekB_P1ZaQ3fK7AGXgsV1vgTAmvuu4dp8njdWNTdIoxAHifQz5W7xDVEQOqzXdlOOikaNMsbjxU7WVVOD
//            RGd2ITQuZmcdptkalch9Z02eIMAQEZMkO";
//        }
        try {
            $userSocial = Socialite::driver('google')->userFromToken($token);
        } catch (ClientException $exception) {
            return response()->json([
                "error" => [
                    'message' => "The access token could not be decrypted",
                    'code' => 400
                ]
            ], 400);
        }
        $id = $userSocial->getId();
        //Якщо такий Користувач існує
        if ($user = User::where("googleId", $id)->first()) {
            $arrUser = $user->toArray();
            $arrUser["image"] = $userSocial->getAvatar();
            $success['token'] = $user->createToken('MyApp')->accessToken;

            return response()->json(["data" => ['success' => $success, 'user' => $arrUser]], $this->successStatus);
        } else {
            $input['name'] = $userSocial->getName();
            $input['googleId'] = $id;//в міграціях перетворюємо на string
            $input['remember_token'] = self::generateToken();
            $input['role_id'] = Role::ROLE_USER;
            $input['email_verified_at'] = new \DateTime('now');
            $createUser = User::create($input);
            $success['token'] = $createUser->createToken('MyApp')->accessToken;
            $user = User::where("googleId", $id)->first();
            $arrUser = $user->toArray();
            $arrUser["image"] = $userSocial->getAvatar();

            return response()->json(["data" => ['success' => $success, 'user' => $arrUser]], $this->successStatus);
        }
    }

    /**
     * {@inheritdoc}
     */
    public static function generateToken()
    {
        return rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
    }

    /**
     * login api
     *
     * @return \Illuminate\Http\Response
     */
    public function logout()
    {
        $user = Auth::user();
        $token = $user->token()->revoke();

        return response()->json(["data" => ['logout' => 'success']], $this->successStatus);
    }

    public static function generateRandomString($length = 10)
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }

        return $randomString;
    }
}
