<?php

namespace AppBundle\Entity;

use Gedmo\Tree\Entity\Repository\NestedTreeRepository;
use Doctrine\ORM\Query\Expr;

/**
 * PageRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class PageRepository extends NestedTreeRepository
{
    /**
     * @param Page $page
     * @return Page[]|array
     *
     * @todo Optimize performance by adapting search algorithm's optimizations
     */
    public function getChildrenWithTravelProgramsAndDates(Page $page)
    {
        $pages = $this->getChildrenQueryBuilder($page)
            ->leftJoin('node.travelProgram', 'tp')
            ->addSelect('tp')
            ->andWhere('tp.status > 0')
            ->andWhere('node.status > 0')
            ->orderBy('node.order')
            ->addOrderBy('tp.position')
            ->addOrderBy('node.title')
            ->getQuery()
            ->execute();
        /** @var Page $childPage */
        foreach ($pages as &$childPage)
        {
            if ($childPage->getTravelProgram())
            {
                $this->getEntityManager()->getRepository('AppBundle:TravelPeriod')->getTrueTravelPeriods(
                  $childPage->getTravelProgram());
            }
        }
        return $pages;
    }

    public function findWithTravelProgramsOfCountry(TravelCountry $country)
    {
        return $this->createQueryBuilder('node')
            ->innerJoin('node.travelProgram', 'tp')
            ->innerJoin('tp.countries', 'c')
            ->where('c.id = '. $country->getId())
            ->andWhere('node.status = 1')
            ->andWhere('tp.status = 1')
            ->getQuery()
            ->execute()
            ;
    }

    /**
     * @return Page[]
     */
    public function findOffers()
    {
        $ret = [];
        $countries = $this->getEntityManager()->getRepository('AppBundle:TravelCountry')->findAll();
        foreach ($countries as $country)
        {
            $ret = array_merge($ret, $this->createQueryBuilder('node')
                ->innerJoin('node.travelProgram', 'tp')
                ->addSelect('tp')
                ->innerJoin('tp.countries', 'c')
                ->where('c.id = '. $country->getId())
                ->andWhere('node.status = 1')
                ->andWhere('tp.status = 1')
                ->orderBy('node.order')
                ->addOrderBy('tp.position')
                ->addOrderBy('node.title')
                ->setMaxResults(3)
                ->getQuery()
                ->execute()
            );
        }
        shuffle($ret);
        return $ret;
    }

    public function findCountryPages()
    {
        return $this->createQueryBuilder('node')
            ->innerJoin('node.country', 'country')
            ->where('node.status > 0')
            ->andWhere('node.template = \'overview\'')
            ->andWhere('node.lvl = 0')
            ->orderBy('node.lft,node.title')
            ->getQuery()
            ->execute()
            ;
    }

    public function findTopCountryNavPages()
    {
        return $this->createQueryBuilder('node')
            ->innerJoin('node.country', 'country')
            ->leftJoin('node.children', 'childPage', Expr\Join::WITH, 'childPage.status > 0')
            ->addSelect('childPage')
            ->where('node.status > 0')
            ->andWhere('node.template = \'overview\'')
            ->andWhere('node.lvl = 0')
            ->orderBy('node.lft,node.title,childPage.lft,childPage.title')
            ->getQuery()
            ->execute()
            ;
    }

    public function findFeedbacks($rootPageId)
    {
        $qb = $this->createQueryBuilder('node');
        return $qb
            ->where($qb->expr()->eq('node.parent', $rootPageId))
            ->andWhere('node.showInNavi = 1')
            ->andWhere('node.status = 1')
            ->orderBy('node.date')
            ->getQuery()
            ->execute()
            ;
    }

    /**
     * @param Page $page
     *
     * @return Page[]|\Doctrine\Common\Collections\Collection
     */
    public function getSiblings(Page $page)
    {
        $parent = $page->getParent();
        if (!$parent)
        {
            // On purpose, we don't treat root pages as if they were siblings
            return [];
        }
        $siblings = $parent->getChildren();
        foreach ($siblings as &$sibling)
        {
            $sibling->setParent($parent);
        }

        // Da diese Methode nur für die Navigation verwendet wird, kann man hier vorfiltern
        $filteredSiblings = [];
        foreach ($siblings as &$sibling)
        {
            if($sibling->getStatus() == 1 && $sibling->getShowInNavi() == 1)
            {
                $filteredSiblings[] = $sibling;
            }
        }

        return $filteredSiblings;
    }
}
