<?php

namespace App\Command;

use App\Entity\Equipement;
use App\Service\EquipementManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * Commande pour mettre à jour quotidiennement le flag a_servir
 * Cette commande doit être exécutée via cron tous les jours
 * 
 * Exemple de configuration cron :
 * 0 2 * * * cd /path/to/project && php bin/console app:update-a-servir-flag-daily
 */
class UpdateAServirFlagDailyCommand extends Command
{
    protected static $defaultName = 'app:update-a-servir-flag-daily';

    private EntityManagerInterface $entityManager;
    private EquipementManager $equipementManager;

    public function __construct(EntityManagerInterface $em, EquipementManager $equipementManager)
    {
        parent::__construct();
        $this->entityManager = $em;
        $this->equipementManager = $equipementManager;
    }

    protected function configure(): void
    {
        $this
            ->setDescription('Met à jour le flag a_servir pour tous les équipements (à exécuter quotidiennement)')
            ->addOption(
                'all',
                'a',
                InputOption::VALUE_NONE,
                'Mettre à jour tous les équipements (par défaut, seulement ceux avec contrat actif ou récemment expiré)'
            )
            ->addOption(
                'days',
                'd',
                InputOption::VALUE_OPTIONAL,
                'Nombre de jours dans le passé à considérer pour les contrats expirés',
                30
            );
    }

    protected function initialize(InputInterface $input, OutputInterface $output): void
    {
        // Augmenter la limite de mémoire pour traiter beaucoup d'équipements
        ini_set('memory_limit', '-1');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
        $io->title('Mise à jour quotidienne du flag a_servir');

        $updateAll = $input->getOption('all');
        $days = (int) $input->getOption('days');

        if ($updateAll) {
            // Mettre à jour tous les équipements
            $io->info('Mode : Mise à jour de tous les équipements');
            $equipements = $this->entityManager->getRepository(Equipement::class)->findAll();
        } else {
            // Optimisation : ne traiter que les équipements qui pourraient avoir changé
            // (ceux avec un contrat actif ou récemment expiré)
            $io->info("Mode : Mise à jour des équipements avec contrat actif ou expiré dans les {$days} derniers jours");
            
            $now = new \DateTime();
            $pastDate = clone $now;
            $pastDate->modify("-{$days} days");
            
            $queryBuilder = $this->entityManager->getRepository(Equipement::class)->createQueryBuilder('e');
            $queryBuilder
                ->innerJoin('e.contrats', 'c')
                ->where('e.actif = true')
                ->andWhere('c.date_debut_contrat <= :now')
                ->andWhere('c.date_fin_contrat >= :pastDate') // Contrats actifs ou récemment expirés
                ->andWhere('c.dernier_contrat = true')
                ->setParameter('now', $now)
                ->setParameter('pastDate', $pastDate);
            
            $equipements = $queryBuilder->getQuery()->getResult();
        }

        $total = count($equipements);
        
        if ($total === 0) {
            $io->warning('Aucun équipement à traiter');
            return Command::SUCCESS;
        }

        $io->progressStart($total);
        $io->info("Traitement de {$total} équipements...");

        $updated = 0;
        $changed = 0;
        $batchSize = 100;
        $batchCount = 0;
        $aServir = 0;

        foreach ($equipements as $equipement) {

            //if($equipement->getId() == 125220) {
                // Sauvegarder l'ancienne valeur pour détecter les changements
                $oldValue = $equipement->getAServir();

                // Calculer et mettre à jour le flag
                $res = $this->equipementManager->updateAServirFlag($equipement);
                if ($res) {
                    $aServir++;
                }
                // Compter les changements
                if ($oldValue !== $equipement->getAServir()) {
                    $changed++;
                }

                $updated++;
                $batchCount++;

                // Flush par batch pour optimiser les performances
                if ($batchCount >= $batchSize) {
                    $this->entityManager->flush();
                    $batchCount = 0;
                }

                $io->progressAdvance();
            //}
        }

        // Flush final
        if ($batchCount > 0) {
            $this->entityManager->flush();
        }

        $io->progressFinish();
        $io->success([
            "Mise à jour terminée :",
            "- {$updated} équipements traités",
            "- {$changed} équipements avec changement de statut",
            "- {$aServir} équipements à servir"
        ]);

        return Command::SUCCESS;
    }
}

