<?php

declare(strict_types=1);

namespace App\Module\Mail\Infrastructure\Console;

use App\Module\Mail\Application\Service\MailSyncService;
use App\Module\Mail\Domain\Repository\MailConfigurationRepositoryInterface;
use App\Module\Mail\Domain\Repository\MailFolderRepositoryInterface;
use Symfony\Component\Console\Attribute\AsCommand;
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;

#[AsCommand(
    name: 'app:mail:sync',
    description: 'Synchronise la boîte mail partagée OVH (IMAP) vers la base locale',
)]
final class MailSyncCommand extends Command
{
    public function __construct(
        private readonly MailSyncService $mailSyncService,
        private readonly MailConfigurationRepositoryInterface $configRepository,
        private readonly MailFolderRepositoryInterface $folderRepository,
    ) {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->addOption(
                'folder',
                null,
                InputOption::VALUE_OPTIONAL,
                'Synchronise uniquement le dossier spécifié (ex: INBOX)',
            )
            ->addOption(
                'dry-run',
                null,
                InputOption::VALUE_NONE,
                'Simule la synchronisation sans écrire en base (lecture IMAP uniquement)',
            )
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        $config = $this->configRepository->findSingleton();

        if (null === $config || !$config->isEnabled()) {
            $io->info('Mail config disabled, skipping.');

            return Command::SUCCESS;
        }

        $isDryRun   = (bool) $input->getOption('dry-run');
        $folderPath = $input->getOption('folder');

        if ($isDryRun) {
            $io->note('Mode --dry-run activé : aucune écriture en base.');
            $io->success('Dry-run terminé — config IMAP active, aucune sync exécutée.');

            return Command::SUCCESS;
        }

        $io->text('Démarrage de la synchronisation mail...');
        $startTime = microtime(true);

        if (null !== $folderPath) {
            $folder = $this->folderRepository->findByPath((string) $folderPath);

            if (null === $folder) {
                $io->error(sprintf('Dossier "%s" introuvable en base — lance une sync complète au moins une fois.', $folderPath));

                return Command::FAILURE;
            }

            $io->text(sprintf('Synchronisation du dossier : %s', $folderPath));
            $report = $this->mailSyncService->syncFolder($folder);
        } else {
            $report = $this->mailSyncService->syncAll();
        }

        $elapsed = round(microtime(true) - $startTime, 2);

        $io->success(sprintf(
            'Sync terminée en %.1fs : %d créés, %d mis à jour, %d supprimés, %d dossiers scannés.',
            $elapsed,
            $report->createdCount,
            $report->updatedCount,
            $report->deletedCount,
            $report->foldersScanned,
        ));

        if ([] !== $report->errors) {
            $io->warning(sprintf('%d erreur(s) :', count($report->errors)));

            foreach ($report->errors as $error) {
                $io->text(' - '.$error);
            }
        }

        return [] === $report->errors ? Command::SUCCESS : Command::FAILURE;
    }
}
