<?php

namespace Lc\SovBundle\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Gedmo\Translatable\TranslatableListener;
use Lc\SovBundle\Doctrine\Extension\StatusInterface;

abstract class AbstractRepository extends EntityRepository implements ServiceEntityRepositoryInterface,
                                                                      AbstractRepositoryInterface
{

        protected $defaultLocale;

        public function setDefaultLocale($locale)
        {
                $this->defaultLocale = $locale;
        }

        public function __construct(EntityManagerInterface $entityManager)
        {
                parent::__construct($entityManager, $entityManager->getClassMetadata($this->getInterfaceClass()));
        }

        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 getOneOrNullResult(QueryBuilder $qb, $locale = null, $hydrationMode = null)
        {
                return $this->getTranslatedQuery($qb, $locale)->getOneOrNullResult($hydrationMode);
        }


        public function getResult(QueryBuilder $qb, $locale = null, $hydrationMode = AbstractQuery::HYDRATE_OBJECT)
        {
                return $this->getTranslatedQuery($qb, $locale)->getResult($hydrationMode);
        }


        public function getArrayResult(QueryBuilder $qb, $locale = null)
        {
                return $this->getTranslatedQuery($qb, $locale)->getArrayResult();
        }


        public function getSingleResult(QueryBuilder $qb, $locale = null, $hydrationMode = null)
        {
                return $this->getTranslatedQuery($qb, $locale)->getSingleResult($hydrationMode);
        }


        public function getScalarResult(QueryBuilder $qb, $locale = null)
        {
                return $this->getTranslatedQuery($qb, $locale)->getScalarResult();
        }


        public function getSingleScalarResult(QueryBuilder $qb, $locale = null)
        {
                return $this->getTranslatedQuery($qb, $locale)->getSingleScalarResult();
        }

        protected function getTranslatedQuery(QueryBuilder $qb, $locale = null)
        {
                $locale = null === $locale ? $this->defaultLocale : $locale;

                $query = $qb->getQuery();

                $query->setHint(
                        Query::HINT_CUSTOM_OUTPUT_WALKER,
                        'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'
                );

                $query->setHint(TranslatableListener::HINT_TRANSLATABLE_LOCALE, $locale);

                return $query;
        }


        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']);
                }

                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']);
                }

                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();
        }

}