<?php

namespace Tests\App\Services;

use App\Models\SchoolYearModel;
use App\Services\SchoolYearContextService;
use CodeIgniter\HTTP\URI;
use CodeIgniter\HTTP\UserAgent;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\Mock\MockIncomingRequest;
use Config\App;

final class SchoolYearContextRequest extends MockIncomingRequest
{
    public function __construct(private readonly array $gets = [])
    {
        parent::__construct(config(App::class), new URI('https://test.alrahmaisgl.org'), 'php://input', new UserAgent());
    }

    public function getGet($key = null, $filter = null, $default = null)
    {
        if ($key === null) {
            return $this->gets;
        }

        return $this->gets[$key] ?? $default;
    }
}

final class SchoolYearContextFakeModel extends SchoolYearModel
{
    public function __construct(private readonly array $rows)
    {
    }

    public function find($id = null)
    {
        return $this->rows[(int) $id] ?? null;
    }

    public function active(): ?array
    {
        foreach ($this->rows as $row) {
            if (($row['status'] ?? '') === 'active') {
                return $row;
            }
        }

        return null;
    }
}

final class SchoolYearContextServiceTest extends CIUnitTestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        if (method_exists(session(), 'isStarted') && ! session()->isStarted()) {
            session()->start();
        }
    }

    public function testClosedSessionSelectionIsRetainedAsExplicitReadonlyContext(): void
    {
        session()->set('selected_school_year_id', 1);

        $service = new SchoolYearContextService(new SchoolYearContextFakeModel([
            1 => ['id' => 1, 'name' => '2025-2026', 'status' => 'closed'],
            2 => ['id' => 2, 'name' => '2026-2027', 'status' => 'active'],
        ]));

        $context = $service->resolve(new SchoolYearContextRequest());

        $this->assertSame(1, $context->id());
        $this->assertSame('2025-2026', $context->yearName());
        $this->assertTrue($context->isReadonly());
        $this->assertTrue($context->isExplicitSelection());
        $this->assertSame(1, session()->get('selected_school_year_id'));
    }

    public function testInvalidSessionSelectionFallsBackToActiveYearAndClearsSession(): void
    {
        session()->set('selected_school_year_id', 99);

        $service = new SchoolYearContextService(new SchoolYearContextFakeModel([
            2 => ['id' => 2, 'name' => '2026-2027', 'status' => 'active'],
        ]));

        $context = $service->resolve(new SchoolYearContextRequest());

        $this->assertSame(2, $context->id());
        $this->assertSame('2026-2027', $context->yearName());
        $this->assertNull(session()->get('selected_school_year_id'));
    }

    public function testSelectingActiveYearClearsHistoricalOverride(): void
    {
        session()->set('selected_school_year_id', 1);
        session()->set('class_section_id', 44);
        session()->set('semester', 'Fall');
        session()->set('active_school_year', '2025-2026');

        $service = new SchoolYearContextService(new SchoolYearContextFakeModel([
            1 => ['id' => 1, 'name' => '2025-2026', 'status' => 'closed'],
            2 => ['id' => 2, 'name' => '2026-2027', 'status' => 'Active'],
        ]));

        $context = $service->select(2);

        $this->assertSame(2, $context->id());
        $this->assertTrue($context->isActive());
        $this->assertFalse($context->isExplicitSelection());
        $this->assertNull(session()->get('selected_school_year_id'));
        $this->assertNull(session()->get('class_section_id'));
        $this->assertNull(session()->get('semester'));
        $this->assertNull(session()->get('active_school_year'));
    }
}
