<?php

namespace App\Services;

use App\Models\NewsItem;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use App\Exceptions\ApiHttpException;
use App\Libs\Api\ParsedListParams;
use Illuminate\Database\Eloquent\Builder;
use App\Services\DataService;
use Illuminate\Support\Carbon;
use App\Libs\Database\Eloquent\Collection\ContentTypeCollection;

class NewsItemDataService extends DataService
{
    /**
     * Gets and filters news items
     *
     * @param ParsedListParams $params - Filter and order data
     * @return Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function list(ParsedListParams $params): LengthAwarePaginator
    {
        /** @var Builder $query */
        $query = NewsItem::full();
        $query->with([
            'artists' => function ($query) {
                $query->full()->select('*');
            },
            'category' => function ($catQuery) {
                $catQuery->full();
            }, 'image'
        ]);

        //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 news Item
     *
     * @param int $id
     * @throws ApiHttpException if the provided News item record is not found.
     * @return NewsItem
     */
    public function find(int $id): NewsItem
    {
        $newsItem = NewsItem::full()
            ->where('status', 'published')
            ->with([
                'artists' => function ($query) {
                    $query->full()->with('image')->select('*');
                },
                'category' => function ($catQuery) {
                    $catQuery->full();
                },
                'image'
            ])->where('id', $id)->first();

        if (!$newsItem) {
            throw new ApiHttpException(404, 'item_not_found');
        }

        return $newsItem;
    }


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

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

        //Defaults when no information is provided
        if (!isset($params->originalData['order']['by'])) {
            $orderBy = 'date';
        }
        if (!isset($params->originalData['order']['direction'])) {
            $orderDirection = 'DESC';
        }

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

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

        if (isset($params->filters['category_id'])) {
            $query->where('news_category_id', $params->filters['category_id']);
        }

        if (isset($params->filters['date_from'])) {

            $filterDateParam = Carbon::createFromFormat('d-m-Y', $params->filters['date_from'])->startOfDay();
            $query->whereDate('date', '>=', $filterDateParam);
        }

        // Highlights Filter
        if (isset($params->filters['highlights'])) {
            $query->where('highlight', $params->filters['highlights']);
        }
    }

    /**
     * Gets the news for the entry screen
     * 
     * @return App\Libs\Database\Eloquent\Collection\ContentTypeCollection
     */
    public function getEntryScreenNews(): ContentTypeCollection
    {

        /** @var Builder $query */
        $query = NewsItem::full();
        $query->with([
            'image', 'category'
        ])->where('highlight', 1)->where('status', 'published')
            ->orderBy('date', 'DESC');

        return $query->get();
    }
}
