<?php

namespace PrestaShop\Module\PolarisPrestaConnector\Command;

use PrestaShop\Module\PolarisPrestaConnector\Syncer;
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 Symfony console pour lancer la synchronisation du catalogue.
 *
 * Usage :
 *   php bin/console prestaconnector:sync
 *   php bin/console prestaconnector:sync --full
 *
 * Reproduit exactement la logique de CronAdminController::cronAction(),
 * sans la couche HTTP (token guard, JsonResponse).
 *
 * La commande initialise elle-même le contexte Prestashop legacy
 * (employee admin, shop) de la même façon que le cron HTTP.
 */
/*#[AsCommand(
    name: 'prestaconnector:sync',
    description: 'Lance la synchronisation du catalogue PolarisPrestaConnector (équivalent du cron HTTP).'
)]*/
class SyncCommand extends Command
{
    public const FAILURE = 1;
    public const SUCCESS = 0;
    
    public function __construct(private readonly \PolarisPrestaConnector $module)
    {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this->setName(strtolower($this->module->getBridge()->getId()) . 'prestaconnector:sync');
        $this->setDescription('Lance la synchronisation du catalogue PolarisPrestaConnector (équivalent du cron HTTP).');
        $this
            ->addOption(
                'full',
                null,
                InputOption::VALUE_NONE,
                'Force une resynchronisation complète de tous les produits, stocks et clients ; par défaut, seule la synchronisation incrémentale est effectuée (produits modifiés depuis la dernière synchronisation).'
            );
    }

    protected function execute(InputInterface $input, OutputInterface $output) : int
    {
        $io = new SymfonyStyle($input, $output);
        $io->title('PolarisPrestaConnector — Synchronisation');

        // ── Initialisation du contexte Prestashop legacy ─────────────────────
        // Même logique que CronAdminController : on charge le premier employee
        // super-admin actif pour que les opérations Prestashop qui nécessitent
        // un contexte employee fonctionnent correctement.
        $context = \Context::getContext();

        if (!($context->employee instanceof \Employee) || !(int) $context->employee->id)
        {
            $idEmployee = \Db::getInstance()->getValue(
                'SELECT id_employee FROM ' . _DB_PREFIX_ . 'employee WHERE active = 1 AND id_profile = 1 ORDER BY id_employee ASC'
            );

            if (!$idEmployee)
            {
                $io->error('Aucun employé administrateur actif trouvé pour exécuter la synchronisation.');
                return self::FAILURE;
            }

            $context->employee = new \Employee((int) $idEmployee);
        }

        // Comme le cron HTTP, le contexte legacy de la CLI n'a pas de devise initialisée.
        // Order::getProducts() lit Context::getComputingPrecision() (=> currency->precision)
        // lors de l'export des commandes : on positionne donc la devise par défaut.
        if (!($context->currency instanceof \Currency) || !(int) $context->currency->id)
        {
            $context->currency = \Currency::getDefaultCurrency();
        }

        $io->text(sprintf(
            'Contexte initialisé — employee : %s %s (%s)',
            $context->employee->firstname,
            $context->employee->lastname,
            $context->employee->email
        ));

        // ── Lancement de la synchronisation ──────────────────────────────────
        $full = (bool) $input->getOption('full');
        $io->text($full ? 'Mode : resynchronisation complète.' : 'Mode : synchronisation incrémentale.');
        $io->newLine();

        $syncer = new Syncer($this->module, true);

        try
        {
            // On redirige les echo de audit() vers OutputInterface en temps réel
            // grâce à un handler de buffer de sortie avec chunk_size=1 :
            // chaque echo déclenche immédiatement le callback.
            ob_start(function (string $chunk) use ($output): string {
                foreach (explode("\n", rtrim($chunk, "\n")) as $line)
                    if ($line !== '')
                        $output->writeln('  ' . $line);
                return '';  // ne rien laisser dans le buffer
            }, 1);

            $reason = $syncer->sync($full);

            ob_end_clean();
        }
        catch (\Exception $e)
        {
            ob_end_clean();
            $io->error('Exception : ' . $e->getMessage());
            return self::FAILURE;
        }

        // ── Résultat ──────────────────────────────────────────────────────────
        if ($reason === null)
        {
            $io->success('Synchronisation terminée avec succès.');
            return self::SUCCESS;
        }

        switch ($reason)
        {
            case 'ALREADY_RUNNING':
                $io->warning('Une synchronisation est déjà en cours.');
                return self::SUCCESS;

            case 'DISABLED':
                $io->warning('La synchronisation est désactivée dans la configuration.');
                return self::SUCCESS;

            default:
                $io->error('Échec : ' . $reason);
                return self::FAILURE;
        }
    }
}

