<?php

namespace App\Models\Task;

use App\Models\Agency\Agency;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Task extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'tasks';

    public const STATUS_PENDING = 'pending';
    public const STATUS_IN_PROGRESS = 'in_progress';
    public const STATUS_COMPLETED = 'completed';
    public const STATUS_CANCELLED = 'cancelled';

    public const PRIORITY_LOW = 'low';
    public const PRIORITY_NORMAL = 'normal';
    public const PRIORITY_HIGH = 'high';
    public const PRIORITY_URGENT = 'urgent';

    /** Durum → [etiket, rozet rengi] */
    public const STATUSES = [
        self::STATUS_PENDING => ['label' => 'Bekliyor', 'color' => '#f59e0b'],
        self::STATUS_IN_PROGRESS => ['label' => 'Devam Ediyor', 'color' => '#4f46e5'],
        self::STATUS_COMPLETED => ['label' => 'Tamamlandı', 'color' => '#16a34a'],
        self::STATUS_CANCELLED => ['label' => 'İptal', 'color' => '#64748b'],
    ];

    /** Öncelik → [etiket, renk] */
    public const PRIORITIES = [
        self::PRIORITY_LOW => ['label' => 'Düşük', 'color' => '#94a3b8'],
        self::PRIORITY_NORMAL => ['label' => 'Normal', 'color' => '#4f46e5'],
        self::PRIORITY_HIGH => ['label' => 'Yüksek', 'color' => '#f59e0b'],
        self::PRIORITY_URGENT => ['label' => 'Acil', 'color' => '#ef4444'],
    ];

    protected $fillable = [
        'agency_id',
        'title',
        'description',
        'status',
        'priority',
        'due_date',
        'completed_at',
        'completed_by',
        'archived_at',
        'archived_by',
        'is_auto',
        'trigger_key',
        'automation_key',
        'sort_order',
        'context',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'due_date' => 'datetime',
        'completed_at' => 'datetime',
        'archived_at' => 'datetime',
        'is_auto' => 'boolean',
        'context' => 'array',
    ];

    protected static function boot()
    {
        parent::boot();

        static::creating(function (self $task) {
            // Otomatik (sistem) görevlerinde created_by null kalır; agency_id motor tarafından verilir
            if ($task->is_auto) {
                return;
            }
            if (auth()->check()) {
                $task->created_by = $task->created_by ?? auth()->id();
                $task->agency_id = $task->agency_id ?? auth()->user()->currentAgencyId();
            }
        });

        static::updating(function (self $task) {
            if (auth()->check()) {
                $task->updated_by = auth()->id();
            }
        });
    }

    // ================= İlişkiler =================

    public function agency()
    {
        return $this->belongsTo(Agency::class);
    }

    public function assignees()
    {
        return $this->belongsToMany(User::class, 'task_assignees')
            ->withPivot('role')
            ->withTimestamps();
    }

    public function relations()
    {
        return $this->hasMany(TaskRelation::class);
    }

    public function comments()
    {
        return $this->hasMany(TaskComment::class)->latest();
    }

    public function primaryRelation()
    {
        return $this->hasOne(TaskRelation::class)->where('is_primary', true);
    }

    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function completer()
    {
        return $this->belongsTo(User::class, 'completed_by');
    }

    public function archiver()
    {
        return $this->belongsTo(User::class, 'archived_by');
    }

    // ================= Scope'lar =================

    public function scopeByAgency($query, ?int $agencyId)
    {
        return $query->where('tasks.agency_id', $agencyId);
    }

    /** Kullanıcının atanmış olduğu görevler (watcher hariç). */
    public function scopeAssignedTo($query, int $userId)
    {
        return $query->whereHas('assignees', function ($q) use ($userId) {
            $q->where('users.id', $userId)
                ->where('task_assignees.role', 'assignee');
        });
    }

    /** Açık görevler (bekliyor + devam ediyor). */
    public function scopeOpen($query)
    {
        return $query->whereIn('tasks.status', [self::STATUS_PENDING, self::STATUS_IN_PROGRESS]);
    }

    /** Açık ve süresi geçmemiş. */
    public function scopePendingNotOverdue($query)
    {
        return $query->open()->where(function ($q) {
            $q->whereNull('tasks.due_date')->orWhere('tasks.due_date', '>=', now());
        });
    }

    /** Açık ve süresi geçmiş. */
    public function scopeOverdue($query)
    {
        return $query->open()->where('tasks.due_date', '<', now());
    }

    public function scopeCompleted($query)
    {
        return $query->where('tasks.status', self::STATUS_COMPLETED);
    }

    public function scopeCompletedToday($query)
    {
        return $query->completed()->where('tasks.completed_at', '>=', now()->startOfDay());
    }

    public function scopeDueToday($query)
    {
        return $query->open()->whereBetween('tasks.due_date', [now()->startOfDay(), now()->endOfDay()]);
    }

    public function scopeArchived($query)
    {
        return $query->whereNotNull('tasks.archived_at');
    }

    public function scopeNotArchived($query)
    {
        return $query->whereNull('tasks.archived_at');
    }

    // ================= Yardımcılar =================

    public function isOverdue(): bool
    {
        return in_array($this->status, [self::STATUS_PENDING, self::STATUS_IN_PROGRESS], true)
            && $this->due_date !== null
            && $this->due_date->isPast();
    }

    public function markCompleted(?int $userId = null): void
    {
        $this->update([
            'status' => self::STATUS_COMPLETED,
            'completed_at' => now(),
            'completed_by' => $userId ?? auth()->id(),
        ]);
    }

    public function isArchived(): bool
    {
        return $this->archived_at !== null;
    }

    public function archive(?int $userId = null): void
    {
        $this->update([
            'archived_at' => now(),
            'archived_by' => $userId ?? auth()->id(),
        ]);
    }

    public function unarchive(): void
    {
        $this->update([
            'archived_at' => null,
            'archived_by' => null,
        ]);
    }

    public function statusMeta(): array
    {
        return self::STATUSES[$this->status] ?? self::STATUSES[self::STATUS_PENDING];
    }

    public function priorityMeta(): array
    {
        return self::PRIORITIES[$this->priority] ?? self::PRIORITIES[self::PRIORITY_NORMAL];
    }
}
