<?php

namespace App;

use App\Facades\Settings;
use App\Filter\Sorting\VehicleAttribute as VehicleAttributeSorting;
use Illuminate\Database\Eloquent\Model;
use Mtc\MercuryDataModels\CatalogOffer;
use Mtc\MercuryDataModels\Vehicle;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Config;
use Mtc\Filter\Contracts\FilterObject;
use App\Http\Resources\VehicleList;
use Mtc\MercuryDataModels\VehicleAttribute;

class VehicleFilter implements FilterObject
{
    /**
     * Instantiate a query for object
     *
     * @return Builder
     */
    public function createQuery(): Builder
    {
        return Vehicle::query()
            ->active()
            ->withRelationshipsForCardView()
            ->when(Settings::get('automotive-vehicle-brand-on-filter-card'), fn($query) => $query->with('make'));
    }

    /**
     * Fetch results
     *
     * @param Builder $query
     * @return LengthAwarePaginator
     */
    public function getResults(Builder $query): LengthAwarePaginator
    {
        $pageLimit = Settings::get('filter-results-per-page', Config::get('filter.result_page_limit'));

        if ($this->hasCatalogOffers()) {
            $pageLimit--;
        }

        return $query->paginate(request('perPage', $pageLimit));
    }

    /**
     * Fetch results
     *
     * @param Builder $query
     * @return int
     */
    public function getResultCount(Builder $query, bool $include_extras = true): int
    {
        $count = $query->count();

        if ($include_extras && $this->hasCatalogOffers()) {
            $count++;
        }

        return $count;
    }

    /**
     * Format results to response data
     *
     * @param LengthAwarePaginator $results
     * @return JsonResource
     */
    public function format(LengthAwarePaginator $results): JsonResource
    {
        return new VehicleList($results, $this->getCatalogOffer(), true);
    }

    /**
     * Apply filters to query (e.g. when getting values for filters not main object)
     *
     * @param Builder $query
     */
    public function applyFilter(Builder $query): void
    {
        $query->active();
    }

    /**
     * @return bool
     */
    private function catalogOffersEnabled(): bool
    {
        return Settings::get('filter-inject-offers-into-used-car-filter') === true;
    }

    /**
     * @return bool
     */
    private function hasCatalogOffers(): bool
    {
        if (!$this->catalogOffersEnabled()) {
            return false;
        }

        return CatalogOffer::query()
            ->active()
            ->exists();
    }

    /**
     * @return Model|Builder|null
     */
    private function getCatalogOffer(): Model|Builder|null
    {
        return CatalogOffer::query()
            ->active()
            ->inRandomOrder()
            ->first();
    }

    public function sortOptionName(): string
    {
        return 'vehicles';
    }

    public function additionalSortOptions($activeSortOptionName = '')
    {
        $sortOptions = [];
        $sortableAttributes = VehicleAttribute::query()
            ->where('sortable', 1)
            ->get();

        foreach ($sortableAttributes as $sortableAttribute) {
            $sortOptions[$sortableAttribute->slug] = VehicleAttributeSorting::class;
        }

        return $sortOptions;
    }
}
