<?php

namespace Myvetshop\Module\Clinique\Command\Clinic;

use Myvetshop\Module\Clinique\Adapter\Repository\GroupRepository;
use Myvetshop\Module\Clinique\Adapter\Repository\SpecificPriceRepository;
use Myvetshop\Module\Clinique\Entity\MyvetshopClinique;
use Myvetshop\Module\Clinique\Entity\MyvetshopTarifSpecifique;
use Myvetshop\Module\Clinique\Mapper\TarifSpecifique\TarifSpecifiqueToSpecificPriceMapper;
use Myvetshop\Module\Clinique\Repository\MyvetshopCliniqueRepository;
use Myvetshop\Module\Clinique\Repository\MyvetshopTarifSpecifiqueRepository;
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;

class ClinicTarifsRefreshCommand extends Command
{
    private GroupRepository $groupRepository;

    private MyvetshopCliniqueRepository $myvetshopCliniqueRepository;

    private MyvetshopTarifSpecifiqueRepository $myvetshopTarifSpecifiqueRepository;

    private SpecificPriceRepository $specificPriceRepository;

    private TarifSpecifiqueToSpecificPriceMapper $tarifSpecifiqueToSpecificPriceMapper;

    protected function configure(): void
    {
        $this
            ->addOption(
                'code-privilege',
                'c',
                InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
                'Code privilège'
            )
            ->setDescription('Mise à jour des tarifs privilège');
    }

    public function __construct(
        GroupRepository $groupRepository,
        MyvetshopCliniqueRepository $myvetshopCliniqueRepository,
        MyvetshopTarifSpecifiqueRepository $myvetshopTarifSpecifiqueRepository,
        SpecificPriceRepository $specificPriceRepository,
        TarifSpecifiqueToSpecificPriceMapper $tarifSpecifiqueToSpecificPriceMapper
    ) {
        parent::__construct('app:clinic:tarifs:refresh');

        $this->groupRepository = $groupRepository;
        $this->myvetshopCliniqueRepository = $myvetshopCliniqueRepository;
        $this->myvetshopTarifSpecifiqueRepository = $myvetshopTarifSpecifiqueRepository;
        $this->specificPriceRepository = $specificPriceRepository;
        $this->tarifSpecifiqueToSpecificPriceMapper = $tarifSpecifiqueToSpecificPriceMapper;
    }

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

        $styledOutput->title('Suppression des tarifs_specifiques inutiles');
        $this->myvetshopTarifSpecifiqueRepository->purgeOlds();

        $styledOutput->title('Suppression des specific_prices inutiles');
        $this->specificPriceRepository->purgeOlds();

        $styledOutput->title('Mise à jour des tarifs privilège');

        /** @var list<string>|null $codePrivileges */
        $codePrivileges = $input->getOption('code-privilege');
        if (!\is_array($codePrivileges)) {
            $codePrivileges = null;
        }

        if ($codePrivileges) {
            $cliniques = $this->myvetshopCliniqueRepository->findAllByPrivilegedCode($codePrivileges);
        } else {
            $cliniques = $this->myvetshopCliniqueRepository->findAllActive();
        }

        $codePrivilegesFinaux = \array_map(
            function (MyvetshopClinique $clinique) { return $clinique->codePrivilege; },
            $cliniques
        );
        $styledOutput->text(
            'Pour les codes privilèges suivant (' . \count($codePrivilegesFinaux) . ") :\n - "
                . \implode("\n - ", $codePrivilegesFinaux)
        );

        $groups = $this->groupRepository->findGroupsForClinics($cliniques);

        // Mise à jour des tarifs spécifiques pour les cliniques actives

        /** @var MyvetshopTarifSpecifique[] $tarifs */
        $tarifs = $this->myvetshopTarifSpecifiqueRepository->findAll();

        $progressBar = $styledOutput->createProgressBar(\count($tarifs));

        foreach ($tarifs as $tarif) {
            $progressBar->advance(1);

            try {
                $this->tarifSpecifiqueToSpecificPriceMapper
                    ->executeUpdateQueries(
                        $this->tarifSpecifiqueToSpecificPriceMapper->buildUpdateQueries($tarif, $groups)
                    );
            } catch (\Exception $e) {
                $styledOutput->error('Erreur durant le traitement du produit ' . $tarif->idProduct . ' : ' . $e->getMessage());
            }
        }

        $progressBar->finish();

        // Suppression des tarifs spécifiques associés à des cliniques désactivées

        $styledOutput->success('Fin de la génération');

        return 0;
    }
}
