<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Grid\Query;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;
use PrestaShop\PrestaShop\Core\Grid\Query\AbstractDoctrineQueryBuilder;
use PrestaShop\PrestaShop\Core\Grid\Query\DoctrineSearchCriteriaApplicatorInterface;
use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface;

final class CarrierQueryBuilder extends AbstractDoctrineQueryBuilder
{
    private $searchCriteriaApplicator;

    public function __construct(Connection $connection, string $dbPrefix, DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator)
    {
        parent::__construct($connection, $dbPrefix);

        $this->searchCriteriaApplicator = $searchCriteriaApplicator;
    }

    public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria): QueryBuilder
    {
        $queryBuilder = $this
            ->getCommonQueryBuilder($searchCriteria)
            ->select('gls.*, c.name, c.id_carrier');

        $this->searchCriteriaApplicator
            ->applyPagination($searchCriteria, $queryBuilder)
            ->applySorting($searchCriteria, $queryBuilder);

        return $queryBuilder;
    }

    public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria): QueryBuilder
    {
        return $this
            ->getCommonQueryBuilder($searchCriteria)
            ->select('COUNT(*)');
    }

    private function getCommonQueryBuilder(SearchCriteriaInterface $searchCriteria): QueryBuilder
    {
        $queryBuilder = $this->connection
            ->createQueryBuilder()
            ->from($this->dbPrefix . 'gls_poland_carrier', 'gls')
            ->innerJoin('gls', $this->dbPrefix . 'carrier', 'c', 'c.id_reference = gls.id_reference AND c.deleted = 0');

        $this->applyFilters($searchCriteria->getFilters(), $queryBuilder);

        return $queryBuilder;
    }

    private function applyFilters(array $filters, QueryBuilder $qb): void
    {
        foreach ($filters as $filterName => $filterValue) {
            if ('' === $filterValue || null === $filterValue) {
                continue;
            }

            switch ($filterName) {
                case 'id_reference':
                case 'type':
                case 'parcelshop_type':
                    $qb->andWhere('gls.`' . $filterName . '` = :' . $filterName);
                    $qb->setParameter($filterName, $filterValue);

                    break;
                case 'countries':
                    $qb->andWhere('gls.`' . $filterName . '` LIKE :' . $filterName);
                    $qb->setParameter($filterName, '%' . $filterValue . '%');

                    break;
                case 'name':
                    $qb->andWhere('c.`' . $filterName . '` LIKE :' . $filterName);
                    $qb->setParameter($filterName, '%' . $filterValue . '%');

                    break;
                default:
                    break;
            }
        }
    }
}
