<?php

namespace App\Entity;

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

/**
 * Cotisation d'un utilisateur.
 *
 * @ORM\Entity
 */
class Cotisation extends Flux
{
    const TYPE_COTISATION_ADHERENT = 'cotisation_adherent';
    const TYPE_COTISATION_PRESTATAIRE = 'cotisation_prestataire';

    /**
     * @ORM\OneToOne(targetEntity="Prestataire")
     * @ORM\JoinColumn(name="prestataire_dest_id", referencedColumnName="id", nullable=true)
     */
    protected $destinataire;

    /**
     * @ORM\OneToOne(targetEntity="CotisationInfos", inversedBy="cotisation", cascade={"persist"})
     * @ORM\JoinColumn(name="cotisationinfos_id", referencedColumnName="id", nullable=true)
     */
    protected $cotisationInfos;

    protected $don;

    /**
     * Constructeur.
     */
    public function __construct()
    {
        parent::__construct();
        $this->montant = (float) 0.0;
        $this->cotisationInfos = new CotisationInfos();
    }

    public static function getAvailableTypes(): array
    {
        return [
            self::TYPE_COTISATION_ADHERENT => self::TYPE_COTISATION_ADHERENT,
            self::TYPE_COTISATION_PRESTATAIRE => self::TYPE_COTISATION_PRESTATAIRE,
        ];
    }

    public function getAllOperations($em)
    {
        $cotisationOperations = [];
        if (MoyenEnum::MOYEN_EMLC == $this->getMoyen()) {
            $cotisationOperations = [
                OperationFactory::getOperation($this, $this->getExpediteur(), CurrencyEnum::CURRENCY_EMLC, -$this->getMontant()),
                OperationFactory::getOperation($this, $this->getDestinataire(), CurrencyEnum::CURRENCY_EMLC, $this->getMontant()),
            ];
        } elseif (MoyenEnum::MOYEN_CB == $this->getMoyen() || MoyenEnum::MOYEN_HELLOASSO == $this->getMoyen()) {
            $cotisationOperations = [
                OperationFactory::getOperation($this, $this->getDestinataire(), CurrencyEnum::CURRENCY_EURO, $this->getMontant()),
            ];
        }
        if (null != $this->getDon()) {
            return array_merge($cotisationOperations, $this->getDon()->getAllOperations($em));
        }

        return $cotisationOperations;
    }

    public function operate($em)
    {
        if (MoyenEnum::MOYEN_EMLC == $this->getMoyen()) {
            $compteExp = $this->getExpediteur()->getEcompte() - $this->getMontant();
            if ($compteExp < 0) {
                throw new \Exception('[FLUX] Opération impossible ! Montant supérieur au solde de monnaie éléctronique !');
            } else {
                $this->getExpediteur()->removeEcompte($this->getMontant());
                $this->getDestinataire()->addEcompte($this->getMontant());

                return [$this->getExpediteur(), $this->getDestinataire()];
            }
        }
        // Pas d'opération si la cotisation se fait par CB
        return [];
    }

    public function getUsersToNotify()
    {
        return [];
    }

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

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

    /**
     * Get cotisationInfos.
     *
     * @return cotisationInfos
     */
    public function getCotisationInfos(): ?CotisationInfos
    {
        return $this->cotisationInfos;
    }

    /**
     * Set CotisationInfos cotisationInfos.
     *
     * @return $this
     */
    public function setCotisationInfos(CotisationInfos $cotisationInfos)
    {
        $this->cotisationInfos = $cotisationInfos;

        return $this;
    }

    /**
     * @return string
     */
    public function getAnnee(): ?string
    {
        return $this->cotisationInfos->getAnnee();
    }

    /**
     * @param string $annee
     *
     * @return Cotisation
     */
    public function setAnnee(string $annee)
    {
        $this->cotisationInfos->setAnnee($annee);

        return $this;
    }

    /**
     * @return \DateTime
     */
    public function getDebut(): ?\DateTime
    {
        return $this->cotisationInfos->getDebut();
    }

    /**
     * @param \DateTime $debut
     *
     * @return Cotisation
     */
    public function setDebut(\DateTime $debut)
    {
        $this->cotisationInfos->setDebut($debut);

        return $this;
    }

    /**
     * @return \DateTime
     */
    public function getFin(): ?\DateTime
    {
        return $this->cotisationInfos->getFin();
    }

    /**
     * @param \DateTime $fin
     *
     * @return Cotisation
     */
    public function setFin(\DateTime $fin)
    {
        $this->cotisationInfos->setFin($fin);

        return $this;
    }

    /**
     * @return bool
     */
    public function isRecu(): ?bool
    {
        return $this->cotisationInfos->isRecu();
    }

    /**
     * @param bool $recu
     *
     * @return Cotisation
     */
    public function setRecu(bool $recu)
    {
        $this->cotisationInfos->setRecu($recu);

        return $this;
    }

    public function __toString(): string
    {
        if (empty($this->getDestinataire()) || empty($this->getExpediteur()) || null === $this->getMontant()) {
            return '[FLUX] Visualisation impossible ! Destinataire / Expéditeur et/ou montant manquant(s) !';
        }

        return ucwords(str_replace('_', ' ', $this->getType())) . ' : ' . $this->getExpediteur() . ' : ' . $this->getMontant() . '€' . ($this->getCreatedAt() ? ' (le ' . $this->getCreatedAt()->format('d/m/Y H:i') . ')' : '');
    }
}
