<?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;
use Symfony\Component\DependencyInjection\ContainerInterface;

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

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

    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 bool|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 bool|date
     */
    public function isCotisationValidForPresta(?Prestataire $presta)
    {
        // In TAV mode, no standard cotisation required. Return next year date to make all accounts valid.
        if ($this->container->getParameter('tav_env')) {
            return date('Y-m-d', strtotime('+1 year'));
        }

        $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 bool|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 bool|date
     */
    public function isCotisationValidForAdherent(?Adherent $adherent)
    {
        // In TAV mode, no standard cotisation required. Return next year date to make all accounts valid.
        if ($this->container->getParameter('tav_env')) {
            return date('Y-m-d', strtotime('+1 year'));
        }

        $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 bool|date
     */
    public function isCotisationValid(?UserInterface $user)
    {
        // In TAV mode, no standard cotisation required. Return next year date to make all accounts valid.
        if ($this->container->getParameter('tav_env')) {
            return date('Y-m-d', strtotime('+1 year'));
        }

        $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 ($user->isGranted('ROLE_ADHERENT') && 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;
    }
}