<?php

namespace Lc\ShopBundle\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Lc\ShopBundle\Context\FilterMerchantInterface;
use Lc\ShopBundle\Context\FilterMultipleMerchantsInterface;
use Lc\ShopBundle\Context\MerchantUtilsInterface;
use Lc\ShopBundle\Context\StatusInterface;
use Lc\ShopBundle\Services\Utils;

class BaseRepository extends EntityRepository implements ServiceEntityRepositoryInterface
{
        protected $merchantUtils;
        protected $utils;

        /**
         * @param string $entityClass The class name of the entity this repository manages
         */
        public function __construct(EntityManager $entityManager, MerchantUtilsInterface $merchantUtils, Utils $utils)
        {
                $this->merchantUtils = $merchantUtils;
                $this->utils = $utils;
                parent::__construct($entityManager, $entityManager->getClassMetadata($this->getInterfaceClass()));
        }



        public function findByTerm($field, $term, $limit=10){
                $qb = $this->findByMerchantQuery();

                if($this->utils->hasFilterAssociation($field, '_')){
                        $aliasRelation = $this->utils->getFilterAssociationAlias($field, '_');

                        $qb->innerJoin('e.'.$aliasRelation, $aliasRelation);
                        $qb->select($this->utils->getFilterPropertyInit($field));
                        $qb->groupBy($this->utils->getFilterPropertyInit($field));
                        $qb->andWhere(
                                $qb->expr()->like($this->utils->getFilterPropertyInit($field), ':term'));
                }else {
                        $qb->select('e.' . $field);
                        $qb->groupBy('e.' . $field);
                        $qb->andWhere(
                                $qb->expr()->like('e.' . $field, ':term'));
                }
                $qb->setParameter('term', '%'.$term.'%');
                $qb->setMaxResults($limit);

                return $qb->getQuery()->getResult();

        }




        public function findOneByOldUrl($url)
        {
                $qb = $this->createQueryBuilder('entity')
                        ->where('entity.oldUrls LIKE :oldUrl')
                        ->andWhere('entity.status = 1')
                        ->setParameter(':oldUrl', '%'.$url.'%');

                return $qb->getQuery()->getOneOrNullResult();
        }

        public function findByMerchantQuery($merchant = null) :QueryBuilder
        {
                if($merchant === false || $merchant===null)$merchant = $this->merchantUtils->getMerchantCurrent();
                return $this->createQueryBuilder('e')
                        ->where('e.merchant = :currentMerchant')
                        ->setParameter('currentMerchant', $merchant) ;
        }

        public function findAll()
        {
                return $this->findBy(array());
        }

        public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
        {
                $className = $this->getClassMetadata()->getName();
                $entity = new $className;

                if($entity instanceof StatusInterface){
                        if (!isset($criteria['status'])) $criteria['status'] = 1;
                        if ($criteria['status'] === false) unset($criteria['status']);
                }

                if($entity instanceof FilterMerchantInterface){
                        if (!isset($criteria['merchant'])) $criteria['merchant'] = $this->merchantUtils->getMerchantCurrent();
                        if ($criteria['merchant'] === false) unset($criteria['merchant']);
                }

                return parent::findBy($criteria, $orderBy, $limit, $offset);

        }

        public function findOneBy(array $criteria, array $orderBy = null)
        {

                $className = $this->getClassMetadata()->getName();
                $entity = new $className;

                if($entity instanceof StatusInterface){
                        if (!isset($criteria['status'])) $criteria['status'] = 1;
                        if ($criteria['status'] === false) unset($criteria['status']);
                }

                if($entity instanceof FilterMerchantInterface){
                        if (!isset($criteria['merchant'])) $criteria['merchant'] = $this->merchantUtils->getMerchantCurrent();
                        if ($criteria['merchant'] === false) unset($criteria['merchant']);
                }

                return parent::findOneBy($criteria, $orderBy);
        }

        public function findSimilarSlug($merchant){
                $qb = $this->createQueryBuilder('entity')
                        ->select('entity.id, COUNT(entity.slug) as niche')
                        ->andWhere('entity.status>=0')
                        ->andWhere('entity.merchant= :merchant')
                        ->setParameter('merchant', $merchant)

                        ->groupBy('entity.slug')
                        ->having('COUNT(entity.slug) >1');

                return $qb->getQuery()->getResult();
        }

}