<?php

namespace Tests\Support;

use App\Jobs\ImportImageUrlList;
use Illuminate\Database\Eloquent\Collection;
use Mtc\MercuryDataModels\Media;
use Mtc\MercuryDataModels\MediaUse;
use Mtc\MercuryDataModels\Vehicle;

/**
 * Helpers for tests that exercise the AutoTrader image sync.
 */
trait InteractsWithAutoTraderMedia
{
    /**
     * Run the AutoTrader image sync job exactly as
     * AutoTraderApiToVehicleImport::importImages() dispatches it: the image
     * URL list in AT order plus additionalData keyed by URL.
     *
     * @param Vehicle $vehicle
     * @param Media[] $mediaInAutoTraderOrder
     */
    protected function runAutoTraderImageSync(Vehicle $vehicle, array $mediaInAutoTraderOrder): void
    {
        $imageList = collect($mediaInAutoTraderOrder)->mapWithKeys(fn (Media $media) => [
            $media->source_filename => [
                'description' => null,
                'caption' => null,
                'interior' => false,
                'exterior' => false,
                'auto_trader_id' => $media->auto_trader_id,
            ],
        ]);

        (new ImportImageUrlList(
            $imageList->keys(),
            $vehicle,
            [
                'imageProvider' => 'auto-trader',
                'additionalData' => $imageList->toArray(),
            ]
        ))->handle();
    }

    /**
     * Run the image sync job for a non-AutoTrader provider: the image URL list
     * in feed order plus additionalData keyed by URL.
     *
     * @param Vehicle $vehicle
     * @param string $provider
     * @param Media[] $mediaInFeedOrder
     */
    protected function runProviderImageSync(Vehicle $vehicle, string $provider, array $mediaInFeedOrder): void
    {
        $imageList = collect($mediaInFeedOrder)->mapWithKeys(fn (Media $media) => [
            $media->source_filename => [
                'description' => null,
                'caption' => null,
            ],
        ]);

        (new ImportImageUrlList(
            $imageList->keys(),
            $vehicle,
            [
                'imageProvider' => $provider,
                'additionalData' => $imageList->toArray(),
            ]
        ))->handle();
    }

    /**
     * A provider-supplied image that already exists in the media library, so
     * the sync job matches it instead of downloading the file.
     */
    protected function providerMedia(string $provider, string $reference): Media
    {
        $created = Media::factory()->create([
            'external' => true,
            'image_provider' => $provider,
            'src' => $reference . '.jpg',
            'source_filename' => 'https://cdn.example.com/' . $reference . '.jpg',
        ]);

        /** @var Media $media */
        $media = Media::query()->findOrFail($created->id);

        return $media;
    }

    /**
     * An AutoTrader-provided image that already exists in the media library,
     * so the sync job matches it instead of downloading the file.
     */
    protected function autoTraderMedia(string $autoTraderId): Media
    {
        $created = Media::factory()->create([
            'external' => true,
            'image_provider' => 'auto-trader',
            'src' => $autoTraderId . '.jpg',
            'source_filename' => 'https://m.atcdn.co.uk/a/' . $autoTraderId . '.jpg',
        ]);

        /** @var Media $media */
        $media = Media::query()->findOrFail($created->id);
        $media->update(['auto_trader_id' => $autoTraderId]);

        return $media;
    }

    protected function primaryUses(Vehicle $vehicle): Collection
    {
        return MediaUse::query()
            ->where('owner_type', $vehicle->getMorphClass())
            ->where('owner_id', $vehicle->id)
            ->where('primary', true)
            ->get();
    }

    protected function useFor(Vehicle $vehicle, int $mediaId): MediaUse
    {
        return MediaUse::query()
            ->where('owner_type', $vehicle->getMorphClass())
            ->where('owner_id', $vehicle->id)
            ->where('media_id', $mediaId)
            ->firstOrFail();
    }
}
