<?php

declare(strict_types=1);

namespace App\Administration\Application\Service\Import;

use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
use App\Shared\Domain\Tenant\TenantId;
use Doctrine\DBAL\Connection;

/**
 * Charge les élèves existants d'un tenant pour une année scolaire,
 * avec leur affectation de classe, afin de détecter les doublons à l'import.
 */
final readonly class ExistingStudentFinder
{
    public function __construct(
        private Connection $connection,
    ) {
    }

    /**
     * @return list<array{firstName: string, lastName: string, email: ?string, studentNumber: ?string, className: ?string}>
     */
    public function findAllForTenant(TenantId $tenantId, AcademicYearId $academicYearId): array
    {
        $sql = <<<'SQL'
            SELECT u.first_name, u.last_name, u.email, u.student_number, sc.name AS class_name
            FROM users u
            LEFT JOIN class_assignments ca ON ca.user_id = u.id AND ca.academic_year_id = :academic_year_id
            LEFT JOIN school_classes sc ON sc.id = ca.school_class_id
            WHERE u.tenant_id = :tenant_id
              AND u.roles::jsonb @> :role
            SQL;

        /** @var list<array{first_name: string, last_name: string, email: ?string, student_number: ?string, class_name: ?string}> $rows */
        $rows = $this->connection->fetchAllAssociative($sql, [
            'tenant_id' => (string) $tenantId,
            'academic_year_id' => (string) $academicYearId,
            'role' => '"ROLE_ELEVE"',
        ]);

        return array_map(
            static fn (array $row) => [
                'firstName' => $row['first_name'],
                'lastName' => $row['last_name'],
                'email' => $row['email'],
                'studentNumber' => $row['student_number'],
                'className' => $row['class_name'],
            ],
            $rows,
        );
    }
}
