<?php

namespace Zoomyboy\MedialibraryHelper;

use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Attributes\MapOutputName;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\MediaCollections\MediaCollection;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

#[MapInputName(SnakeCaseMapper::class)]
#[MapOutputName(SnakeCaseMapper::class)]
class MediaData extends Data
{
    public ?int $id;

    public string $originalUrl;

    public int $size;

    public string $name;

    public string $collectionName;

    public string $fileName;

    public string $mimeType;

    #[MapInputName('custom_properties')]
    public array $properties;

    public array $conversions = [];

    public bool $fallback = false;

    public bool $isDeferred = false;

    public static function fromMedia(Media $media): self
    {
        $conversions = collect($media->getMediaConversionNames())->flip()->map(
            fn ($integer, $conversion) => $media->hasGeneratedConversion($conversion)
                ? ['original_url' => $media->getFullUrl($conversion)]
                : null,
        );

        return self::withoutMagicalCreationFrom([
            ...$media->toArray(),
            'conversions' => $conversions->toArray(),
        ]);
    }

    public function with(): array
    {
        $mime = Str::slug($this->mimeType);

        return [
            'icon' => Storage::disk('public')->url("filetypes/{$mime}.svg"),
        ];
    }

    public static function defaultFromCollection(HasMedia $parent, MediaCollection $collection): ?self
    {
        $default = $collection->runCallback('withFallback', $parent);

        if (is_null($default)) {
            return null;
        }

        return static::from([
            'id' => null,
            'originalUrl' => Storage::disk($default[1])->url($default[0]),
            'size' => -1,
            'collection_name' => $collection->name,
            'name' => pathinfo($default[0], PATHINFO_FILENAME),
            'file_name' => pathinfo($default[0], PATHINFO_BASENAME),
            'properties' => [],
            'fallback' => true,
            'mime_type' => Storage::disk($default[1])->mimeType($default[0]),
        ]);
    }
}
