<?php

namespace App\Services;

use App\Repositories\QueryBuilder\Config as QueryBuilderConfig;
use App\Repositories\QueryBuilder\ConfigProvider as QueryBuilderConfigProvider;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Http\Request;
use Spatie\QueryBuilder\QueryBuilder;
use Webmozart\Assert\Assert;

class QueryBuilderService
{
    /**
     * @param EloquentBuilder|Relation|string $subject
     * @param string|QueryBuilderConfigProvider|null $configProvider
     * @param Request|null $request
     * @return QueryBuilder
     */
    public function createQueryBuilder(
        $subject,
        $builderConfigProvider = null,
        Request $request = null
    ): QueryBuilder
    {
        $builder = QueryBuilder::for($subject, $request);

        if ($builderConfigProvider) {
            Assert::isAOf(
                $builderConfigProvider,
                QueryBuilderConfigProvider::class
            );

            $this->applyQueryBuilderConfig(
                $builder,
                $builderConfigProvider::getQueryBuilderConfig(),
            );
        }

        return $builder;
    }

    private function applyQueryBuilderConfig(
        QueryBuilder $builder,
        QueryBuilderConfig $config
    ): void
    {
        $allowedFields = $config->getAllowedFields();

        if (count($allowedFields)) {
            $builder->allowedFields($allowedFields);
        }

        $builder->allowedAppends($config->getAllowedAppends());
        $builder->allowedFilters($config->getAllowedFilters());
        $builder->allowedIncludes($config->getAllowedIncludes());
        $builder->allowedSorts($config->getAllowedSorts());
    }
}

