<?php

namespace App\Livewire\Configurations\Environments;

use App\Models\Environments\Type;
use App\Support\LimiteDeSubida;
use Illuminate\Validation\Rule;
use Livewire\Component;
use Livewire\WithFileUploads;

/**
 * Crear un tipo de entorno (MGR-097).
 *
 * **Lo que había**: este componente eran ocho líneas —`render()` y nada más—, mientras su
 * vista tenía el formulario completo con `wire:model="name"`, `"shortname"`,
 * `"description"`, `"image"` y `wire:submit="store"`. Así que la pantalla se abría bien y
 * **reventaba al usarla**: no hacía falta ni enviarla, escribir en el primer campo lanzaba
 * `PublicPropertyNotFoundException`. Nunca ha funcionado —el único commit que tocaba el
 * fichero es `1eae382 Full css change`—, y por eso los cuatro tipos que existen están
 * puestos desde `TypeSeeder`.
 *
 * Es el patrón de `Edit`, que sí estaba completo.
 *
 * **El `shortname` no es una etiqueta: es una clave de la API.** `SyncAction` resuelve el
 * tipo de un entorno con `Type::where('shortname', $datos['type'])`, o sea que ese valor es
 * **el que manda el plugin del cliente** en su `sync`. Un tipo con un shortname que ningún
 * plugin envía nunca no se asigna a nadie, y eso no se ve en ninguna pantalla. Por eso el
 * formulario lo dice.
 */
class Create extends Component
{
    use WithFileUploads;

    public string $name = '';
    public string $shortname = '';
    public ?string $description = null;
    public $image = null;

    public function mount(): void
    {
        // El permiso de la ruta no se reaplica en /livewire/update (MGR-005). En `Edit` se
        // comprueba solo al guardar; aquí también al entrar, que es lo correcto: abrir un
        // formulario que no se va a poder enviar es una pantalla que engaña.
        $this->authorize('admin.configurations.environments-types.create');
    }

    protected function rules(): array
    {
        return [
            'name' => 'required|string|max:200',
            // **Cuenta también los borrados, y no es una elección: lo impone el esquema.**
            // `Type` tiene borrado lógico, así que la fila sigue ahí — y
            // `create_types_table` declara `shortname` con un `unique()` normal, que no
            // distingue borrados. Excluirlos en la validación solo movía el fallo de un
            // mensaje de formulario a una `UniqueConstraintViolationException` de la base.
            // Lo que se puede arreglar es **el mensaje**, que es lo que dice `messages()`.
            'shortname' => ['required', 'string', 'max:20', Rule::unique('types', 'shortname')],
            'description' => 'nullable|string',
            'image' => ['nullable', 'file', 'mimes:jpeg,jpg,png,webp', 'max:' . LimiteDeSubida::enKb()],
        ];
    }

    protected function messages(): array
    {
        return [
            // Se nombra la papelera a propósito: el shortname de un tipo borrado sigue
            // ocupado —el índice de la base no distingue borrados— y sin decirlo el error
            // señala algo que no se ve en ninguna pantalla.
            'shortname.unique' => 'Ese shortname ya está en uso. Es la clave con la que la API reconoce el tipo que manda el plugin, así que no puede repetirse — y sigue ocupado aunque el tipo que lo tenía esté borrado.',
            'image.mimes' => 'La imagen debe ser jpg, png o webp. El SVG no se acepta: puede llevar código y se serviría desde el propio dominio del panel.',
        ];
    }

    public function store()
    {
        $this->authorize('admin.configurations.environments-types.create');

        $validated = $this->validate();

        if ($this->image) {
            // Mismo destino que en `Edit`: `images/environments` del disco público. Los
            // iconos que vienen con la aplicación viven en `images_static/` y no se tocan.
            $validated['image'] = $this->image->store('images/environments', 'public');
        }

        $tipo = Type::create($validated);

        session()->flash('success', 'Tipo de entorno «' . $tipo->name . '» creado. Los entornos lo recibirán cuando su plugin mande «' . $tipo->shortname . '» en el sync.');

        return $this->redirect(route('configurations.catalogs'), navigate: true);
    }

    public function render()
    {
        return view('livewire.configurations.environments.create')
            ->layout('layouts.clean');
    }
}
