<?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 isPensionCase(): bool {
        return $this->owner instanceof \App\Models\PensionCase\PensionCase;
    }

    #[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::withoutGlobalScope('outstanding')
        ->where('owner_type', $this->owner->getMorphClass())
        ->where('owner_id', $this->owner->getKey());

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

    return $query
        ->orderByRaw('completed_at IS NOT NULL')
        ->orderBy('due_at', 'asc')
        ->paginate(5);
    }

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

    public function applyUpdateClientTemplate() {
        $this->title = Task::UPDATE_CLIENT_TITLE;
        $this->description = '3-monthly client update — contact the client.';
        $this->due_at = now()->addMonths(3)->format('Y-m-d\TH:i');
        $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);
    
        $service->addTask(
            $history,
            $this->owner,
            $validated['title'],
            $validated['due_at'] ?: Carbon::now()->addHours(48)->toDateString(),
            $validated['description'] ?? null,
            $validated['assigned_to'] ?? null,
        );
    
        $this->hideAddTask();
        $this->resetPage();
    }

    public function completeTask($taskId, HistoryService $history, TaskService $service)
    {
        $task = Task::withoutGlobalScope('outstanding')
        ->where('owner_type', $this->owner->getMorphClass())
        ->where('owner_id', $this->owner->getKey())
        ->findOrFail($taskId);

        $service->completeTask($history, $task, $this->owner);

        $this->resetPage();
    }

    public function deleteTask($taskId) {
        $task = Task::withoutGlobalScope('outstanding')
        ->where('owner_type', $this->owner->getMorphClass())
        ->where('owner_id', $this->owner->getKey())
        ->findOrFail($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');
    }
}