<?php

namespace App\Repository;

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

/**
 * @method Equipement|null find($id, $lockMode = null, $lockVersion = null)
 * @method Equipement|null findOneBy(array $criteria, array $orderBy = null)
 * @method Equipement[]    findAll()
 * @method Equipement[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class EquipementRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Equipement::class);
    }

    public function getEquipementsForUpdatePrivileges($site, $equipementFamillesContrat) {
        $queryBuilder = $this->createQueryBuilder('e');
        $expr = $queryBuilder->expr();
        $queryBuilder
            ->andWhere('e.site = :site' )
            ->andWhere('e.actif = true')
            ->andWhere('e.privilege = false or e.privilege is null')
            ->andWhere($expr->in('e.equipement_famille_contrat',  ':equipementFamillesContrat'))
            ->setParameter('site', $site)
            ->setParameter('equipementFamillesContrat', $equipementFamillesContrat);

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

    }

    public function findByAdresse($datas) {
        $queryBuilder = $this->createQueryBuilder('e');
        $queryBuilder
            ->innerJoin('e.adresse', 'ea')
           // ->andWhere('e.actif = true')
            ->andWhere('e.client_souscripteur <> :client')->setParameter('client', $datas['id_souscripteur_search'])
            ->andWhere('LOWER(ea.adresse) LIKE LOWER(:adresse)')->setParameter('adresse','%'.$datas['adresse_equipement_search'].'%');

        if (isset($datas['code_postal_equipement_search']) && !empty($datas['code_postal_equipement_search']))
            $queryBuilder->andWhere('ea.code_postal = :code_postal')->setParameter('code_postal',$datas['code_postal_equipement_search']);
        if (isset($datas['ville_equipement_search']) && !empty($datas['ville_equipement_search']))
            $queryBuilder->andWhere('LOWER(ea.ville) LIKE LOWER(:ville)')->setParameter('ville','%'.$datas['ville_equipement_search'].'%');

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

    public function getEquipementAServir($latitude = null, $longitude = null, $distanceMaxKm = null){
        //nbAbs, nbV1V2
        //nbV1selonContrat MOD MOD2, GT GT2
        //Prendre tous les équipements sous contrat à l'instant T debutcontrat <= trunc(sysdate) && fincontrat >= trunc(sysdate)
        //rajouter les filtres : secteur, distance, etc...
        $queryBuilder = $this->createQueryBuilder('e');
        $now = new \DateTime();
        
        // Sous-requête pour trouver les équipements qui ont eu des interventions V1
        // On cherche par code ou par libellé contenant "V1"
        $subQuery = $this->createQueryBuilder('e2')
            ->select('e2.id')
            ->innerJoin('e2.interventions', 'i2')
            ->innerJoin('i2.type_planification', 'tp2')
            ->where('tp2.code = :v1_code OR tp2.libelle LIKE :v1_libelle')
            ->getDQL();
        
        $queryBuilder
            ->innerJoin('e.contrats', 'c')
            ->innerJoin('e.adresse', 'a')
            ->where('e.actif = true')
            ->andWhere('c.date_debut_contrat <= :now')
            ->andWhere('c.date_fin_contrat >= :now')
            ->andWhere('c.dernier_contrat = true')
            ->andWhere('e.id NOT IN (' . $subQuery . ')')
            ->setParameter('now', $now)
            ->setParameter('v1_code', 'V1')
            ->setParameter('v1_libelle', '%V1%');

        // Filtre par distance si les paramètres sont fournis
        if ($latitude !== null && $longitude !== null && $distanceMaxKm !== null) {
            // Formule de Haversine pour calculer la distance en kilomètres
            $haversineFormula = "
                6371 * acos(
                    cos(radians(:latitude)) * 
                    cos(radians(a.latitude)) * 
                    cos(radians(a.longitude) - radians(:longitude)) + 
                    sin(radians(:latitude)) * 
                    sin(radians(a.latitude))
                )
            ";
            
            $queryBuilder
                ->andWhere('a.latitude IS NOT NULL')
                ->andWhere('a.longitude IS NOT NULL')
                ->andWhere($haversineFormula . ' <= :distanceMax')
                ->setParameter('latitude', $latitude)
                ->setParameter('longitude', $longitude)
                ->setParameter('distanceMax', $distanceMaxKm);
        }

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