<?php

/** @noinspection PhpUnhandledExceptionInspection */

/** @noinspection PhpDuplicateMatchArmBodyInspection */

namespace DefStudio\GameEngine\Models\Concerns;

use Spatie\MediaLibrary\InteractsWithMedia;
use DefStudio\GameEngine\Enums\MediaCollection;
use DefStudio\GameEngine\Enums\MediaConversion;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

trait HasMedia
{
    use InteractsWithMedia {
        getMedia as getMediaFromSpatie;
        getFirstMedia as getFirstMediaFromSpatie;
        getFirstMediaUrl as getFirstMediaUrlFromSpatie;
    }

    private function register_media_collection(MediaCollection $collection): void
    {
        match ($collection) {
            MediaCollection::icon => $this
                ->addMediaCollection(MediaCollection::icon->name)
                ->singleFile()
                ->withResponsiveImages()
                ->registerMediaConversions(function(): void {
                    $this->register_standard_media_conversions();
                }),
            MediaCollection::background => $this
                ->addMediaCollection(MediaCollection::background->name)
                ->singleFile()
                ->registerMediaConversions(function(): void {
                    $this->addMediaConversion(MediaConversion::thumb->name)
                        ->nonQueued()
                        ->crop('crop-center', 64, 64)
                        ->quality(80)
                        ->sharpen(10);
                }),
            MediaCollection::avatar => $this
                ->addMediaCollection(MediaCollection::avatar->name)
                ->singleFile()
                ->withResponsiveImages()
                ->registerMediaConversions(function(): void {
                    $this->addMediaConversion(MediaConversion::thumb->name)
                        ->nonQueued()
                        ->crop('crop-center', 64, 64)
                        ->quality(80)
                        ->sharpen(10);
                }),
            MediaCollection::placeholder => $this
                ->addMediaCollection(MediaCollection::placeholder->name)
                ->singleFile(),
            MediaCollection::placeholder_active => $this
                ->addMediaCollection(MediaCollection::placeholder_active->name)
                ->singleFile(),
            MediaCollection::placeholder_complete => $this
                ->addMediaCollection(MediaCollection::placeholder_complete->name)
                ->singleFile(),
            MediaCollection::cover => $this
                ->addMediaCollection(MediaCollection::cover->name)
                ->singleFile()
                ->withResponsiveImages()
                ->registerMediaConversions(function(): void {
                    $this->addMediaConversion(MediaConversion::thumb->name)
                        ->nonQueued()
                        ->crop('crop-center', 64, 64)
                        ->quality(80)
                        ->sharpen(10);
                }),
            MediaCollection::assets => $this
                ->addMediaCollection(MediaCollection::assets->name)
                ->withResponsiveImages()
                ->registerMediaConversions(function(): void {
                    $this->register_standard_media_conversions();
                }),
            MediaCollection::base_image => $this
                ->addMediaCollection(MediaCollection::base_image->name)
                ->singleFile()
                ->registerMediaConversions(function(): void {
                    $this->addMediaConversion(MediaConversion::thumb->name)
                        ->nonQueued()
                        ->crop('crop-center', 64, 64)
                        ->quality(80)
                        ->sharpen(10);
                }),
            MediaCollection::tile_placeholders => $this
                ->addMediaCollection(MediaCollection::tile_placeholders->name)
                ->registerMediaConversions(function(): void {
                    $this->addMediaConversion(MediaConversion::thumb->name)
                        ->nonQueued()
                        ->crop('crop-center', 64, 64)
                        ->quality(80)
                        ->sharpen(10);
                }),
        };
    }

    public function enable_media_collection(MediaCollection $collection): void
    {
        $this->media_collections = collect($this->media_collections)
            ->push($collection)
            ->unique()
            ->toArray();
    }

    public function registerMediaCollections(): void
    {
        collect($this->media_collections)
            ->map(fn(MediaCollection $collection) => $this->register_media_collection($collection));
    }

    public function getMedia(MediaCollection|string $collection = 'default', array|callable $filters = []): \Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection
    {
        $collection = $collection instanceof MediaCollection ? $collection->name : $collection;

        return $this->getMediaFromSpatie($collection, $filters);
    }

    public function getFirstMedia(MediaCollection|string $collection, $filters = []): ?Media
    {
        $collection = $collection instanceof MediaCollection ? $collection->name : $collection;

        return $this->getFirstMediaFromSpatie($collection, $filters);
    }

    public function getFirstMediaUrl(MediaCollection|string $collection, MediaConversion|string $conversion = null): string
    {
        $collection = $collection instanceof MediaCollection ? $collection->name : $collection;
        $conversion = $conversion instanceof MediaConversion ? $conversion->name : $conversion;

        return $this->getFirstMediaUrlFromSpatie($collection, $conversion ?? '');
    }

    private function register_standard_media_conversions(): void
    {
        $this->addMediaConversion(MediaConversion::thumb->name)
            ->nonQueued()
            ->crop('crop-center', 64, 64)
            ->quality(80)
            ->sharpen(10);
        $this->addMediaConversion(MediaConversion::small->name)
            ->crop('crop-center', 128, 128)
            ->quality(80)
            ->sharpen(10);
        $this->addMediaConversion(MediaConversion::medium->name)
            ->crop('crop-center', 256, 256)
            ->sharpen(10);
        $this->addMediaConversion(MediaConversion::large->name)
            ->crop('crop-center', 512, 512)
            ->sharpen(10);
    }
}
