<?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\Database\Eloquent\Model;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Lazy;
use Livewire\Component;
use Livewire\WithPagination;

class TaskAssigner extends Component {
    use WithPagination;

    // Use bootstrap for Livewire pagination links
    protected $paginationTheme = 'bootstrap';

    // The polymorphic owner model
    public $owner;

    public bool $showAdd = false;
    public string $filter = 'all'; // Filters: all, overdue, soon, good

    public string $title = '';
    public string $description = '';
    public string $due_at = '';
    public int $assigned_to = 0;

    #[Computed]
    public function users() {
        return User::all()->mapWithKeys(function ($user) {
            return [$user->id => "{$user->name_first} {$user->name_last}"];
        })->toArray();
    }

    #[Computed]
    public function counts() {
        // Base query restricted to this specific polymorphic owner
        $baseQuery = Task::where('owner_type', $this->owner->getMorphClass())
            ->where('owner_id', $this->owner->getKey());

        return [
            'overdue' => (clone $baseQuery)->where('due_at', '<', now())->count(),
            'soon'    => (clone $baseQuery)->whereBetween('due_at', [now(), now()->addDays(2)])->count(),
            'good'    => (clone $baseQuery)->where('due_at', '>', now()->addDays(2))->count(),
        ];
    }

    #[Computed]
    public function tasks() {
        $query = Task::where('owner_type', $this->owner->getMorphClass())
            ->where('owner_id', $this->owner->getKey());

        if ($this->filter === 'overdue') {
            $query->where('due_at', '<', now());
        } elseif ($this->filter === 'soon') {
            $query->whereBetween('due_at', [now(), now()->addDays(2)]);
        } elseif ($this->filter === 'good') {
            $query->where('due_at', '>', now()->addDays(2));
        }

        // Return a paginated list
        return $query->orderBy('due_at', 'asc')->paginate(5);
    }

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

    public function hideAddTask() {
        $this->showAdd = false;
        $this->reset('title', 'description', 'due_at');
    }

    public function addTask(HistoryService $history, TaskService $service) {
        $rules = [
            'title'       => 'required|string|max:255',
            'description' => 'required|string|max:255',
            'due_at'      => 'nullable|date|after:now',
        ];

        if(auth()->user()->can('tasks.admin')) {
            $rules['assigned_to'] = 'nullable|exists:users,id';
        }

        $validated = $this->validate($rules);

        // Create the task using your service
        $task = $service->addTask(
            $history,
            $validated['title'],
            $validated['due_at'] ?: Carbon::now()->addHours(48)->toDateString(),
            $validated['description'] ?? null,
            $validated['assigned_to'] ?? null,
        );

        // Attach the task to the polymorphic owner
        $task->owner_type = $this->owner->getMorphClass();
        $task->owner_id   = $this->owner->getKey();
        $task->save();

        $this->hideAddTask();
        $this->resetPage(); // Reset to the first page so they can see their new task (if applicable)
    }

    public function completeTask($taskId) {
        $task = Task::find($taskId);

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

    public function deleteTask($taskId) {
        $task = Task::find($taskId);

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

    public function setFilter($filter) {
        // Toggle off if they click the active filter again
        $this->filter = ($this->filter === $filter) ? 'all' : $filter;
        $this->resetPage(); // Reset pagination when filter changes
    }

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