<?php

namespace App\Entity;

use App\Enum\CurrencyEnum;
use App\Utils\OperationFactory;
use Doctrine\ORM\Mapping as ORM;

/**
 * TRANSACTION
 * Dans l'interface de gestion de son compte professionnel, un prestataire peut effectuer deux types de virements internes, vers un autre prestataire ou vers un adhérent
 * Pour ajouter il faut un rôle spécifique:
 *     – Adhérent (paiement numérique avec son compte adhérent)
 *     – Prestataire (entre prestataires et virement vers un compte adhérent)
 * La somme des transactions électroniques sont limitées à un million d'euro par année glissante,
 * important donc de contrôler au moins le montant global des 365 derniers jours.
 *
 * Types de transaction :
 *
 *   - PRESTATAIRES     =>    ADHERENTS         (Virement vers un adherent)
 *   - PRESTATAIRES     =>    PRESTATAIRES      (Virement entre prestataires)
 *   - ADHERENTS        =>    PRESTATAIRES      (Paiement numérique)
 *   - ADHERENTS        =>    ADHERENTS         (transfert de monnaie numérique)
 *
 * @ORM\Entity
 */
class Transaction extends Flux
{
    const TYPE_TRANSACTION_ADHERENT_ADHERENT = 'adherent_adherent';
    const TYPE_TRANSACTION_ADHERENT_PRESTATAIRE = 'adherent_prestataire';
    const TYPE_TRANSACTION_PRESTATAIRE_ADHERENT = 'prestataire_adherent';
    const TYPE_TRANSACTION_PRESTATAIRE_PRESTATAIRE = 'prestataire_prestataire';

    /**
     * A transaction is marked as CCAS if both parties are CCAS compliant.
     * 
     * @ORM\Column(type="boolean", options={"default": false})
     */
    protected $isCcas = false;

    public static function getAvailableTypes(): array
    {
        return [
            self::TYPE_TRANSACTION_ADHERENT_ADHERENT => self::TYPE_TRANSACTION_ADHERENT_ADHERENT,
            self::TYPE_TRANSACTION_ADHERENT_PRESTATAIRE => self::TYPE_TRANSACTION_ADHERENT_PRESTATAIRE,
            self::TYPE_TRANSACTION_PRESTATAIRE_ADHERENT => self::TYPE_TRANSACTION_PRESTATAIRE_ADHERENT,
            self::TYPE_TRANSACTION_PRESTATAIRE_PRESTATAIRE => self::TYPE_TRANSACTION_PRESTATAIRE_PRESTATAIRE,
        ];
    }

    /**
     * @return string
     */
    public function getParenttype(): string
    {
        return parent::TYPE_TRANSACTION;
    }

    public function getAllOperations($em)
    {
        return [
            OperationFactory::getOperation($this, $this->getExpediteur(), CurrencyEnum::CURRENCY_EMLC, -$this->getMontant()),
            OperationFactory::getOperation($this, $this->getDestinataire(), CurrencyEnum::CURRENCY_EMLC, $this->getMontant()),
        ];
    }

    public function operate($em)
    {
        $compteExp = $this->getExpediteur()->getEcompte() - $this->getMontant();
        if ($compteExp < 0) {
            throw new \Exception("[FLUX] Transaction impossible ! Montant supérieur au solde de l'expéditeur !");
        } else {
            $this->getExpediteur()->removeEcompte($this->getMontant());
            $this->getDestinataire()->addEcompte($this->getMontant());

            return [$this->getExpediteur(), $this->getDestinataire()];
        }

        return [];
    }

    /**
     * @return string
     */
    public function getType(): string
    {
        return '';
    }

    public function getUsersToNotify()
    {
        return [];
    }

    public function getIsCcas(): ?bool
    {
        return $this->isCcas;
    }

    public function setIsCcas(bool $isCcas): self
    {
        $this->isCcas = $isCcas;

        return $this;
    }
}
