<?php

namespace App\Packages\v4\User\Manager;

use App\Packages\User\Models\User;
use App\Packages\v4\Follower\Manager\FollowerManager;
use App\Packages\v4\User\Repository\UserRepository;
use App\Packages\v4\User\Requests\PersonalRequest;
use App\PackagesApi\v4\Requests\Settings\UpdateNicknameRequest;
use App\PackagesApi\v4\Requests\Settings\UpdateOnBoarding;
use App\PackagesApi\v4\Requests\Settings\UpdateSettingsRequest;
use Hash;
use Laravel\Socialite\Two\User as SocialiteUser;

/**
 * Class UserEntityManager
 * @package App\Packages\User\Manager\v4
 */
class UserEntityManager
{

    /**
     * @param $email
     * @param $nickname
     * @param $password
     * @return User|object|null
     */
    public static function createUserFromEmail($email, $nickname, $password)
    {
        $user = UserRepository::init()->firstByEmail($email);

        if ( ! $user ) {
            $user = new User();
            $user->email = $email;
            $user->nickname = $nickname;
        }

        $user->password = Hash::make($password);
        $user->is_registered = true;
        $user->save();

        return $user;
    }

    /**
     * @param SocialiteUser $socialiteUser
     * @return User
     */
    public static function createUserFromFacebook(SocialiteUser $socialiteUser)
    {
        $user = UserRepository::init()->firstByEmailWithPassword($socialiteUser->getEmail());

        if ( ! $user ) $user = new User();

        $user->fb_id = $socialiteUser->getId();
        $user->nickname = null;
        if ( ! $user->email ) $user->email = $socialiteUser->getEmail();
        $user->is_registered = true;
        $user->save();

        return $user;
    }

    /**
     * @param SocialiteUser $socialiteUser
     * @return User
     */
    public static function createUserFromGoogle(SocialiteUser $socialiteUser)
    {
        $user = UserRepository::init()->firstByEmailWithPassword($socialiteUser->getEmail());

        if ( ! $user ) $user = new User();

        $user->google_id = $socialiteUser->getId();
        $user->nickname = null;
        if ( ! $user->email ) $user->email = $socialiteUser->getEmail();
        $user->is_registered = true;
        $user->save();

        return $user;
    }

    /**
     * @param SocialiteUser $socialiteUser
     * @return User
     */
    public static function createUserFromApple(SocialiteUser $socialiteUser)
    {
        $user = UserRepository::init()->firstByEmailWithPassword($socialiteUser->getEmail());

        if ( ! $user ) $user = new User();

        $user->apple_id = $socialiteUser->getId();
        $user->nickname = null;
        if ( ! $user->email ) $user->email = $socialiteUser->getEmail();
        $user->is_registered = true;
        $user->save();

        return $user;
    }

    /**
     * @param $phoneCode
     * @param $phoneNumber
     *
     * @return User
     */
    public static function createUserFromPhoneNumber($phoneCode, $phoneNumber)
    {
        $phoneHash = phoneHash($phoneCode, $phoneNumber);
        $user = UserRepository::init()->firstByPhoneHash($phoneHash);

        if (!$user) {
            $user = UserEntityManager::createUserFromPhoneHash($phoneHash);
        }

        return $user;
    }

    /**
     * @param string $phoneHash
     *
     * @return User
     */
    public static function createUserFromPhoneHash($phoneHash)
    {
        $user = new User();
        $user->nickname = "";
        $user->phone_hash = $phoneHash;
        $user->phone_code = "";
        $user->phone_number = "";
        $user->is_registered = false;
        $user->save();

        return $user;
    }

	/**
	 * @param string $phoneCode
	 * @param string $phoneNumber
     *
	 * @return User
	 */
	public static function createUser($phoneCode, $phoneNumber)
	{
		$user = new User();
		$user->nickname = "";
        $user->phone_hash = phoneHash($phoneCode, $phoneNumber);
		$user->phone_code = $phoneCode;
		$user->phone_number = $phoneNumber;
		$user->is_registered = true;
		$user->save();

		return $user;
	}

    /**
     * @param User $user
     * @param UpdateNicknameRequest $request
     *
     * @return User
     */
    public static function updateNickname(User $user, UpdateNicknameRequest $request)
    {
        $user->nickname = mb_strtolower($request->nickname);
        $user->is_registered = true;
        $user->save();

        return $user;
    }

    /**
     * @param User $user
     * @param UpdateSettingsRequest $request
     *
     * @return User
     */
    public static function updateSettings(User $user, UpdateSettingsRequest $request)
    {
        if ($request->filled('nickname')) $user->nickname = mb_strtolower($request->nickname);
        $user->is_private = $request->is_private;
        $user->is_notification_app = $request->isAppNotificationsEnabled;
        $user->is_notification_push = $request->isPushNotificationsEnabled;
        $user->save();

        if ( ! $user->is_private ) {
            FollowerManager::acceptAllPending($user);
        }

        return $user;
    }

    /**
     * @param User $user
     * @param UpdateOnBoarding $request
     *
     * @return User
     */
    public static function updateOnBoarding(User $user, UpdateOnBoarding $request)
    {
        $user->is_on_boarding_done = (bool)$request->onboarding_done;
        $user->save();

        return $user;
    }

    /**
     * @param User $user
     * @return bool|null
     * @throws \Exception
     */
    public static function deleteUser(User $user)
    {
        $user->phone_code = null;
        $user->phone_number = null;
        $user->nickname = null;
        $user->phone_hash = null;
        $user->save();

        return $user->delete();
    }
}
