<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\PersonBundle\Widget;

use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Templating\Widget\WidgetInterface;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use DateTime;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\User\UserInterface;
use Twig_Environment;

/**
 * add a widget with person list.
 *
 * The configuration is defined by `PersonListWidgetFactory`
 */
class ChillPersonAddAPersonWidget implements WidgetInterface
{
    /**
     * the authorization helper.
     *
     * @var AuthorizationHelper;
     */
    protected $authorizationHelper;

    /**
     * The entity manager.
     *
     * @var EntityManager
     */
    protected $entityManager;

    /**
     * Repository for persons.
     *
     * @var EntityRepository
     */
    protected $personRepository;

    /**
     * @var TokenStorage
     */
    protected $tokenStorage;

    /**
     * @var UserInterface
     */
    protected $user;

    public function __construct(
        EntityRepository $personRepostory,
        EntityManager $em,
        AuthorizationHelper $authorizationHelper,
        TokenStorage $tokenStorage
    ) {
        $this->personRepository = $personRepostory;
        $this->authorizationHelper = $authorizationHelper;
        $this->tokenStorage = $tokenStorage;
        $this->entityManager = $em;
    }

    /**
     * @param type $place
     *
     * @return string
     */
    public function render(Twig_Environment $env, $place, array $context, array $config)
    {
        $qb = $this->personRepository
            ->createQueryBuilder('person');

        // show only the person from the authorized centers
        $and = $qb->expr()->andX();
        $centers = $this->authorizationHelper
            ->getReachableCenters($this->getUser(), PersonVoter::SEE);
        $and->add($qb->expr()->in('person.center', ':centers'));
        $qb->setParameter('centers', $centers);

        // add the "only active" where clause
        if (true === $config['only_active']) {
            $qb->join('person.accompanyingPeriods', 'ap');
            $or = new Expr\Orx();
            // add the case where closingDate IS NULL
            $andWhenClosingDateIsNull = new Expr\Andx();
            $andWhenClosingDateIsNull->add((new Expr())->isNull('ap.closingDate'));
            $andWhenClosingDateIsNull->add((new Expr())->gte(':now', 'ap.openingDate'));
            $or->add($andWhenClosingDateIsNull);
            // add the case when now is between opening date and closing date
            $or->add(
                (new Expr())->between(':now', 'ap.openingDate', 'ap.closingDate')
            );
            $and->add($or);
            $qb->setParameter('now', new DateTime(), Type::DATE);
        }

        // adding the where clause to the query
        $qb->where($and);

        $qb->setFirstResult(0)->setMaxResults($config['number_of_items']);

        $persons = $qb->getQuery()->getResult();

        return $env->render(
            'ChillPersonBundle:Widget:homepage_person_list.html.twig',
            ['persons' => $persons]
        );
    }

    /**
     * @return UserInterface
     */
    private function getUser()
    {
        // return a user
    }
}
