<?php

use App\Services\PersistentLoginService;
use CodeIgniter\Cookie\Cookie;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
use Tests\Support\Auth\AuthTestTrait;

/**
 * @internal
 */
final class ProductionFlowTest extends CIUnitTestCase
{
    use DatabaseTestTrait;
    use FeatureTestTrait;
    use AuthTestTrait;

    protected $namespace = 'App';
    protected $refresh   = true;
    protected $migrate   = true;
    protected $seed      = '';

    /**
     * @param array<string, mixed> $user
     *
     * @return array<string, mixed>
     */
    private function authSession(array $user): array
    {
        return [
            'user_id'                      => (int) $user['id'],
            'email'                        => (string) $user['email'],
            'profile_onboarding_completed' => (int) $user['profile_onboarding_completed'],
        ];
    }

    public function testUnauthenticatedProtectedScreensRedirectToSignIn(): void
    {
        foreach ([
            'dashboard',
            'analytics',
            'notifications',
            'support',
            'settings',
            'categories',
            'tasks/create',
            'tasks/search',
        ] as $path) {
            $this->withSession([])->get($path)->assertRedirectTo('/sign-in');
        }
    }

    public function testAuthenticatedScreensSendNoStoreCacheHeaders(): void
    {
        $user    = $this->createUser('cache-headers@example.com', 1);
        $session = $this->authSession($user);

        foreach (['dashboard', 'analytics', 'notifications', 'settings', 'support'] as $path) {
            $page = $this->withSession($session)->get($path);
            $page->assertOK();
            $this->assertStringContainsString('no-store', $page->response()->getHeaderLine('Cache-Control'));
        }
    }

    public function testOtpPageRendersSixBoxesAndNoPasswordField(): void
    {
        $page = $this->withSession(['otp_email' => 'six-boxes@example.com'])->get('auth/verify-otp');
        $page->assertOK();
        $body = (string) $page->response()->getBody();
        $this->assertSame(6, substr_count($body, 'class="otp-box"'));
        $this->assertStringNotContainsString('type="password"', $body);
        $this->assertStringNotContainsString('name="password"', $body);
    }

    public function testRootUnauthenticatedGoesToSignIn(): void
    {
        $this->withSession([])->get('/')->assertRedirectTo('/sign-in');
    }

    public function testSecureCookieFlagFollowsCookieConfig(): void
    {
        $user = $this->createUser('secure-cookie@example.com', 1);
        $cookieConfig = config('Cookie');
        $previous     = $cookieConfig->secure;
        $cookieConfig->secure = true;
        try {
            (new PersistentLoginService())->issueToken((int) $user['id']);
            $cookie = service('response')->getCookie($this->rememberCookieName());
            $this->assertInstanceOf(Cookie::class, $cookie);
            $this->assertTrue($cookie->isSecure());
            $this->assertTrue($cookie->isHTTPOnly());
        } finally {
            $cookieConfig->secure = $previous;
        }
    }
}
