<?php

namespace App\Components;

use App\Models\Task;
use App\Services\HistoryService;
use App\Services\TaskService;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Attributes\Lazy;
use Livewire\Component;

#[Lazy]
class TaskManager extends Component {
    use AuthorizesRequests;

    public $tasks;
    public $task;
    public bool $open = false;
    public bool $showAdd = false;
    public int $outstanding = 0;
    public int $overdue = 0;
    public int $soon = 0;
    public int $good = 0;

    public string $title = '';
    public string $description = '';
    public string $due_at = '';

    public ?int $editingTaskId = null;
    public bool $showEdit = false;

    public function mount() {
        $this->load();
    }

    public function showTaskManager() {
        $this->open = true;
        $this->showAdd = false;
    }

    public function hideTaskManager() {
        $this->open = false;
        $this->showAdd = false;
    }

    public function showAddTask() {
        $this->showAdd = true;
    }

    public function hideAddTask() {
        $this->showAdd = false;
    }

    public function addTask(HistoryService $history, TaskService $service) {
        $this->authorize('tasks.create');
        $validated = $this->validate([
            'title' => 'required|string|max:255',
            'description' => 'nullable|string|max:255',
            'due_at' => 'nullable|date|after:now|before:+1 month',
        ]);

        $task = $service->addTask(
            $history,
            $validated['title'],
            $validated['due_at'] ?? null,
            $validated['description'] ?? null
        );

        $this->hideAddTask();

        $this->reset('title', 'description', 'due_at');

        if ($task->due_at->isPast()) {
            $this->overdue++;
        } elseif ($task->due_at->isBefore(now()->addDays(2))) {
            $this->soon++;
        } else {
            $this->good++;
        }

        $this->tasks->push($task);
    }

    public function editTask(int $taskId) {
        $task = Task::where('user_id', auth()->id())->findOrFail($taskId);

        $this->editingTaskId = $task->id;
        $this->title         = $task->title;
        $this->description   = (string) $task->description;
        $this->due_at        = $task->due_at ? $task->due_at->format('Y-m-d\TH:i') : '';
        $this->showEdit      = true;
        $this->showAdd       = false;
    }

    public function updateTask() {
        $this->authorize('tasks.edit');
        $validated = $this->validate([
            'title'       => 'required|string|max:255',
            'description' => 'nullable|string|max:1000',
            'due_at'      => 'nullable|date',
        ]);

        $task = Task::where('user_id', auth()->id())->findOrFail($this->editingTaskId);
        $task->update([
            'title'       => $validated['title'],
            'description' => $validated['description'] ?? null,
            'due_at'      => $validated['due_at'] ?: null,
        ]);

        $this->hideEditTask();
        $this->load();
    }

    public function hideEditTask() {
        $this->showEdit = false;
        $this->reset('title', 'description', 'due_at', 'editingTaskId');
    }

    public function completeTask($taskId) {
        $this->authorize('tasks.complete');
        $task = Task::find($taskId);

        if ($task) {
            $task->update(['completed_at' => now()]);
            $this->load();
        }
    }

    public function deleteTask($taskId) {
        $this->authorize('tasks.delete');
        $task = Task::find($taskId);

        if ($task) {
            $task->delete();
            $this->load();
        }
    }

    public function load() {
        $tasks = Task::with('owner')
            ->where('user_id', auth()->id())
            ->whereNull('completed_at')
            ->orderBy('due_at')
            ->get();

        $this->tasks = $tasks;
        $this->overdue = Task::where('user_id', auth()->id())->whereNull('completed_at')->where('due_at', '<', now())->count();
        $this->soon = Task::where('user_id', auth()->id())->whereNull('completed_at')->whereBetween('due_at', [now(), now()->addDays(2)])->count();
        $this->good = Task::where('user_id', auth()->id())->whereNull('completed_at')->where('due_at', '>', now()->addDays(2))->count();
        $this->outstanding = $this->overdue + $this->good + $this->soon;
    }

    public function placeholder() {
        return <<<HTML
            <div class="placeholder-glow">
                <span class="placeholder col-12 d-block mb-1"></span>
                <span class="placeholder col-9 d-block mb-1"></span>
                <span class="placeholder col-6 d-block"></span>
            </div>
            HTML;

    }

    public function render() {
        return view('components.task-manager');
    }
}
