<?php

namespace App\Utils;

use App\Entity\Adherent;
use App\Entity\Flux;
use App\Entity\Prestataire;
use FOS\UserBundle\Model\UserInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Security;

class CotisationUtils
{
    private $em;
    private $session;
    private $security;
    private $eventDispatcher;

    public function __construct(CustomEntityManager $em, SessionInterface $session, Security $security, EventDispatcherInterface $eventDispatcher)
    {
        $this->em = $em;
        $this->session = $session;
        $this->security = $security;
        $this->eventDispatcher = $eventDispatcher;
    }

    public function isUserCotisationExpired(UserInterface $user, int $nbDay = 30): bool
    {
        if (null === $user && null != $this->security->getUser()) {
            if ($this->security->isGranted('ROLE_ADHERENT') && null != $this->security->getUser()->getAdherent()) {
                return $this->isCotisationExpired($this->security->getUser()->getAdherent());
            } elseif ($this->security->isGranted('ROLE_PRESTATAIRE') && null != $this->session->get('_prestagere')) {
                return $this->isCotisationExpired($this->session->get('_prestagere'));
            }
        } elseif (null !== $user) {
            if ($user->isGranted('ROLE_ADHERENT') && null != $user->getAdherent()) {
                return $this->isCotisationExpired($user->getAdherent());
            } elseif ($user->isGranted('ROLE_PRESTATAIRE') && null != $this->session->get('_prestagere')) {
                return $this->isCotisationExpired($this->session->get('_prestagere'));
            }
        }

        return false;
    }

    public function isCotisationExpired($object, int $nbDay = 30): bool
    {
        if ($object instanceof Adherent) {
            $cotisations = $this->em->getRepository(Flux::class)->getQueryByAdherent($adherent, 'cotisation')->getResult();
        } elseif ($object instanceof Prestataire) {
            $cotisations = $this->em->getRepository(Flux::class)->getQueryByPrestataire($prestataire, 'cotisation')->getResult();
        } else {
            return false;
        }
        $hasCotisationValidForPeriod = false;
        foreach ($cotisations as $cotisation) {
            if ($cotisation->isRecu() && $cotisation->getCotisationInfos()->getFin() > new \DateTime('now - ' . $nbDay . 'days')) {
                $hasCotisationValidForPeriod = true;
            }
        }

        return $hasCotisationValidForPeriod;
    }

    /**
     * Get first Cotisation For Presta ?
     * @param  Prestataire $presta
     * @return boolean|date
     */
    public function getFirstCotisationForPresta(?Prestataire $presta)
    {
        $query = null;
        if (null !== $presta) {
            $query = $this->em->getRepository(Flux::class)->getQueryByPrestataire($presta, 'cotisation');
        }
        if (null !== $query) {
            $cotisations = $query->getResult();
            if (count($cotisations) > 0) {
                $firstCotis = $cotisations[0];
                return $firstCotis->getCotisationInfos()->getDebut();
            }
        }

        return false;
    }

     /**
     * Is the Cotisation Valid For Presta ?
     * @param  Prestataire $presta
     * @return boolean|date
     */
    public function isCotisationValidForPresta(?Prestataire $presta)
    {
        $query = null;
        if (null !== $presta) {
            $query = $this->em->getRepository(Flux::class)->getQueryByPrestataire($presta, 'cotisation');
        }
        if (null !== $query) {
            $cotisations = $query->getResult();
            foreach ($cotisations as $cotisation) {
                if ($cotisation->isRecu() && $cotisation->getCotisationInfos()->getFin() > new \DateTime('now')) {
                    return $cotisation->getCotisationInfos()->getFin();
                }
            }
        }

        return false;
    }

    /**
     * Get first Cotisation For Adherent
     * @param  Adherent $adherent
     * @return boolean|date
     */
    public function getFirstCotisationForAdherent(?Adherent $adherent)
    {
        $query = null;
        if (null !== $adherent) {
            $query = $this->em->getRepository(Flux::class)->getQueryByAdherent($adherent, 'cotisation');
        }
        if (null !== $query) {
            $cotisations = $query->getResult();
            if (count($cotisations) > 0) {
                $firstCotis = $cotisations[0];
                return $firstCotis->getCotisationInfos()->getDebut();
            }
        }

        return false;
    }

    /**
     * Is the Cotisation Valid For Adherent
     * @param  Adherent $adherent
     * @return boolean|date
     */
    public function isCotisationValidForAdherent(?Adherent $adherent)
    {
        $query = null;
        if (null !== $adherent) {
            $query = $this->em->getRepository(Flux::class)->getQueryByAdherent($adherent, 'cotisation');
        }
        if (null !== $query) {
            $cotisations = $query->getResult();
            foreach ($cotisations as $cotisation) {
                if ($cotisation->isRecu() && $cotisation->getCotisationInfos()->getFin() > new \DateTime('now')) {
                    return $cotisation->getCotisationInfos()->getFin();
                }
            }
        }

        return false;
    }

    /**
     * Is Cotisation Valid
     * @param  UserInterface $user
     * @return boolean|date
     */
    public function isCotisationValid(?UserInterface $user)
    {
        $query = null;
        if (null === $user && null != $this->security->getUser()) {
            if ($this->security->isGranted('ROLE_ADHERENT') && null != $this->security->getUser()->getAdherent()) {
                $query = $this->em->getRepository(Flux::class)->getQueryByAdherent($this->security->getUser()->getAdherent(), 'cotisation');
            } elseif ($this->security->isGranted('ROLE_PRESTATAIRE') && null != $this->session->get('_prestagere')) {
                $query = $this->em->getRepository(Flux::class)->getQueryByPrestataire($this->session->get('_prestagere'), 'cotisation');
            }
        } elseif (null !== $user) {
            if (null != $user->getAdherent()) {
                $query = $this->em->getRepository(Flux::class)->getQueryByAdherent($user->getAdherent(), 'cotisation');
            } elseif ($user->isGranted('ROLE_PRESTATAIRE') && null != $this->session->get('_prestagere')) {
                $query = $this->em->getRepository(Flux::class)->getQueryByPrestataire($this->session->get('_prestagere'), 'cotisation');
            }
        }
        if (null !== $query) {
            $cotisations = $query->getResult();
            foreach ($cotisations as $cotisation) {
                if ($cotisation->isRecu() && $cotisation->getCotisationInfos()->getFin() > new \DateTime('now')) {
                    return $cotisation->getCotisationInfos()->getFin();
                }
            }
        }

        return false;
    }
}