<?php

namespace App\Livewire\Admin\Cms;

use FluxCms\Core\Models\CmsMedia;
use FluxCms\Core\Services\MediaConversionService;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\View\View;
use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\WithPagination;

class MediaPicker extends Component
{
    use WithFileUploads;
    use WithPagination;

    public ?int $value = null;

    public string $field = 'media_id';

    public string $type = 'image';

    public string $profile = 'thumbnail';

    public string $label = 'Bild auswählen';

    public bool $showModal = false;

    public string $search = '';

    /** @var array<\Livewire\Features\SupportFileUploads\TemporaryUploadedFile> */
    public array $quickUploads = [];

    public function mount(?int $value = null): void
    {
        $this->value = $value;
    }

    public function openPicker(): void
    {
        $this->showModal = true;
    }

    public function selectMedia(int $id): void
    {
        $media = CmsMedia::find($id);
        if (! $media) {
            return;
        }

        if ($media->isImage() && $this->profile) {
            $service = app(MediaConversionService::class);
            if (! $media->hasConversion($this->profile)) {
                $service->convert($media, $this->profile);
                $media->refresh();
            }
        }

        $this->value = $media->id;
        $this->showModal = false;

        $this->dispatch('media-selected', field: $this->field, mediaId: $media->id, url: $media->getConversionUrl($this->profile));
    }

    public function clearSelection(): void
    {
        $this->value = null;
        $this->dispatch('media-selected', field: $this->field, mediaId: null, url: null);
    }

    public function updatedQuickUploads(): void
    {
        $this->validate([
            'quickUploads' => 'nullable|array|max:5',
            'quickUploads.*' => 'file|mimes:jpeg,jpg,png,gif,webp,svg,pdf,doc,docx|max:10240',
        ]);

        $service = app(MediaConversionService::class);
        $lastMedia = null;

        foreach ($this->quickUploads as $file) {
            $lastMedia = $service->storeUpload($file);

            if ($lastMedia->isImage() && $this->profile) {
                $service->convert($lastMedia, $this->profile);
                $lastMedia->refresh();
            }
        }

        $this->quickUploads = [];

        if ($lastMedia) {
            $this->value = $lastMedia->id;
            $this->showModal = false;

            $this->dispatch('media-selected', field: $this->field, mediaId: $lastMedia->id, url: $lastMedia->getConversionUrl($this->profile));
        }
    }

    public function removeQuickUpload(int $index): void
    {
        if (isset($this->quickUploads[$index])) {
            unset($this->quickUploads[$index]);
            $this->quickUploads = array_values($this->quickUploads);
        }
    }

    public function render(): View
    {
        return view('livewire.admin.cms.media-picker', [
            'selectedMedia' => $this->resolveSelectedMedia(),
            'mediaItems' => $this->resolveMediaItems(),
        ]);
    }

    private function resolveSelectedMedia(): ?CmsMedia
    {
        if (! $this->value) {
            return null;
        }

        return CmsMedia::find($this->value);
    }

    /**
     * @return LengthAwarePaginator<int, CmsMedia>
     */
    private function resolveMediaItems(): LengthAwarePaginator
    {
        return CmsMedia::query()
            ->when($this->type === 'image', fn ($q) => $q->images())
            ->when($this->type === 'pdf', fn ($q) => $q->pdfs())
            ->when($this->type === 'document', fn ($q) => $q->documents())
            ->when($this->search, fn ($q) => $q->where('filename', 'like', "%{$this->search}%"))
            ->orderByDesc('created_at')
            ->paginate(18);
    }
}
