<?php

namespace App\Command;

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:stripe:sync',
    description: 'Synchronise les donnees Stripe (paiements, remboursements, versements, comptes Connect)',
)]
class StripeSyncCommand extends Command
{
    public function __construct(
        #[Autowire(env: 'STRIPE_SK')] private string $stripeSecretKey,
    ) {
        parent::__construct();
    }

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

        if ('' === $this->stripeSecretKey || 'sk_test_***' === $this->stripeSecretKey) {
            $io->warning('Cle Stripe non configuree. Synchronisation ignoree.');

            return Command::SUCCESS;
        }

        \Stripe\Stripe::setApiKey($this->stripeSecretKey);

        $this->syncPayments($io);
        $this->syncRefunds($io);
        $this->syncPayouts($io);
        $this->syncConnectAccounts($io);

        $io->success('Synchronisation Stripe terminee.');

        return Command::SUCCESS;
    }

    protected function syncPayments(SymfonyStyle $io): void
    {
        $io->section('Paiements');

        try {
            $charges = $this->fetchCharges();

            $count = 0;
            foreach ($charges as $charge) {
                $io->info('Paiement ID: '.$charge->id);
                ++$count;
            }

            $io->info(sprintf('%d paiement(s) recupere(s) (dernières 24h).', $count));
        } catch (\Throwable $e) {
            $io->error('Erreur paiements : '.$e->getMessage());
        }
    }

    protected function syncRefunds(SymfonyStyle $io): void
    {
        $io->section('Remboursements');

        try {
            $refunds = $this->fetchRefunds();

            $count = 0;
            foreach ($refunds as $refund) {
                $io->info('Remboursement ID: '.$refund->id);
                ++$count;
            }

            $io->info(sprintf('%d remboursement(s) recupere(s) (dernières 24h).', $count));
        } catch (\Throwable $e) {
            $io->error('Erreur remboursements : '.$e->getMessage());
        }
    }

    protected function syncPayouts(SymfonyStyle $io): void
    {
        $io->section('Versements');

        try {
            $payouts = $this->fetchPayouts();

            $count = 0;
            foreach ($payouts as $payout) {
                $io->info('Versement ID: '.$payout->id);
                ++$count;
            }

            $io->info(sprintf('%d versement(s) recupere(s) (derniers 7 jours).', $count));
        } catch (\Throwable $e) {
            $io->error('Erreur versements : '.$e->getMessage());
        }
    }

    protected function syncConnectAccounts(SymfonyStyle $io): void
    {
        $io->section('Comptes Connect');

        try {
            $accounts = $this->fetchConnectAccounts();

            $count = 0;
            foreach ($accounts as $account) {
                $status = $account->charges_enabled ? 'actif' : 'inactif';
                $payoutsEnabled = $account->payouts_enabled ? 'oui' : 'non';

                $io->comment(sprintf(
                    '[%s] %s — Charges: %s, Payouts: %s',
                    $account->id,
                    $account->email ?? 'N/A',
                    $status,
                    $payoutsEnabled,
                ));

                $io->info('Synchronisation compte: '.$account->id);
                ++$count;
            }

            $io->info(sprintf('%d compte(s) Connect synchronise(s).', $count));
        } catch (\Throwable $e) {
            $io->error('Erreur comptes Connect : '.$e->getMessage());
        }
    }

    /**
     * @return iterable<\Stripe\Charge>
     *
     * @codeCoverageIgnore
     */
    protected function fetchCharges(): iterable
    {
        return \Stripe\Charge::all(['limit' => 100, 'created' => ['gte' => strtotime('-1 day')]])->data;
    }

    /**
     * @return iterable<\Stripe\Refund>
     *
     * @codeCoverageIgnore
     */
    protected function fetchRefunds(): iterable
    {
        return \Stripe\Refund::all(['limit' => 100, 'created' => ['gte' => strtotime('-1 day')]])->data;
    }

    /**
     * @return iterable<\Stripe\Payout>
     *
     * @codeCoverageIgnore
     */
    protected function fetchPayouts(): iterable
    {
        return \Stripe\Payout::all(['limit' => 100, 'created' => ['gte' => strtotime('-7 days')]])->data;
    }

    /**
     * @return iterable<\Stripe\Account>
     *
     * @codeCoverageIgnore
     */
    protected function fetchConnectAccounts(): iterable
    {
        return \Stripe\Account::all(['limit' => 100])->data;
    }
}
