<?php

namespace App\Command;

use App\Entity\Customer;
use App\Repository\CustomerRepository;
use App\Service\MeilisearchService;
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 Symfony\Component\DependencyInjection\Attribute\Autowire;

#[AsCommand(
    name: 'app:clean:pending-delete',
    description: 'Supprime les clients en attente de suppression (state = pending_delete)',
)]
class CleanPendingDeleteCommand extends Command
{
    public function __construct(
        private CustomerRepository $customerRepository,
        private EntityManagerInterface $em,
        private MeilisearchService $meilisearch,
        private LoggerInterface $logger,
        #[Autowire(env: 'STRIPE_SK')] private string $stripeSecretKey = '',
    ) {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
        $io->title('Nettoyage des clients en attente de suppression');

        $customers = $this->customerRepository->findBy(['state' => Customer::STATE_PENDING_DELETE]);

        if ([] === $customers) {
            $io->success('Aucun client en attente de suppression.');

            return Command::SUCCESS;
        }

        $io->text(\count($customers).' client(s) a supprimer.');
        $deleted = 0;

        foreach ($customers as $customer) {
            $name = $customer->getFullName();
            $email = $customer->getEmail();

            $this->deleteFromStripe($customer);
            $this->deleteFromMeilisearch($customer);

            $user = $customer->getUser();
            $this->em->remove($customer);
            $this->em->remove($user);
            $this->em->flush();

            $this->logger->info('CleanPendingDelete: client supprime '.$email.' ('.$name.')');
            $io->text('  Supprime : '.$name.' ('.$email.')');
            ++$deleted;
        }

        $io->success($deleted.' client(s) supprime(s).');

        return Command::SUCCESS;
    }

    private function deleteFromStripe(Customer $customer): void
    {
        if ('' === $this->stripeSecretKey || 'sk_test_***' === $this->stripeSecretKey) {
            return;
        }

        if (null === $customer->getStripeCustomerId()) {
            return;
        }

        try { // @codeCoverageIgnoreStart
            \Stripe\Stripe::setApiKey($this->stripeSecretKey);
            \Stripe\Customer::retrieve($customer->getStripeCustomerId())->delete();
        } catch (\Throwable $e) {
            $this->logger->warning('CleanPendingDelete: erreur Stripe '.$customer->getEmail().': '.$e->getMessage());
        } // @codeCoverageIgnoreEnd
    }

    private function deleteFromMeilisearch(Customer $customer): void
    {
        try {
            $this->meilisearch->removeCustomer($customer->getId());
        } catch (\Throwable $e) {
            $this->logger->warning('CleanPendingDelete: erreur Meilisearch '.$customer->getEmail().': '.$e->getMessage());
        }
    }
}
