<?php

namespace App\Livewire\Projects;

use App\Livewire\Concerns\HasCatalogToast;
use App\Livewire\Forms\ProjectForm;
use App\Models\Project;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\View\View;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
use Livewire\WithPagination;
use Throwable;

#[Layout('layouts.app', ['title' => 'Proyectos', 'header' => 'Proyectos'])]
#[Title('Proyectos')]
class ProjectIndex extends Component
{
    use HasCatalogToast;
    use WithPagination;

    public ProjectForm $form;

    public string $search = '';

    public int $perPage = 10;

    public bool $showModal = false;

    public bool $isEditing = false;

    public ?int $projectId = null;

    public bool $showDeleteConfirm = false;

    public ?int $deleteProjectId = null;

    public function mount(): void
    {
        $this->authorize('viewAny', Project::class);
    }

    /** @return LengthAwarePaginator<int, Project> */
    #[Computed]
    public function projects(): LengthAwarePaginator
    {
        return Project::query()
            ->when($this->search, fn ($query) => $query->where('name', 'like', '%'.$this->search.'%'))
            ->withCount(['sites', 'works'])
            ->orderBy('name')
            ->paginate($this->perPage);
    }

    #[Computed]
    public function totalProjects(): int
    {
        return Project::query()->count();
    }

    #[Computed]
    public function activeProjects(): int
    {
        return Project::query()->where('status', true)->count();
    }

    #[Computed]
    public function inactiveProjects(): int
    {
        return Project::query()->where('status', false)->count();
    }

    public function openCreate(): void
    {
        $this->authorize('create', Project::class);
        $this->isEditing = false;
        $this->projectId = null;
        $this->form->resetForCreate();
        $this->resetErrorBag();
        $this->showModal = true;
    }

    public function openEdit(int $id): void
    {
        $project = Project::query()->find($id);

        if (! $project) {
            $this->showToastMessage('Proyecto no encontrado.', 'error');

            return;
        }

        $this->authorize('update', $project);
        $this->projectId = $project->id;
        $this->isEditing = true;
        $this->form->fillFromModel($project);
        $this->resetErrorBag();
        $this->showModal = true;
    }

    public function save(): void
    {
        if ($this->isEditing) {
            $project = Project::query()->findOrFail($this->projectId);
            $this->authorize('update', $project);
        } else {
            $this->authorize('create', Project::class);
        }

        $this->form->validate(
            $this->form->rules($this->isEditing ? $this->projectId : null),
            $this->form->validationMessages(),
        );

        try {
            if ($this->isEditing) {
                $project = Project::query()->findOrFail($this->projectId);
                $project->update([
                    'name' => trim($this->form->name),
                    'color' => strtoupper(trim($this->form->color)),
                    'status' => $this->form->status,
                ]);
                $message = 'Proyecto actualizado correctamente.';
            } else {
                Project::query()->create([
                    'name' => trim($this->form->name),
                    'color' => strtoupper(trim($this->form->color)),
                    'status' => $this->form->status,
                ]);
                $message = 'Proyecto registrado correctamente.';
            }

            $this->closeModal();
            $this->resetPage();
            $this->showToastMessage($message, 'success');
        } catch (Throwable $e) {
            report($e);
            $this->showToastMessage('No se pudo guardar el proyecto.', 'error');
        }
    }

    public function confirmDelete(int $id): void
    {
        $project = Project::query()->withCount(['sites', 'works'])->find($id);

        if (! $project) {
            $this->showToastMessage('Proyecto no encontrado.', 'error');

            return;
        }

        if ($project->sites_count > 0 || $project->works_count > 0) {
            $this->showToastMessage('No se puede eliminar: el proyecto tiene sitios o trabajos asociados.', 'warning');

            return;
        }

        $this->authorize('delete', $project);
        $this->deleteProjectId = $id;
        $this->showDeleteConfirm = true;
    }

    public function destroy(): void
    {
        if ($this->deleteProjectId === null) {
            return;
        }

        $project = Project::query()->find($this->deleteProjectId);

        if (! $project) {
            $this->closeDeleteModal();
            $this->showToastMessage('Proyecto no encontrado.', 'error');

            return;
        }

        $this->authorize('delete', $project);

        if ($project->sites()->count() > 0 || $project->works()->count() > 0) {
            $this->closeDeleteModal();
            $this->showToastMessage('No se puede eliminar: el proyecto está en uso.', 'warning');

            return;
        }

        $project->delete();
        $this->closeDeleteModal();
        $this->resetPage();
        $this->showToastMessage('Proyecto eliminado correctamente.', 'success');
    }

    public function closeModal(): void
    {
        $this->showModal = false;
        $this->isEditing = false;
        $this->projectId = null;
        $this->form->resetForCreate();
        $this->resetErrorBag();
    }

    public function closeDeleteModal(): void
    {
        $this->showDeleteConfirm = false;
        $this->deleteProjectId = null;
    }

    public function resetSearch(): void
    {
        $this->search = '';
        $this->resetPage();
    }

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

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

    public function render(): View
    {
        return view('livewire.projects.index');
    }
}
