<?php

namespace App\Repository;

use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @extends ServiceEntityRepository<User>
 */
class UserRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, User::class);
    }

    public function findOneByEmail(string $email): ?User
    {
        return $this->findOneBy(['email' => $email]);
    }

    /** Nombre de demandes d'accès en attente de validation. */
    public function countPending(): int
    {
        return (int) $this->createQueryBuilder('u')
            ->select('COUNT(u.id)')
            ->andWhere('u.status = :st')
            ->setParameter('st', User::STATUS_PENDING)
            ->getQuery()
            ->getSingleScalarResult();
    }

    /**
     * @return User[]
     */
    public function findByStatus(string $status): array
    {
        return $this->createQueryBuilder('u')
            ->andWhere('u.status = :st')
            ->setParameter('st', $status)
            ->orderBy('u.createdAt', 'DESC')
            ->getQuery()
            ->getResult();
    }

    /**
     * Utilisateurs ayant un rôle donné (LIKE sur la colonne JSON `roles`).
     *
     * @return User[]
     */
    public function findByRole(string $role): array
    {
        return $this->createQueryBuilder('u')
            ->andWhere('u.roles LIKE :role')
            ->setParameter('role', '%"' . $role . '"%')
            ->getQuery()
            ->getResult();
    }

    /**
     * Emails des utilisateurs actifs habilités à valider (ADMIN ou AUDIT).
     *
     * @return list<string>
     */
    public function findValidatorEmails(): array
    {
        $rows = $this->createQueryBuilder('u')
            ->select('u.email')
            ->andWhere('u.status = :active')
            ->andWhere('u.roles LIKE :admin OR u.roles LIKE :audit')
            ->setParameter('active', User::STATUS_ACTIVE)
            ->setParameter('admin', '%"' . User::ROLE_ADMIN . '"%')
            ->setParameter('audit', '%"' . User::ROLE_AUDIT . '"%')
            ->getQuery()
            ->getScalarResult();

        return array_values(array_map(static fn (array $r) => (string) $r['email'], $rows));
    }

    /**
     * Tous les utilisateurs, triés (en attente d'abord, puis par date).
     *
     * @return User[]
     */
    public function findAllOrdered(): array
    {
        return $this->createQueryBuilder('u')
            ->orderBy('u.status', 'ASC')
            ->addOrderBy('u.createdAt', 'DESC')
            ->getQuery()
            ->getResult();
    }
}
