<?php
/**
 * @author Colinet Julien
 */

namespace CpCreation\VitiCore\Shop\Repository;

use CpCreation\VitiCore\Product\Model\ProductPriceGroup;
use CpCreation\VitiCore\Repository\BaseRepository;
use CpCreation\VitiCore\Shop\Model\ShippingCountry;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Intl\Countries;

class ShippingCountryRepository extends BaseRepository
{

    /**
     * ShippingCountryRepository constructor.
     * @param ManagerRegistry $registry
     * @throws \ReflectionException
     */
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, ShippingCountry::class);
    }

    /**
     * @return \Doctrine\ORM\QueryBuilder
     */
    public function findCountriesNotDisabledQueryBuilder()
    {
        $qb = $this->createQueryBuilder('country')
                   ->andWhere('country.disabled = FALSE')
                   ->orderBy('country.code', 'ASC');

        return $qb;
    }

    /**
     * @return \Doctrine\ORM\QueryBuilder
     */
    public function findCountriesNotDisabledNotAssignedQueryBuilder()
    {
        $qb = $this->createQueryBuilder('country')
                    ->andWhere('country.disabled = FALSE')
                    ->orderBy('country.code', 'ASC');

        return $qb;
    }

    /**
     * @return Collection | ShippingCountry[]
     */
    public function findCountriesNotDisabled()
    {
        $qb = $this->createQueryBuilder('country')
                   ->andWhere('country.disabled = FALSE')
                   ->orderBy('country.code', 'ASC')
                   ->getQuery()->getResult();

        return $qb;
    }

    /**
     * @return Collection | ShippingCountry[]
     */
    public function findCountriesOrder()
    {
        $qb = $this->createQueryBuilder('country')
                   ->getQuery()->getResult();

        /** @var ShippingCountry $country */
        foreach ($qb as $country) {
            $countries[Countries::getName($country->getCode()).'-'.$country->getId()] = $country;
        }
        ksort($countries);

        return $countries;
    }


    /**
     * @return Collection | ShippingCountry[]
     */
    public function findCountriesAssigned()
    {
        $countries = [];
        $qb        = $this->createQueryBuilder('country')
                          ->innerJoin('country.zones', 'zones')
                          ->innerJoin('zones.countries', 'countries', Join::WITH, 'countries.id = country.id')
                          ->andWhere('country.disabled = FALSE')
                          ->getQuery()->getResult();


        foreach ($qb as $country) {
            $countries[Countries::getName($country->getCode()).'-'.$country->getId()] = $country;
        }
        ksort($countries);

        return $countries;
    }

    /**
     * @param $group
     * @return array
     */
    public function findCountriesAssignedByGroup($group)
    {
        $countries = [];
        $qb        = $this->createQueryBuilder('country')
                          ->innerJoin('country.zones', 'zones')
                          ->innerJoin('zones.countries', 'c', Join::WITH, 'c.id = country.id')
                          ->innerJoin('country.groups', 'g', Join::WITH, 'g.id = :group')
                          ->andWhere('country.disabled = FALSE')
                          ->setParameter('group', $group)
                          ->getQuery()->getResult();


        /** @var ShippingCountry $country */
        foreach ($qb as $country) {
            $countries[Countries::getName($country->getCode()).'-'.$country->getId()] = $country;
        }
        ksort($countries);

        return $countries;
    }

    /**
     * @param $code
     * @param $group
     * @return int|mixed|string|null
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    public function findOneByGroup($code, $group)
    {
        $qb    = $this->createQueryBuilder('country')
                      ->andWhere('country.code = :code')
                      ->andWhere('country.disabled = FALSE')
                      ->innerJoin('country.groups', 'g', Join::WITH, 'g.id = :group')
                      ->setMaxResults(1)
                      ->setParameter('code', $code)
                      ->setParameter('group', $group);
        $query = $qb->getQuery();

        return $query->getOneOrNullResult();
    }

}
