<?php

namespace App\Services;

use App\Filter;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleReview;

class VehicleContentService
{
    private const DEFAULT_PER_PAGE = 15;

    public function getVideos(
        ?string $makeSlug = null,
        ?string $modelSlug = null,
        ?int $perPage = null,
        int $page = 1
    ): LengthAwarePaginator {
        $perPage = $perPage ?? self::DEFAULT_PER_PAGE;
        $makeId = $makeSlug ? Filter::matchSlugToId('make', $makeSlug) : null;
        $modelId = $modelSlug ? Filter::matchSlugToId('model', $modelSlug) : null;

        $vehicles = Vehicle::query()
            ->active()
            ->whereNotNull('main_video_url')
            ->where('main_video_url', '!=', '')
            ->with(['make', 'model', 'primaryMediaUse.media'])
            ->when($makeId, fn ($q) => $q->where('make_id', $makeId))
            ->when($modelId, fn ($q) => $q->where('model_id', $modelId))
            ->get();

        $grouped = $vehicles
            ->groupBy(fn (Vehicle $v) => $v->make_id . '-' . $v->model_id)
            ->map(fn (Collection $group) => $group->first())
            ->map(fn (Vehicle $vehicle) => $this->mapVideoData($vehicle))
            ->values();

        return $this->paginateCollection($grouped, $perPage, $page);
    }

    public function getReviews(
        string $provider,
        ?string $makeSlug = null,
        ?string $modelSlug = null,
        ?int $perPage = null,
        int $page = 1
    ): LengthAwarePaginator {
        $perPage = $perPage ?? self::DEFAULT_PER_PAGE;
        $makeId = $makeSlug ? Filter::matchSlugToId('make', $makeSlug) : null;
        $modelId = $modelSlug ? Filter::matchSlugToId('model', $modelSlug) : null;

        $reviews = VehicleReview::query()
            ->where('provider', $provider)
            ->whereNotNull('review')
            ->with(['vehicles' => function ($q) use ($makeId, $modelId) {
                $q->active()
                    ->with(['make', 'model', 'primaryMediaUse.media'])
                    ->when($makeId, fn ($q) => $q->where('make_id', $makeId))
                    ->when($modelId, fn ($q) => $q->where('model_id', $modelId));
            }])
            ->get();

        $filtered = $reviews
            ->filter(fn (VehicleReview $review) => $review->vehicles->isNotEmpty())
            ->map(fn (VehicleReview $review) => $this->mapReviewData($review))
            ->unique('make_model_key')
            ->values();

        return $this->paginateCollection($filtered, $perPage, $page);
    }

    private function paginateCollection(Collection $collection, int $perPage, int $page): LengthAwarePaginator
    {
        $total = $collection->count();
        $items = $collection->slice(($page - 1) * $perPage, $perPage)->values();

        return new LengthAwarePaginator(
            $items,
            $total,
            $perPage,
            $page,
            ['path' => request()->url(), 'query' => request()->query()]
        );
    }


    private function mapVideoData(Vehicle $vehicle): array
    {
        return [
            'video_url' => $vehicle->main_video_url,
            'slug' => '/vehicles/' . $vehicle->slug,
            'title' => $vehicle->title,
            'thumbnail' => $vehicle->getPreviewImage('medium'),
            'make_model_key' => $vehicle->make_id . '-' . $vehicle->model_id,
        ];
    }

    private function mapReviewData(VehicleReview $review): array
    {
        $vehicle = $review->vehicles->first();

        return [
            'review' => $review->review,
            'slug' => '/vehicles/' . $vehicle->slug,
            'title' => $vehicle->title,
            'thumbnail' => $vehicle->getPreviewImage('medium'),
            'make_model_key' => $vehicle->make_id . '-' . $vehicle->model_id,
        ];
    }
}
