<?php

namespace App\Http\Livewire\Admin;

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

class Departamentos extends Component
{
    use WithPagination;

    public string $busca = '';
    public string $buscaIcone = '';
    public bool $modalAberto = false;
    public ?int $departamentoEditandoId = null;
    public string $nome = '';
    public string $descricao = '';
    public string $icone = 'building-office-2';
    public bool $ativo = true;

    protected $paginationTheme = 'tailwind';

    public function mount(): void
    {
        abort_unless(Auth::user()?->hasRole('Administrador Master'), 403);
    }

    public function updatedBusca(): void
    {
        $this->resetPage();
    }

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

    public function editar(int $departamentoId): void
    {
        $departamento = Departamento::findOrFail($departamentoId);

        $this->departamentoEditandoId = $departamento->id;
        $this->nome = $departamento->nome;
        $this->descricao = (string) $departamento->descricao;
        $this->icone = $departamento->icone ?: 'building-office-2';
        $this->ativo = (bool) $departamento->ativo;
        $this->modalAberto = true;
    }

    public function salvar(): void
    {
        $dados = $this->validate([
            'nome' => [
                'required',
                'string',
                'max:120',
                Rule::unique('departamentos', 'nome')->ignore($this->departamentoEditandoId),
            ],
            'descricao' => ['nullable', 'string', 'max:1000'],
            'icone' => ['required', 'string', Rule::in(array_keys(config('heroicons', [])))],
            'ativo' => ['boolean'],
        ]);

        Departamento::updateOrCreate(
            ['id' => $this->departamentoEditandoId],
            [
                'nome' => $dados['nome'],
                'slug' => $this->gerarSlugUnico($dados['nome'], $this->departamentoEditandoId),
                'descricao' => $dados['descricao'],
                'icone' => $dados['icone'],
                'ativo' => $dados['ativo'],
            ]
        );

        $this->modalAberto = false;
        $this->resetFormulario();
        $this->dispatchBrowserEvent('notify', ['message' => 'Departamento salvo com sucesso.']);
    }

    public function alternarAtivo(int $departamentoId): void
    {
        $departamento = Departamento::findOrFail($departamentoId);
        $departamento->update(['ativo' => ! $departamento->ativo]);

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

    public function excluir(int $departamentoId): void
    {
        $departamento = Departamento::findOrFail($departamentoId);
        $departamento->delete();

        $this->dispatchBrowserEvent('notify', ['message' => 'Departamento excluido.']);
    }

    public function selecionarIcone(string $icone): void
    {
        abort_unless(array_key_exists($icone, config('heroicons', [])), 404);

        $this->icone = $icone;
    }

    public function render()
    {
        $departamentos = Departamento::query()
            ->withCount(['usuarios', 'subcategorias', 'artigos'])
            ->when($this->busca, function ($query) {
                $termo = '%' . $this->busca . '%';

                $query->where(function ($subQuery) use ($termo) {
                    $subQuery->where('nome', 'like', $termo)
                        ->orWhere('descricao', 'like', $termo);
                });
            })
            ->orderBy('nome')
            ->paginate(10);

        return view('livewire.admin.departamentos', [
            'departamentos' => $departamentos,
            'icones' => $this->iconesDisponiveis(),
            'rotulosIcones' => $this->rotulosIcones(),
            'totalIcones' => count(config('heroicons', [])),
        ])->layout('layouts.module');
    }

    private function iconesDisponiveis(): array
    {
        $icones = array_keys(config('heroicons', []));
        $busca = $this->normalizarBuscaIcone($this->buscaIcone);

        if ($busca !== '') {
            $icones = array_values(array_filter($icones, function (string $icone) use ($busca) {
                $nomeNormalizado = $this->normalizarBuscaIcone($icone);
                $rotulos = $this->normalizarBuscaIcone($this->rotulosIcone($icone));

                return Str::contains($nomeNormalizado, $busca)
                    || Str::contains($rotulos, $busca);
            }));
        }

        if (! in_array($this->icone, $icones, true) && array_key_exists($this->icone, config('heroicons', []))) {
            array_unshift($icones, $this->icone);
        }

        return array_values(array_unique($icones));
    }

    private function normalizarBuscaIcone(string $valor): string
    {
        return Str::of($valor)
            ->ascii()
            ->lower()
            ->replace(['_', '-', '/', '.', ','], ' ')
            ->squish()
            ->toString();
    }

    private function rotulosIcone(string $icone): string
    {
        return "{$icone} " . ($this->rotulosIcones()[$icone] ?? '');
    }

    private function rotulosIcones(): array
    {
        return [
            'academic-cap' => 'treinamento graduacao escola curso educacao',
            'archive-box' => 'arquivo caixa estoque armazenagem',
            'banknotes' => 'financeiro dinheiro pagamento faturamento banco',
            'beaker' => 'farmaceutico laboratorio quimico qualidade',
            'bell' => 'notificacao alerta aviso',
            'book-open' => 'wiki manual conhecimento artigo tutorial',
            'building-office-2' => 'empresa departamento predio escritorio unidade',
            'clipboard-document-check' => 'auditoria checklist conferencia controle qualidade',
            'cog-6-tooth' => 'configuracao sistema ajuste administracao',
            'cube-transparent' => 'modulo portal sistema',
            'document-text' => 'documento emissao nota cte formulario',
            'folder-open' => 'pasta categoria subcategoria arquivo',
            'map-pin' => 'rastreamento localizacao rota mapa entrega',
            'shopping-cart' => 'compras fornecedor cotacao suprimentos',
            'truck' => 'frota transporte veiculo caminhao logistica entrega',
            'users' => 'usuarios pessoas rh equipe cliente colaborador perfil',
            'wrench-screwdriver' => 'manutencao ferramenta ajuste configuracao',
        ];
    }

    private function resetFormulario(): void
    {
        $this->reset(['departamentoEditandoId', 'nome', 'descricao', 'buscaIcone']);
        $this->icone = 'building-office-2';
        $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 (Departamento::where('slug', $slug)->when($ignorarId, fn ($query) => $query->where('id', '!=', $ignorarId))->exists()) {
            $slug = "{$base}-{$contador}";
            $contador++;
        }

        return $slug;
    }
}
