<?php declare(strict_types=1);
/**
 * This file is part of the SplendidBear Websites' projects.
 *
 * Copyright (c) 2026 @ www.splendidbear.org
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace App\Tests\Controller;

use App\Tests\Factory\UserFactory;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\TestDox;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use App\Tests\WebTestCase;
use Symfony\Component\HttpFoundation\Response;

/**
 * Class SecurityControllerTest
 *
 * @package  App\Tests\Controller
 * @author   Lang <https://www.splendidbear.org>
 * @category Class
 * @license  https://www.gnu.org/licenses/lgpl-3.0.en.html GNU Lesser General Public License
 * @link     www.splendidbear.org
 * @since    2026. 04. 21.
 */
#[TestDox('Security Controller')]
class SecurityControllerTest extends WebTestCase
{
    private KernelBrowser $client;

    protected function setUp(): void
    {
        parent::setUp();
        $this->client = static::createClient();
    }

    #[Test]
    #[TestDox('Login page loads successfully with form fields')]
    public function loginPageLoadsSuccessfully(): void
    {
        $crawler = $this->client->request('GET', '/login');

        self::assertResponseStatusCodeSame(Response::HTTP_OK);
        self::assertSelectorExists('form');
        self::assertSelectorExists('input[name="_username"]');
        self::assertSelectorExists('input[name="_password"]');
        self::assertSelectorExists('button[type="submit"]');
    }

    #[Test]
    #[TestDox('Login page has links to register and forgot password')]
    public function loginPageHasRegisterLink(): void
    {
        $crawler = $this->client->request('GET', '/login');

        self::assertResponseIsSuccessful();
        self::assertSelectorExists('a[href="/register"]');
        self::assertSelectorExists('a[href="/forgot-password"]');
    }

    #[Test]
    #[TestDox('Register page loads successfully with form')]
    public function registerPageLoadsSuccessfully(): void
    {
        $crawler = $this->client->request('GET', '/register');

        self::assertResponseStatusCodeSame(Response::HTTP_OK);
        self::assertSelectorExists('form');
        self::assertSelectorExists('button[type="submit"]');
    }

    #[Test]
    #[TestDox('Register page has link to login')]
    public function registerPageHasLoginLink(): void
    {
        $crawler = $this->client->request('GET', '/register');

        self::assertResponseIsSuccessful();
        self::assertSelectorExists('a[href="/login"]');
    }

    #[Test]
    #[TestDox('Forgot password page loads successfully with form')]
    public function forgotPasswordPageLoadsSuccessfully(): void
    {
        $crawler = $this->client->request('GET', '/forgot-password');

        self::assertResponseStatusCodeSame(Response::HTTP_OK);
        self::assertSelectorExists('form');
        self::assertSelectorExists('button[type="submit"]');
    }

    #[Test]
    #[TestDox('Account activation with invalid token redirects to login')]
    public function activateWithInvalidTokenShowsError(): void
    {
        $this->client->request('GET', '/activate/invalid-token');

        self::assertResponseRedirects('/login');
    }

    #[Test]
    #[TestDox('Password reset with invalid token redirects to forgot password')]
    public function resetPasswordWithInvalidTokenShowsError(): void
    {
        $this->client->request('GET', '/reset-password/invalid-token');

        self::assertResponseRedirects('/forgot-password');
    }

    #[Test]
    #[TestDox('Authenticated user is redirected from login page to homepage')]
    public function authenticatedUserRedirectsFromLogin(): void
    {
        $user = UserFactory::createOne();
        $this->client->loginUser($user->_real());

        $this->client->request('GET', '/login');

        self::assertResponseRedirects('/');
    }

    #[Test]
    #[TestDox('Authenticated user is redirected from register page to homepage')]
    public function authenticatedUserRedirectsFromRegister(): void
    {
        $user = UserFactory::createOne();
        $this->client->loginUser($user->_real());

        $this->client->request('GET', '/register');

        self::assertResponseRedirects('/');
    }

    #[Test]
    #[TestDox('Login form has remember me checkbox')]
    public function loginFormHasRememberMeCheckbox(): void
    {
        $crawler = $this->client->request('GET', '/login');

        self::assertResponseIsSuccessful();
        self::assertSelectorExists('input[name="_remember_me"]');
    }
}
