<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace App\Repository;

use App\Entity\Utilisateur;
use App\Entity\UtilisateurProfil;
use App\Entity\UtilisateurRole;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * This custom Doctrine repository is empty because so far we don't need any custom
 * method to query for application user information. But it's always a good practice
 * to define a custom repository that will be used when the application grows.
 *
 * See https://symfony.com/doc/current/doctrine.html#querying-for-objects-the-repository
 *
 * @author Ryan Weaver <weaverryan@gmail.com>
 * @author Javier Eguiluz <javier.eguiluz@gmail.com>
 */
class UtilisateurRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Utilisateur::class);
    }

    public function getSubordonneeAvailable(Utilisateur $utilisateur) {
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();

        return $queryBuilder
            ->where($expr->notIn('u',  ':user'))
            ->andWhere($expr->notIn('u',  ':sub'))
            ->andWhere('u.responsable is null')
            ->setParameter('user', $utilisateur)
            ->setParameter('sub', $utilisateur->getUtilisateurs())
            ->getQuery()
            ->getResult()
            ;
    }

    public function getUtilisateursWithNotIn($usersNotIn) {
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();

        return $queryBuilder
            ->where($expr->notIn('u',  ':users'))
            ->setParameter('users', $usersNotIn)
            ->getQuery()
            ->getResult()
            ;
    }

    public function getAgents() {
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();
//        return $queryBuilder
//            ->leftJoin('u.utilisateurAffectations', 'ua')
//            ->innerJoin('ua.utilisateur_profil', 'up')
//            ->where('ua.actif = true')
//            ->andWhere($expr->in('up.id',  ':ids'))
//            ->setParameter('ids', [UtilisateurProfil::ID_AGENT, UtilisateurProfil::ID_RESPONSABLE_SECTEUR])
//            ->getQuery()
//            ->getResult()
//            ;
        return $queryBuilder
            ->innerJoin('u.role', 'ur')
            ->andWhere($expr->in('ur.id',  ':ids'))
            ->setParameter('ids', [
                UtilisateurRole::ID_AGENT,
                UtilisateurRole::ID_RESPONSABLE_SECTEUR,
                UtilisateurRole::ID_AGENT_PLANNING,
                UtilisateurRole::ID_RENSEIGNEMENT_TECHNIQUE,
                UtilisateurRole::ID_REPONSABLE_AGENT_PLANNING,
                UtilisateurRole::ID_ROLE_RESPONSABLE_TECHNIQUE,
            ])
            ->getQuery()
            ->getResult()
            ;
    }

    public function countAgents() {
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();
        return $queryBuilder
            ->select('count(u.id)')
            ->innerJoin('u.utilisateurAffectations', 'ua')
            ->innerJoin('ua.utilisateur_profil', 'up')
            ->where('ua.actif = true')
            ->andWhere($expr->in('up.id',  ':ids'))
            ->setParameter('ids', [UtilisateurProfil::ID_AGENT, UtilisateurProfil::ID_RESPONSABLE_SECTEUR])
            ->getQuery()
            ->getSingleScalarResult()
            ;
    }

    public function getUtilisateursPlanning() {
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();
        return $queryBuilder
            ->innerJoin('u.utilisateurAffectations', 'ua')
            ->innerJoin('ua.utilisateur_profil', 'up')
            ->where('ua.actif = true')
            ->andWhere('u.actif = true')
            ->andWhere($expr->in('up.id',  ':ids'))
            ->setParameter('ids', [UtilisateurProfil::ID_PLANNING, UtilisateurProfil::ID_POLY_PLANNING])
            ->getQuery()
            ->getResult()
            ;
    }

    public function getUtilisateursResponsable($sites = null) {
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();
        $queryBuilder
            ->select('u', 'ua')
            ->addSelect("CAST(SUBSTRING(u.code_agent, 2) AS int) AS HIDDEN code_agent_numeric")
            ->innerJoin('u.utilisateurAffectations', 'ua', 'WITH', 'ua.actif = true')
            ->innerJoin('ua.utilisateur_profil', 'up')
            ->andWhere('u.actif = true')
            ->andWhere($expr->in('up.id',  ':ids'))
            ->setParameter('ids', [UtilisateurProfil::ID_RESPONSABLE_SECTEUR])
            ->orderBy('code_agent_numeric', 'ASC');

            // Si $sites est fourni, on ajoute le filtre sur les sites
        if ($sites !== null && count($sites) > 0) {
        $queryBuilder
            ->innerJoin('u.utilisateurSites', 'us')
            ->andWhere($expr->in('us.site', ':sites'))
            ->setParameter('sites', $sites);
        }

        return $queryBuilder->getQuery()->getResult();
    }

    public function getAgentsCarto($groupes) {
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();

        $subQuery = $this->getEntityManager()->createQueryBuilder()
            ->select('MAX(ag2.date_heure)')
            ->from('App\Entity\AgentGps', 'ag2')
            ->where('ag2.utilisateur_agent = u.id');

        return $queryBuilder
            ->select('u', 'ag')
            ->addSelect("CAST(SUBSTRING(u.code_agent, 2) AS int) AS HIDDEN code_agent_numeric")
            ->innerJoin('u.utilisateurSites', 'us')
            ->innerJoin('u.role', 'ur')
            ->innerJoin('u.groupesUtilisateur', 'gu')
            ->leftJoin('u.agentGps', 'ag', 'WITH', 'ag.date_heure = (' . $subQuery->getDQL() . ')')
            ->andWhere('u.actif = true')
            ->andWhere($expr->in('ur.id',  ':ids'))
            ->andWhere($expr->in('gu.groupe',  ':groupes'))
            ->setParameter('ids', [UtilisateurRole::ID_AGENT, UtilisateurRole::ID_RESPONSABLE_SECTEUR])
            ->setParameter('groupes', $groupes)
            ->orderBy('code_agent_numeric', 'ASC')
            ->getQuery()
            ->getResult();
    }

    public function getAgentsSousResponsable($responsable) {
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();
        return $queryBuilder
            ->select('u')
            ->addSelect("CAST(SUBSTRING(u.code_agent, 2) AS int) AS HIDDEN code_agent_numeric")
            ->innerJoin('u.utilisateurAffectations', 'ua', 'WITH', 'ua.actif = true')
            ->innerJoin('ua.utilisateur_profil', 'up')
            ->andwhere('ua.utilisateur_reponsable = :responsable')
            ->andWhere($expr->in('up.id',  ':ids'))
            ->setParameter('ids', [UtilisateurProfil::ID_AGENT, UtilisateurProfil::ID_RESPONSABLE_SECTEUR])
            ->setParameter('responsable', $responsable)
            ->orderBy('code_agent_numeric', 'ASC')
            ->getQuery()
            ->getResult()
            ;
    }

    /**
     * Récupère les agents inactifs
     * 
     * @return array
     */
    public function getAgentsInactifs()
    {
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();
        return $queryBuilder
            ->select('u')
            ->innerJoin('u.role', 'ur')
            ->andWhere('u.actif = false')
            ->andWhere($expr->in('ur.id', ':ids'))
            ->setParameter('ids', [UtilisateurRole::ID_AGENT, UtilisateurRole::ID_RESPONSABLE_SECTEUR])
            ->orderBy('u.nom', 'ASC')
            ->addOrderBy('u.prenom', 'ASC')
            ->getQuery()
            ->getResult();
    }

    public function getUtilisateursAgent($sites = null){
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();
        $queryBuilder
            ->select('u', 'ua')
            ->innerJoin('u.utilisateurAffectations', 'ua', 'WITH', 'ua.actif = true')
            ->innerJoin('ua.utilisateur_profil', 'up')
            ->andWhere('u.actif = true')
            ->andWhere($expr->in('up.id',  ':ids'))
            ->setParameter('ids', [UtilisateurProfil::ID_AGENT]);

        // Si $sites est fourni, on ajoute le filtre sur les sites
        if ($sites !== null && count($sites) > 0) {
            $queryBuilder
                ->innerJoin('u.utilisateurSites', 'us')
                ->andWhere($expr->in('us.site', ':sites'))
                ->setParameter('sites', $sites);
        }

        return $queryBuilder->getQuery()->getResult();
    }

    public function getAgentIdNomByRole($roles){
        $queryBuilder = $this->createQueryBuilder('u');
        $expr = $queryBuilder->expr();

        return $queryBuilder
            ->select('u.nom as value,u.nom as text')
            ->innerJoin('u.role', 'ur')
            ->andWhere($expr->in('ur.id',  ':ids'))
            ->setParameter('ids', $roles)
            ->orderBy('u.nom', 'ASC')
            ->getQuery()
            ->getArrayResult();
            ;
    }
}