<?php

namespace App\Components\Task;

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

class TaskHub extends Component {
    use AuthorizesRequests;
    public $userId = '';
    public $timeframe = 'all';
    public bool $groupByUser = true;

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

    public $editingTaskId = null;
    public bool $showEditOffcanvas = false;

    #[Computed]
    public function manageableUsers() {
        // Order by last name then first name for professional sorting
        return User::orderBy('name_last')->orderBy('name_first')->get();
    }

    #[Computed]
    public function tasks() {
        $query = Task::with(['user', 'owner'])->latest();

        if ($this->userId) {
            $query->where('user_id', $this->userId);
        }

        if ($this->timeframe === 'day') {
            $query->whereDate('due_at', Carbon::today());
        } elseif ($this->timeframe === 'week') {
            $query->whereBetween('due_at', [Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()]);
        }

        $collection = $query->get();

        if ($this->groupByUser) {
            return $collection->groupBy(function ($task)
            {
                return $task->user
                    ? "{$task->user->name_first} {$task->user->name_last}"
                    : 'Unassigned';
            });
        }

        return $collection;
    }

    public function editTask($taskId) {
        $task = Task::findOrFail($taskId);
        $this->editingTaskId = $taskId;

        // Fill the form fields
        $this->target_user_id = $task->user_id;
        $this->title = $task->title;
        $this->description = $task->description;
        $this->due_at = $task->due_at ? $task->due_at->format('Y-m-d\TH:i') : '';

        $this->showEditOffcanvas = true;
    }

    public function updateTask() {
        $this->authorize('tasks.edit');
        $this->validate([
            'title' => 'required|min:3',
            'target_user_id' => 'required|exists:users,id',
            'due_at' => 'required|date',
        ]);

        $task = \App\Models\Task::findOrFail($this->editingTaskId);
        $task->update([
            'user_id' => $this->target_user_id,
            'title' => $this->title,
            'description' => $this->description,
            'due_at' => $this->due_at,
        ]);

        $this->closeOffcanvas();
    }

    public function closeOffcanvas() {
        $this->showEditOffcanvas = false;
        $this->reset(['title', 'description', 'due_at', 'target_user_id', 'editingTaskId']);
    }

    public function addTask(HistoryService $history, TaskService $service) {
        $this->authorize('tasks.admin');
        $this->validate([
            'title' => 'required|min:3',
            'target_user_id' => 'required|exists:users,id',
            'due_at' => 'required|date|after:now|before:+1 month',
            'description' => 'nullable|string|max:1000',
        ]);

        $service->addTask(
            $history,
            $this->title,
            $this->due_at,
            $this->description,
            $this->target_user_id
        );

        $this->reset(['title', 'description', 'due_at', 'target_user_id']);
    }

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

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

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

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

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