<?php

namespace UserBundle\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use UserBundle\Entity\User;
use UserBundle\Enum\UserRoleEnum;

/**
 * UserRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class UserRepository extends EntityRepository
{

    /**
     * Get query builder for fetching users which not verified.
     *
     * @return QueryBuilder
     */
    public function getNotVerifiedQueryBuilder()
    {
        return $this->createQueryBuilder('User')
            ->join('User.billingSubscription', 'Subscription')
            ->where('User.verified = 0 AND Subscription.payed = 1');
    }

    /**
     * Get user with his billing subscription.
     *
     * @param integer $id User entity id.
     *
     * @return User|null
     */
    public function getWithBillingSubscription($id)
    {
        return $this->createQueryBuilder('User')
            ->addSelect('BillingSubscription, Plan')
            ->join('User.billingSubscription', 'BillingSubscription')
            ->join('BillingSubscription.plan', 'Plan')
            ->where('User.id = :id')
            ->setParameter('id', $id)
            ->getQuery()
            ->getOneOrNullResult();
    }

   /**
     * Get user with his billing subscription.
     *
     * @param integer $id User entity id.
     *
     * @return User|null
     */
    public function getAllUserBillingSubscription($currentDate)
    {
        $startDate = $currentDate.' 00:00:00';
        $endDate = $currentDate.' 23:59:59';
        return $this->createQueryBuilder('User')
            ->addSelect('BillingSubscription')
            ->join('User.billingSubscription', 'BillingSubscription')
            ->where('BillingSubscription.isSubscriptionCancelled = :isSubscriptionCancelled')
            ->setParameter('isSubscriptionCancelled', true)
            ->andWhere('BillingSubscription.endDate >= :endDate1')
            ->setParameter('endDate1', $startDate)
            ->andWhere('BillingSubscription.endDate <= :endDate2')
            ->setParameter('endDate2', $endDate)
            ->getQuery()
            ->getResult();
    }

    /**
     * Get user with his billing subscription.
     *
     * @param integer $id User entity id.
     *
     * @return User|null
     */
    public function getAllUserBillingSubscriptionPlanDowngrade($currentDate)
    {
        $startDate = $currentDate.' 00:00:00';
        $endDate = $currentDate.' 23:59:59';
        return $this->createQueryBuilder('User')
            ->addSelect('BillingSubscription')
            ->join('User.billingSubscription', 'BillingSubscription')
            ->where('BillingSubscription.isPlanDowngrade = :isPlanDowngrade')
            ->setParameter('isPlanDowngrade', true)
            ->andWhere('BillingSubscription.isSubscriptionCancelled = :isSubscriptionCancelled')
            ->setParameter('isSubscriptionCancelled', false)
            ->andWhere('BillingSubscription.endDate >= :endDate1')
            ->setParameter('endDate1', $startDate)
            ->andWhere('BillingSubscription.endDate <= :endDate2')
            ->setParameter('endDate2', $endDate)
            ->getQuery()
            ->getResult();
    }

    /**
     * Get user by role and search words
     *
     * @param UserRoleEnum $role        Requested user role.
     * @param array        $searchWords Search words which should be contained in
     *                                  user full name or email.
     *
     * @return \Doctrine\ORM\QueryBuilder
     */
    public function getUserByRoleQB(UserRoleEnum $role, array $searchWords)
    {
        $expr = $this->_em->getExpressionBuilder();
        $qb = $this->createQueryBuilder('User')
            ->addSelect('BillingSubscription, Plan')
            ->leftJoin('User.billingSubscription', 'BillingSubscription')
            ->leftJoin('BillingSubscription.plan', 'Plan')
            ->where($expr->andX(
                $expr->like('User.roles', ':role'),
                $expr->andX('User.verified = 1')
            ))
            ->setParameter(':role', '%'.$role.'%');

        if (count($searchWords)) {
            $condition = $expr->orX();
            foreach ($searchWords as $key => $word) {
                $condition->add($expr->like('User.firstName', ':word_'.$key));
                $condition->add($expr->like('User.lastName', ':word_'.$key));
                $condition->add($expr->like('User.email', ':word_'.$key));
                $qb->setParameter('word_'.$key, '%'.$word.'%');
            }
            $qb->andWhere($condition);
        }

        return $qb;
    }

    /**
     * Get all subscribers fro given user.
     *
     * @param integer $user A master User entity id.
     *
     * @return \Doctrine\ORM\QueryBuilder
     */
    public function getSubscribersQueryBuilder($user)
    {
        $expr = $this->_em->getExpressionBuilder();

        return $this->createQueryBuilder('Subscriber')
            ->where($expr->eq('Subscriber.masterUser', ':user'))
            ->setParameter('user', $user);
    }
}
