<?php

namespace App\Libraries\Users;

use App\Models\User;
use App\Models\UserSession;

/**
 * Class AuthAPI
 *
 * @package App\Libraries\Users
 */
class AuthAPI
{
    /**
     * Class instance
     *
     * @var \App\Libraries\Users\AuthAPI
     */
    protected static $instance = null;

    /**
     * API user
     *
     * @var \App\Models\User
     */
    protected static $user = null;

    /**
     * Get instance
     *
     * @return \App\Libraries\Users\AuthAPI
     */
    static public function getInstance()
    {
        if (is_null(static::$instance)) {
            static::$instance = new AuthAPI();
        }

        return static::$instance;
    }

    /**
     * Set session for user
     *
     * @param \App\Models\User $user
     * @param bool $clearPrevious
     * @return array
     */
    public function setSession(User $user, $clearPrevious = false)
    {
        $token = $this->generateToken($user);

        if ($clearPrevious) {
            $user->sessions()->delete();
        }

        if (count($user->sessions) > 0) {
            $session = $user->sessions()->first();
            $session->update([
                'ip_address' => request()->getClientIp()
            ]);

            $token = $session->token;
        } else {
            $user->sessions()->save(new UserSession([
                'ip_address' => request()->getClientIp(),
                'token' => $token
            ]));
        }

        return ['token_value' => $token];
    }

    /**
     * Get session for token
     *
     * @param string $token
     * @return \App\Models\User|bool
     */
    public function getSession($token)
    {
        if (!is_null(static::$user)) {
            return static::$user;
        }

        $session = UserSession::where('token', $token)->first();
        if (!$session) {
            return false;
        }

        static::$user = $session->user;

        return static::$user;
    }

    /**
     * Generate token for user
     *
     * @param \App\Models\User $user
     * @return string
     */
    protected function generateToken(User $user)
    {
        return md5($user->username . $user->oid . microtime() . uniqid(rand(), true));
    }
}