<?php

namespace App\Http\Livewire\Wiki;

use App\Models\Departamento;
use App\Models\Subcategoria;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use Livewire\Component;

class SubcategoriaManager extends Component
{
    public int $departamentoId;
    public bool $modalAberto = false;
    public ?int $subcategoriaEditandoId = null;
    public string $nome = '';
    public bool $ativo = true;

    protected $listeners = [
        'abrirGestaoSubcategorias' => 'abrir',
    ];

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

    public function abrir(): void
    {
        $this->autorizar();
        $this->modalAberto = true;
    }

    public function editar(int $subcategoriaId): void
    {
        $this->autorizar();

        $subcategoria = $this->subcategoriasQuery()->findOrFail($subcategoriaId);
        $this->subcategoriaEditandoId = $subcategoria->id;
        $this->nome = $subcategoria->nome;
        $this->ativo = (bool) $subcategoria->ativo;
    }

    public function salvar(): void
    {
        $this->autorizar();

        $dados = $this->validate([
            'nome' => [
                'required',
                'string',
                'max:120',
                Rule::unique('subcategorias', 'nome')
                    ->where('departamento_id', $this->departamentoId)
                    ->ignore($this->subcategoriaEditandoId),
            ],
            'ativo' => ['boolean'],
        ]);

        Subcategoria::updateOrCreate(
            ['id' => $this->subcategoriaEditandoId],
            [
                'departamento_id' => $this->departamentoId,
                'nome' => $dados['nome'],
                'slug' => $this->gerarSlugUnico($dados['nome'], $this->subcategoriaEditandoId),
                'ativo' => $dados['ativo'],
            ]
        );

        $this->resetFormulario();
        $this->emitUp('subcategoriasAtualizadas');
        $this->dispatchBrowserEvent('notify', ['message' => 'Subcategoria salva.']);
    }

    public function alternarAtivo(int $subcategoriaId): void
    {
        $this->autorizar();

        $subcategoria = $this->subcategoriasQuery()->findOrFail($subcategoriaId);
        $subcategoria->update(['ativo' => ! $subcategoria->ativo]);

        $this->emitUp('subcategoriasAtualizadas');
        $this->dispatchBrowserEvent('notify', ['message' => 'Status atualizado.']);
    }

    public function excluir(int $subcategoriaId): void
    {
        $this->autorizar();

        $subcategoria = $this->subcategoriasQuery()->findOrFail($subcategoriaId);
        $subcategoria->delete();

        $this->emitUp('subcategoriasAtualizadas');
        $this->dispatchBrowserEvent('notify', ['message' => 'Subcategoria excluida.']);
    }

    public function cancelarEdicao(): void
    {
        $this->resetFormulario();
    }

    public function render()
    {
        return view('livewire.wiki.subcategoria-manager', [
            'departamento' => Departamento::findOrFail($this->departamentoId),
            'subcategorias' => $this->subcategoriasQuery()
                ->withCount('artigos')
                ->orderBy('nome')
                ->get(),
            'podeGerenciar' => $this->podeGerenciar(),
        ]);
    }

    private function subcategoriasQuery()
    {
        return Subcategoria::where('departamento_id', $this->departamentoId);
    }

    private function autorizar(): void
    {
        abort_unless($this->podeGerenciar(), 403);
    }

    private function podeGerenciar(): bool
    {
        return Auth::user()?->hasRole('Administrador Master')
            || Auth::user()?->can('departamentos.gerenciar');
    }

    private function resetFormulario(): void
    {
        $this->reset(['subcategoriaEditandoId', 'nome']);
        $this->ativo = true;
        $this->resetValidation();
    }

    private function gerarSlugUnico(string $nome, ?int $ignorarId = null): string
    {
        $base = Str::slug($nome) ?: Str::random(8);
        $slug = $base;
        $contador = 2;

        while (Subcategoria::where('departamento_id', $this->departamentoId)
            ->where('slug', $slug)
            ->when($ignorarId, fn ($query) => $query->where('id', '!=', $ignorarId))
            ->exists()) {
            $slug = "{$base}-{$contador}";
            $contador++;
        }

        return $slug;
    }
}
