<?php

declare(strict_types=1);

namespace App\Command;

use App\Entity\AccountAdherent;
use App\Entity\AccountComptoir;
use App\Entity\AccountGroupe;
use App\Entity\AccountPrestataire;
use App\Entity\AccountSiege;
use App\Entity\Comptoir;
use App\Entity\Groupe;
use App\Entity\Prestataire;
use App\Entity\Siege;
use App\Entity\User;
use App\Enum\CurrencyEnum;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
 */
class CreateAccountsCommand extends Command
{
    protected static $defaultName = 'kohinos:accounts:create';

    protected $em;
    protected $io;

    public function __construct(
        EntityManagerInterface $em
    ) {
        $this->em = $em;
        parent::__construct();
    }

    protected function configure()
    {
        $this
            ->setDescription('Create accounts for all entities (siege, groupe, comptoir, adherent, prestataire)')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $this->io = new SymfonyStyle($input, $output);
        $this->io->title('--- CREATION DES COMPTES ---');
        $this->updateAllAccount();
        $this->io->success('--- FIN DE LA CREATION DES COMPTES ---');

        return 0;
    }

    private function updateAllAccount()
    {
        $users = $this->em->getRepository(User::class)->findAll();
        $countAccountCreated = 0;
        foreach ($users as $entity) {
            // Create all accounts link to this entity if not exist !
            if (!empty($entity->getAdherent())) {
                if (null == $entity->getAdherent()->getAccountWithCurrency(CurrencyEnum::CURRENCY_EMLC)) {
                    $account = new AccountAdherent();
                    $account
                        ->setBalance($entity->getAdherent()->getEcompte())
                        ->setCurrency(CurrencyEnum::CURRENCY_EMLC)
                    ;
                    $entity->getAdherent()->addAccount($account);
                    $this->em->persist($account);
                    $this->em->persist($entity->getAdherent());
                    ++$countAccountCreated;
                }
            }
        }
        $this->io->success('Nb de comptes adherent crée : ' . $countAccountCreated . ' !');
        $countAccountCreated = 0;
        $this->em->flush();
        $prestas = $this->em->getRepository(Prestataire::class)->findAll();
        foreach ($prestas as $presta) {
            if (null == $presta->getAccountWithCurrency(CurrencyEnum::CURRENCY_EMLC)) {
                $account = new AccountPrestataire();
                $account
                    ->setBalance($presta->getEcompte())
                    ->setCurrency(CurrencyEnum::CURRENCY_EMLC)
                ;
                $presta->addAccount($account);
                $this->em->persist($account);
                ++$countAccountCreated;
            }
            if ($presta->isMlc() && null == $presta->getAccountWithCurrency(CurrencyEnum::CURRENCY_EURO)) {
                // Ajout du compte de fonctionnement euro pour le prestataire MLC
                $accountEuro = new AccountPrestataire();
                $accountEuro
                        ->setCurrency(CurrencyEnum::CURRENCY_EURO)
                    ;
                $presta->addAccount($accountEuro);
                $this->em->persist($accountEuro);
                ++$countAccountCreated;
            }
            $this->em->persist($presta);
        }
        $this->io->success('Nb de comptes prestataire crée : ' . $countAccountCreated . ' !');
        $countAccountCreated = 0;
        $this->em->flush();
        $comptoirs = $this->em->getRepository(Comptoir::class)->findAll();
        foreach ($comptoirs as $comptoir) {
            if (null == $comptoir->getAccountWithCurrency(CurrencyEnum::CURRENCY_MLC)) {
                $account = new AccountComptoir();
                $account
                    ->setBalance($comptoir->getCompte())
                    ->setCurrency(CurrencyEnum::CURRENCY_MLC)
                ;
                $comptoir->addAccount($account);
                $this->em->persist($account);
                $this->em->persist($comptoir);
                ++$countAccountCreated;
            }
        }
        $this->io->success('Nb de comptes comptoir créés : ' . $countAccountCreated . ' !');
        $countAccountCreated = 0;
        $this->em->flush();
        $groupes = $this->em->getRepository(Groupe::class)->findAll();
        foreach ($groupes as $groupe) {
            if (null == $groupe->getAccountWithCurrency(CurrencyEnum::CURRENCY_MLC)) {
                $account = new AccountGroupe();
                $account
                    ->setBalance($groupe->getCompte())
                    ->setCurrency(CurrencyEnum::CURRENCY_MLC)
                ;
                $groupe->addAccount($account);
                $this->em->persist($account);
                $this->em->persist($groupe);
                ++$countAccountCreated;
            }
        }
        $this->io->success('Nb de comptes groupe créé : ' . $countAccountCreated . ' !');
        $this->em->flush();
        $siege = $this->em->getRepository(Siege::class)->getTheOne();

        if (null == $siege->getAccountWithCurrency(CurrencyEnum::CURRENCY_EMLC)) {
            $account = new AccountSiege();
            $account
                ->setBalance($siege->getEcompteNantie())
                ->setCurrency(CurrencyEnum::CURRENCY_EMLC) // compte de monnaie numérique nantie
            ;
            $siege->addAccount($account);
            $this->em->persist($account);
            $this->io->success('Compte emlc  du siege créé !');
        }
        if (null == $siege->getAccountWithCurrency(CurrencyEnum::CURRENCY_MLC)) {
            $accountMLC = new AccountSiege();
            $accountMLC
                ->setBalance($siege->getCompte())
                ->setCurrency(CurrencyEnum::CURRENCY_MLC) // compte de monnaie papier au siege non nantie
            ;
            $siege->addAccount($accountMLC);
            $this->em->persist($accountMLC);
            $this->io->success('Compte mlc papier du siege créé !');
        }
        // if ($siege->getAccountWithCurrency(CurrencyEnum::CURRENCY_EURO) == null) {
        //     $accountEuro = new AccountSiege();
        //     $accountEuro
        //         ->setCurrency(CurrencyEnum::CURRENCY_EURO) // compte réel de nantissement // @TODO : offrir la possibilité de voir les opérations du compte euro du fond de garanti ? Ou plutôt de suivre les euros à récupérés aux comptoirs
        //     ;
        //     $siege->addAccount($accountEuro);
        //     $this->em->persist($accountEuro);
        // }
        if (null == $siege->getAccountWithCurrency(CurrencyEnum::CURRENCY_MLC_NANTIE)) {
            $accountMlcNantie = new AccountSiege();
            $accountMlcNantie
                ->setBalance($siege->getCompteNantie())
                ->setCurrency(CurrencyEnum::CURRENCY_MLC_NANTIE) // compte de monnaie papier nantie
            ;
            $siege->addAccount($accountMlcNantie);
            $this->em->persist($accountMlcNantie);
            $this->em->persist($siege);
            $this->io->success('Compte mlc nantie du siege créé !');
        }
        $this->em->flush();
    }
}
