<?php

namespace App;

use Carbon\Carbon;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Mtc\ContentManager\Models\ContentCategory;
use Mtc\ContentManager\Models\ContentTag;
use Mtc\MercuryDataModels\Page;

class PageRepository
{
    /**
     * @param string|null $type
     * @param int $limit
     * @param string $orderBy
     * @param array|string|null $filters
     * @param $paginated
     * @return LengthAwarePaginator|Collection
     */
    public function listing(
        ?string $type,
        int $limit = 6,
        string $orderBy = 'published_at',
        array|string|null $filters = [],
        $paginated = false
    ) {
        $query = Page::query()
            ->with(['primaryMediaUse.media', 'categories', 'tags'])
            ->active()
            ->where(fn($query) => $query->whereNull('published_at')->orWhere('published_at', '<=', Carbon::now()))
            ->where('category', $type)
            ->when(
                $filters['category'] ?? null,
                fn(Builder $query) => $query->whereHas(
                    'categories',
                    fn(Builder $indexQuery) => $indexQuery->where('slug', $filters['category'])
                )
            )
            ->when(
                $filters['tag'] ?? null,
                fn(Builder $query) => $query->whereHas(
                    'tags',
                    fn(Builder $indexQuery) => $indexQuery->where('slug', $filters['tag'])
                )
            )
            ->orderByDesc($orderBy);

        if ($paginated) {
            return $query->paginate($limit);
        } else {
            return $query->take($limit)->get();
        }
    }

    /**
     * @param string|null $type
     * @return Collection
     */
    public function getCategories(?string $type): Collection
    {
        return ContentCategory::query()
            ->whereHas(
                'pages',
                fn(Builder $query) => $query->where('category', $type)->active()
            )
            ->orderBy('name')
            ->get();
    }

    /**
     * @param string|null $type
     * @return Collection
     */
    public function getTags(?string $type): Collection
    {
        return ContentTag::query()
            ->whereHas(
                'pages',
                fn(Builder $query) => $query->where('category', $type)->active()
            )
            ->orderBy('name')
            ->get();
    }

    /**
     * @param string|null $type
     * @param int $limit
     * @param array|null $filters
     * @return Collection
     */
    public function featured(?string $type, int $limit = 3, ?array $filters = [])
    {
        return Page::query()
            ->with(['primaryMediaUse.media', 'categories', 'tags'])
            ->active()
            ->where('featured', 1)
            ->where('category', $type)
            ->when(
                $filters['category'] ?? null,
                fn(Builder $query) => $query->whereHas(
                    'categories',
                    fn(Builder $indexQuery) => $indexQuery->where('slug', $filters['category'])
                )
            )
            ->when(
                $filters['tag'] ?? null,
                fn(Builder $query) => $query->whereHas(
                    'tags',
                    fn(Builder $indexQuery) => $indexQuery->where('slug', $filters['tag'])
                )
            )
            ->inRandomOrder()
            ->take($limit)
            ->get();
    }
}
