<?php

namespace App\Livewire\Resources;

use App\Models\Resources\Resource;
use App\Models\Resources\ResourceVersion;
use App\Models\Products\Product;
use App\Services\Resources\ResourceFileService;
use Livewire\Component;
use Livewire\WithFileUploads;

class Edit extends Component
{
    use WithFileUploads;

    public Product $product;
    public ResourceVersion $resourceVersion;
    public Resource $resource;
    public string $title = '';
    public ?string $description = null;
    public string $type = 'file';
    public ?string $url = null;
    public $file = null;
    public ?int $read_time = null;
    public bool $is_public = true;
    public string $status = 'draft';
    public ?int $sort_order = null;

    public function mount(Product $product, ResourceVersion $resourceVersion, Resource $resource)
    {
        $this->product = $product;
        $this->resourceVersion = $resourceVersion;
        $this->resource = $resource->load(['resourceVersion.product', 'creator']);

        // Verificar que la versión pertenezca al producto
        if ($this->resourceVersion->product_id !== $this->product->id) {
            abort(404, 'La versión de Recursos no pertenece a este producto.');
        }

        // Verificar que el recurso pertenezca a la versión
        if ($this->resource->resource_version_id !== $this->resourceVersion->id) {
            abort(404, 'El recurso no pertenece a esta versión.');
        }

        $this->title = $resource->title;
        $this->description = $resource->description;
        $this->type = $resource->type;
        $this->url = $resource->url;
        $this->read_time = $resource->read_time;
        $this->is_public = $resource->is_public;
        $this->status = $resource->status;
        $this->sort_order = $resource->sort_order;
    }

    protected function rules()
    {
        $rules = [
            'title' => 'required|string|max:255',
            'description' => 'nullable|string|max:1000',
            'type' => 'required|in:file,external',
            'read_time' => 'nullable|integer|min:0',
            'is_public' => 'required|boolean',
            'status' => 'required|in:draft,published,archived',
            'sort_order' => 'nullable|integer|min:0',
        ];

        // Validaciones condicionales según el tipo
        if ($this->type === 'file') {
            // Si ya tiene un archivo, el nuevo archivo es opcional
            // Si no tiene archivo, es obligatorio
            if (!$this->resource->path) {
                $rules['file'] = 'required|file|mimes:pdf,doc,docx,xls,xlsx,ppt,pptx|max:10240';
            } else {
                $rules['file'] = 'nullable|file|mimes:pdf,doc,docx,xls,xlsx,ppt,pptx|max:10240';
            }
            $rules['url'] = 'nullable|prohibited';
        } else {
            $rules['url'] = 'required|url|max:500';
            $rules['file'] = 'nullable|prohibited';
        }

        return $rules;
    }

    protected function messages()
    {
        return [
            'title.required' => 'El título es obligatorio.',
            'title.max' => 'El título no puede tener más de 255 caracteres.',
            'description.max' => 'La descripción no puede tener más de 1000 caracteres.',
            'type.required' => 'El tipo es obligatorio.',
            'type.in' => 'El tipo debe ser file o external.',
            'file.required' => 'El archivo es obligatorio cuando el tipo es file y no hay archivo existente.',
            'file.file' => 'Debe ser un archivo válido.',
            'file.mimes' => 'El archivo debe ser PDF, DOC, DOCX, XLS, XLSX, PPT o PPTX.',
            'file.max' => 'El archivo no puede ser mayor a 10MB.',
            'url.required' => 'La URL es obligatoria cuando el tipo es external.',
            'url.url' => 'La URL debe tener un formato válido.',
            'url.max' => 'La URL no puede tener más de 500 caracteres.',
            'url.prohibited' => 'La URL no está permitida cuando el tipo es file.',
            'file.prohibited' => 'El archivo no está permitido cuando el tipo es external.',
            'read_time.integer' => 'El tiempo de lectura debe ser un número entero.',
            'read_time.min' => 'El tiempo de lectura debe ser mayor o igual a 0.',
            'is_public.required' => 'La visibilidad es obligatoria.',
            'status.required' => 'El estado es obligatorio.',
            'status.in' => 'El estado debe ser draft, published o archived.',
            'sort_order.integer' => 'El orden debe ser un número entero.',
            'sort_order.min' => 'El orden debe ser mayor o igual a 0.',
        ];
    }

    public function save()
    {
        $this->authorize('admin.resources.edit');
        
        $validated = $this->validate();

        $fileService = app(ResourceFileService::class);

        // Si cambió el tipo de file a external, eliminar el archivo
        if ($this->resource->type === 'file' && $this->type === 'external') {
            if ($this->resource->path) {
                $fileService->deleteAllResourceFiles($this->resource);
            }
        }

        // Si cambió el tipo de external a file, limpiar la URL
        if ($this->resource->type === 'external' && $this->type === 'file') {
            $validated['url'] = null;
        }

        // Actualizar recurso
        $updateData = [
            'title' => $validated['title'],
            'description' => $validated['description'],
            'type' => $validated['type'],
            'url' => $validated['type'] === 'external' ? $validated['url'] : null,
            'read_time' => $validated['read_time'],
            'is_public' => $validated['is_public'],
            'status' => $validated['status'],
            'sort_order' => $validated['sort_order'],
        ];

        // Si es un archivo y se subió uno nuevo, reemplazarlo
        if ($this->type === 'file' && $this->file) {
            // Eliminar archivo anterior si existe
            if ($this->resource->path) {
                $fileService->deleteAllResourceFiles($this->resource);
            }

            // Guardar nuevo archivo
            $filePath = $fileService->storeFile($this->resource, $this->file);
            
            $updateData['path'] = $filePath;
            $updateData['mime'] = $this->file->getMimeType();
            $updateData['original_filename'] = $this->file->getClientOriginalName();
            $updateData['size'] = $this->file->getSize();
        }

        $this->resource->update($updateData);

        session()->flash('success', 'Recurso actualizado correctamente.');

        // Redirigir a la vista de la versión
        return $this->redirect(route('products.resources.version.show', [$this->product, $this->resourceVersion]), navigate: true);
    }

    public function render()
    {
        return view('livewire.resources.edit', [
            'product' => $this->product,
            'resourceVersion' => $this->resourceVersion,
            'resource' => $this->resource,
        ])->layout('layouts.clean');
    }
}

