<?php

namespace App\Auth;

use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;

/**
 * Xenforo authentification bridge.
 */
class XenForoGuard implements Guard
{

    /**
     * Authenticated user.
     * @var XenForoUser|null
     */
    private ?XenForoUser $user = null;

    public function __construct(private readonly Request $request) {}

    /**
     * Check if user is logged in.
     * @return bool
     */
    public function check(): bool
    {
        return $this->user() !== null;
    }

    /**
     * Check if user is a guest.
     * @return bool
     */
    public function guest(): bool
    {
        return ! $this->check();
    }

    /**
     * Get user ID.
     * @return mixed
     */
    public function id(): mixed
    {
        return $this->user()?->getAuthIdentifier();
    }

    /**
     * If user is defined.
     * @return bool
     */
    public function hasUser(): bool
    {
        return $this->user !== null;
    }

    /**
     * Login user.
     * @return XenForoUser|null
     */
    public function user(): ?XenForoUser
    {
        if ($this->hasUser())
            return $this->user;

        $sessionId = $this->request->cookie('xf_session');
        if(!$sessionId)
            return null;

        $xfSession = \DB::connection('xenforo')
            ->table('session')
            ->where('session_id', $sessionId)
            ->value('session_data');

        if(!$xfSession)
            return null;

        $sessionData = unserialize($xfSession);

        if (!$sessionData || !isset($sessionData['userId']) || !$sessionData['userId'])
            return null;

        $xfUser = \DB::connection('xenforo')
            ->table('user')
            ->where('user_id', $sessionData['userId'])
            ->first();

        if(!$xfUser)
            return null;

        return $this->user = new XenForoUser($xfUser);
    }

    /**
     * Unused.
     *
     * @param array $credentials
     *
     * @return bool
     */
    public function validate(array $credentials = []): bool
    {
        return false;
    }

    public function setUser(mixed $user): void
    {
        $this->user = $user;
    }

    /**
     * Unused.
     * @return void
     */
    public function logout(): void
    {
        redirect('/');
    }

}
