<?php

namespace Lc\SovBundle\Repository;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Gedmo\Translatable\TranslatableListener;

abstract class AbstractRepository extends ServiceEntityRepository implements ServiceEntityRepositoryInterface,
                                                                             AbstractRepositoryInterface
{
    protected $defaultLocale;

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

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

    // @TODO : à vérifier si on peut les virer
    /*public function findAll()
    {
        return $this->findBy(array());
    }

    public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $criteria = $this->setCriteria($criteria);

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

    public function findOneBy(array $criteria, array $orderBy = null)
    {
        $criteria = $this->setCriteria($criteria);

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

    protected function setCriteria(array $criteria): array
    {
        $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 $criteria;
    }*/

    // @TODO : à réécrire dans un Store
    /*
    public function findBySimilarSlug($slug)
    {
        $qb = $this->createQueryBuilder('entity')
                ->select('COUNT(entity.slug) as totalSimilar')
                ->andWhere('entity.status>=0')
                ->andWhere('entity.slug LIKE :slug')
                ->setParameter('slug', $slug)
                ->groupBy('entity.slug')
                ->having('COUNT(entity.slug) >=1');

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

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

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

}
