<?php

namespace App\Services;

use App\Models\Artist;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use App\Exceptions\ApiHttpException;
use App\Libs\Api\ParsedListParams;
use Illuminate\Database\Eloquent\Builder;
use App\Services\DataService;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;

class ArtistDataService extends DataService
{
    /**
     * Gets and filters artists
     *
     * @param ParsedListParams $params - Filter and order data
     * @return Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function list(ParsedListParams $params): LengthAwarePaginator
    {
        /** @var Builder $query */
        $query = Artist::full()->with('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);
    }

    /**
     * Gets artists based on a tag
     *
     * @param ParsedListParams $params - Filter and order data
     * @param Tag $tag - The tag to get the artists from
     * @return Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function listByTag(ParsedListParams $params, $tag): LengthAwarePaginator
    {
        return $tag->artists()->full()->with('image')->paginate($params->itemsPerPage, ['*'], 'page', $params->pageNumber);
    }



    /**
     * Finds a single model for the artist
     *
     * @param int $id
     * @throws ApiHttpException if the provided Artist record is not found.
     * @return Artist
     */
    public function find(int $id): Artist
    {
        $artist = Artist::full()
            ->with([
                'collections' => function ($query) {
                    $query->full()->with('image')->select('*');
                },
                'exhibitions' => function ($query) {
                    $query->full()->with([
                        'image',
                        'location' => function ($query) {
                            $query->full()->with([
                                'tags' => function ($query) {
                                    $query->full();
                                },
                            ]);
                        },
                        'artists' => function ($query) {
                            $query->full()->with('image')->select('*');
                        }
                    ])->select('*');
                },
                'tags' => function ($query) {
                    $query->full()->select('*');
                },
                'news' => function ($query) {
                    $query->full()->with([
                        'image',
                        'category' => function ($catQuery) {
                            $catQuery->full();
                        },
                    ])->select('*');
                },
                'image',
            ])->where('id', $id)->first();
        if (!$artist) {
            throw new ApiHttpException(404, 'item_not_found');
        }

        return $artist;
    }


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

        $orderDirection = $params->orderDirection;
        $orderBy        = $params->orderBy;
        if ($orderBy === 'name') {
            $orderBy = 'title';
        }
        $query->orderBy($orderBy, $orderDirection);

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


        // Location Tag id Filter
        if (isset($params->filters['location_tag_id'])) {
            $query->whereHas('exhibitions', function ($exhibitionsQ) use ($params) {
                $exhibitionsQ->whereHas('location', function ($locationQ) use ($params) {
                    $locationQ->whereHas('tags', function ($tagQ) use ($params) {
                        $tagQ->where('id', $params->filters['location_tag_id']);
                    });
                });
            });
        }

        // Location type Filter
        if (isset($params->filters['location_tag_type'])) {
            $query->whereHas('exhibitions', function ($exhibitionsQ) use ($params) {
                $exhibitionsQ->whereHas('location', function ($locationQ) use ($params) {
                    $locationQ->whereHas('tags', function ($tagQ) use ($params) {
                        $tagQ->where('type', $params->filters['location_tag_type']);
                    });
                });
            });
        }
    }
}
