<?php

namespace App\Command;

use App\Entity\Domain;
use App\Service\MailerService;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Twig\Environment;

#[AsCommand(
    name: 'app:ndd:check',
    description: 'Verifie les dates expiration des noms de domaine et envoie un mail groupe (<= 30 jours)',
)]
class CheckNddCommand extends Command
{
    private const EXPIRATION_THRESHOLD_DAYS = 30;
    private const MONITOR_EMAIL = 'notification@e-cosplay.fr';

    public function __construct(
        private EntityManagerInterface $em,
        private MailerService $mailer,
        private Environment $twig,
        private LoggerInterface $logger,
    ) {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
        $io->title('Verification expiration des noms de domaine');

        $now = new \DateTimeImmutable();
        $limit = $now->modify('+'.self::EXPIRATION_THRESHOLD_DAYS.' days');

        /** @var Domain[] $domains */
        $domains = $this->em->createQueryBuilder()
            ->select('d')
            ->from(Domain::class, 'd')
            ->where('d.expiredAt IS NOT NULL')
            ->andWhere('d.expiredAt <= :limit')
            ->orderBy('d.expiredAt', 'ASC')
            ->setParameter('limit', $limit)
            ->getQuery()
            ->getResult();

        $items = [];
        foreach ($domains as $domain) {
            $customer = $domain->getCustomer();
            $diff = $now->diff($domain->getExpiredAt());
            $days = (int) $diff->format('%r%a');
            $items[] = [
                'fqdn' => $domain->getFqdn(),
                'registrar' => $domain->getRegistrar(),
                'customerName' => $customer->getFullName(),
                'customerEmail' => $customer->getEmail(),
                'expiredAt' => $domain->getExpiredAt(),
                'daysLeft' => $days,
                'isExpired' => $days < 0,
            ];
            $io->text(sprintf('  %s -> %s (%d j)', $domain->getFqdn(), $customer->getEmail() ?? '-', $days));
        }

        if ([] === $items) {
            $subject = 'Nom de domaine - Aucune expiration prochaine';
            $message = 'Aucun nom de domaine en expiration.';
        } else {
            $subject = 'Nom de domaine - '.\count($items).' expiration(s) prochaine(s)';
            $message = null;
        }

        try {
            $html = $this->twig->render('emails/ndd_expiration.html.twig', [
                'domains' => $items,
                'message' => $message,
                'thresholdDays' => self::EXPIRATION_THRESHOLD_DAYS,
            ]);

            $this->mailer->sendEmail(
                self::MONITOR_EMAIL,
                $subject,
                $html,
                null,
                null,
                false,
            );
        } catch (\Throwable $e) {
            $this->logger->error('CheckNdd: erreur envoi mail: '.$e->getMessage());
            $io->error('Erreur envoi mail : '.$e->getMessage());

            return Command::FAILURE;
        }

        if ([] === $items) {
            $io->success('Aucun nom de domaine en expiration. Rapport envoye a '.self::MONITOR_EMAIL);
        } else {
            $io->success(\count($items).' domaine(s) en expiration. Rapport envoye a '.self::MONITOR_EMAIL);
        }

        return Command::SUCCESS;
    }
}
