<?php

namespace App\Services;

use App\Models\City;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use App\Exceptions\ApiHttpException;
use App\Libs\Api\ParsedListParams;
use Illuminate\Database\Eloquent\Builder;
use App\Services\DataService;

class CityDataService extends DataService
{
    /**
     * Gets and filters cities
     *
     * @param ParsedListParams $params - Filter and order data
     * @return Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function list(ParsedListParams $params): LengthAwarePaginator
    {
        /** @var Builder $query */
        $query = City::full()->with(['country' => function ($countryQuery) {
            $countryQuery->full();
        }]);
        $query->whereHas('country', function ($query) {
            $query->where('main_country', 1);
        });
        //check if the default filters are to be applied
        $this->applyDefaultFilters($query, $params);
        $this->applyQueryParams($query, $params);
        return $query->paginate($params->itemsPerPage, ['*'], 'page', $params->pageNumber);
    }


    /**
     * Finds a single model for the city
     *
     * @param int $id
     * @throws ApiHttpException if the provided City record is not found.
     * @return City
     */
    public function find(int $id): ?City
    {
        $city = City::with('country')->find($id);
        if (!$city) {
            throw new ApiHttpException(404, 'item_not_found');
        }

        return $city;
    }


    /**
     * applyQueryParams
     *
     * @param Builder &$query
     * @param ParsedListParams $params
     * @return void
     */
    private function applyQueryParams(Builder $query, ParsedListParams $params): void
    {

        $orderDirection = $params->orderDirection;
        $orderBy        = $params->orderBy;

        //default ordering always by the name (the default ordering is always id)
        if ($orderBy == 'id') {
            $orderBy = 'name';
        }

        if ($orderBy === 'name') {
            $orderBy = 'title';
        }

        $query->orderBy($orderBy, $orderDirection);

        // Apply the specific Filters
        // City name Filter
        if (isset($params->filters['name'])) {
            $query->where('title', 'like', $params->filters['name'] . '%');
        }
    }
}
