<?php

namespace App\Twig;

use App\Entity\Adherent;
use App\Entity\Flux;
use App\Entity\Prestataire;
use App\Entity\SolidoumeItem;
use App\Entity\SolidoumeParameter;
use App\Form\Type\SolidoumeFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Security;
use Twig\Extension\AbstractExtension;

class SolidoumeExtension extends AbstractExtension
{
    protected $em;
    protected $formFactory;
    protected $router;
    protected $security;

    public function __construct(
        EntityManagerInterface $em,
        FormFactoryInterface $formFactory,
        RouterInterface $router,
        Security $security
    ) {
        $this->em = $em;
        $this->formFactory = $formFactory;
        $this->router = $router;
        $this->security = $security;
    }

    /**
     * {@inheritdoc}
     */
    public function getFunctions()
    {
        return [
            new \Twig_SimpleFunction('getSolidoumeParam', [$this, 'getSolidoumeParam']),
            new \Twig_SimpleFunction('getSolidoumeForm', [$this, 'getSolidoumeForm']),
            new \Twig_SimpleFunction('getSolidoumeParticipation', [$this, 'getSolidoumeParticipation']),
            new \Twig_SimpleFunction('getSolidoumePrelevements', [$this, 'getSolidoumePrelevements']),
            new \Twig_SimpleFunction('getSolidoumeRedistributions', [$this, 'getSolidoumeRedistributions']),
            new \Twig_SimpleFunction('getSolidoumeDatas', [$this, 'getSolidoumeDatas']),
        ];
    }

    public function getSolidoumeParam(?string $name)
    {
        return $this->em->getRepository(SolidoumeParameter::class)->getValueOf($name);
    }

    public function getSolidoumeForm()
    {
        if (null == $this->security->getUser() || null == $this->security->getUser()->getAdherent() || !$this->security->getUser()->isGranted('ROLE_ADHERENT')) {
            return null;
        }
        $data = $this->em->getRepository(SolidoumeItem::class)->findOneBy(['enabled' => true, 'adherent' => $this->security->getUser()->getAdherent()]);
        $form = $this->formFactory->create(SolidoumeFormType::class, $data, ['action' => $this->router->generate('solidoume_adherer')]);

        return $form->createView();
    }

    public function getSolidoumeParticipation()
    {
        if (null == $this->security->getUser() || null == $this->security->getUser()->getAdherent() || !$this->security->getUser()->isGranted('ROLE_ADHERENT')) {
            return null;
        }
        $data = $this->em->getRepository(SolidoumeItem::class)->findOneBy(['enabled' => true, 'adherent' => $this->security->getUser()->getAdherent()]);

        return $data;
    }

    public function getSolidoumePrelevements(Adherent $adherent)
    {
        $datas = $this->em->getRepository(Flux::class)->getQueryByAdherentAndDestinataire($adherent, $this->em->getRepository(Prestataire::class)->getPrestataireSolidoume(), 'adherent_prestataire');

        return $datas;
    }

    public function getSolidoumeRedistributions(Adherent $adherent)
    {
        $datas = $this->em->getRepository(Flux::class)->getQueryByAdherentAndDestinataire($adherent, $this->em->getRepository(Prestataire::class)->getPrestataireSolidoume(), 'prestataire_adherent');

        return $datas;
    }

    public function getSolidoumeDatas()
    {
        $param = $this->em->getRepository(SolidoumeParameter::class)->findTheOne();
        if (empty($param)) {
            return null;
        }
        $items = $this->em->getRepository(SolidoumeItem::class)->findBy(['enabled' => true]);
        if (empty($items)) {
            return null;
        }
        $total = 0;
        $countPerson = 0;
        $countParticipants = 0;
        foreach ($items as $item) {
            $total += $item->getAmount();
            if (!$item->getIsDonation()) {
                ++$countParticipants;
            }
            ++$countPerson;
        }

        return [
            'total' => $total,
            'countPersons' => $countPerson,
            'countDonateurs' => ($countPerson - $countParticipants),
            'countParticipants' => $countParticipants,
            'totalByParticipant' => ($total / $countParticipants),
            'totalByParticipantWithCommission' => round((($total / $countParticipants) * ((100 - $param->getCommission()) / 100)), 2, PHP_ROUND_HALF_DOWN),
            'commission' => $param->getCommission(),
        ];
    }
}
