<?php

namespace App\Livewire\Media;

use App\Models\Media;
use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use Livewire\WithFileUploads;

class MediaManager extends Component
{
    use WithFileUploads;

    // Polimórfico: a qué entidad pertenece
    public $mediableType;

    public $mediableId;

    public $entity;     // instancia cargada

    public $mediaItems = [];

    // Subida
    public $uploadFiles = [];

    public $uploadDescription = '';

    public $uploadCategory = 'image';

    // Modal visor
    public $showViewer = false;

    public $viewingMedia = null;

    protected $rules = [
        'uploadFiles.*' => 'required|file|max:102400', // 100MB total
        'uploadDescription' => 'nullable|string|max:500',
        'uploadCategory' => 'required|in:image,document,other',
    ];

    protected $messages = [
        'uploadFiles.*.max' => 'Cada archivo debe pesar menos de 100MB.',
    ];

    public function mount($mediableType, $mediableId)
    {
        $this->mediableType = $mediableType;
        $this->mediableId = $mediableId;

        $this->entity = $mediableType::findOrFail($mediableId);
        $this->loadMedia();
    }

    public function loadMedia()
    {
        $this->mediaItems = Media::where('mediable_type', $this->mediableType)
            ->where('mediable_id', $this->mediableId)
            ->with('uploader')
            ->latest()
            ->get();
    }

    public function upload()
    {
        $user = Auth::user();
        if (! $user->can('upload layers')) {
            session()->flash('error', 'Sin permisos.');

            return;
        }

        $this->validate();

        if (empty($this->uploadFiles)) {
            session()->flash('error', 'Selecciona al menos un archivo.');

            return;
        }

        $uploaded = 0;
        foreach ($this->uploadFiles as $file) {
            $mime = $file->getMimeType();
            $ext = $file->getClientOriginalExtension();
            $size = $file->getSize();
            $name = $file->getClientOriginalName();

            // Determinar categoría automática
            $category = $this->uploadCategory;
            if (str_starts_with($mime, 'image/')) {
                $category = 'image';
            } elseif (in_array($mime, ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'])) {
                $category = 'document';
            }

            // Guardar en disco
            $entityType = class_basename($this->entity);
            $dir = "uploads/{$entityType}s/{$this->mediableId}/media";
            $path = $file->store($dir, 'public');

            Media::create([
                'mediable_type' => $this->mediableType,
                'mediable_id' => $this->mediableId,
                'name' => $name,
                'file_path' => $path,
                'file_type' => $mime,
                'file_extension' => $ext,
                'file_size' => $size,
                'category' => $category,
                'description' => $this->uploadDescription,
                'uploaded_by' => $user->id,
            ]);

            $uploaded++;
        }

        $this->reset(['uploadFiles', 'uploadDescription']);
        $this->loadMedia();

        // Notificar al mapa si corresponde
        $this->dispatch('mediaUploaded', [
            'mediableType' => $this->mediableType,
            'mediableId' => $this->mediableId,
        ]);

        session()->flash('message', "$uploaded archivo(s) subido(s) correctamente.");
    }

    public function deleteMedia($mediaId)
    {
        $media = Media::findOrFail($mediaId);

        $user = Auth::user();
        if (! $user->can('delete media') && $media->uploaded_by !== $user->id) {
            session()->flash('error', 'No puedes borrar archivos de otro usuario.');

            return;
        }

        $media->delete();
        $this->loadMedia();
        session()->flash('message', 'Archivo eliminado.');
    }

    public function viewMedia($mediaId)
    {
        $media = Media::findOrFail($mediaId);
        if (! $media->is_image) {
            // Si no es imagen, abrir en nueva pestaña
            $this->dispatch('openUrl', $media->url);

            return;
        }
        $this->viewingMedia = $media;
        $this->showViewer = true;
    }

    public function closeViewer()
    {
        $this->showViewer = false;
        $this->viewingMedia = null;
    }

    public function render()
    {
        return view('livewire.media.media-manager', [
            'entityName' => class_basename($this->entity).': '.($this->entity->name ?? $this->entity->id),
            'images' => $this->mediaItems->filter(fn ($m) => $m->is_image),
            'documents' => $this->mediaItems->filter(fn ($m) => ! $m->is_image),
        ]);
    }
}
