<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

final class ImpersonationLog extends Model
{
    use HasFactory;

    protected $fillable = [
        'admin_id',
        'target_user_id',
        'start_time',
        'end_time',
        'ip_address',
        'user_agent',
        'status',
        'pages_visited',
        'actions_taken',
    ];

    protected $casts = [
        'start_time' => 'datetime',
        'end_time' => 'datetime',
        'pages_visited' => 'array',
        'actions_taken' => 'array',
    ];

    public function admin(): BelongsTo
    {
        return $this->belongsTo(User::class, 'admin_id');
    }

    public function targetUser(): BelongsTo
    {
        return $this->belongsTo(User::class, 'target_user_id');
    }

    public function getDurationInSecondsAttribute(): ?float
    {
        if (! $this->end_time) {
            return null;
        }

        return $this->start_time->diffInSeconds($this->end_time);
    }

    public function getDurationInMinutesAttribute(): ?int
    {
        $seconds = $this->duration_in_seconds;

        return $seconds ? (int) ceil($seconds / 60) : null;
    }

    public function isActive(): bool
    {
        return $this->status === 'active' && is_null($this->end_time);
    }

    public function isCompleted(): bool
    {
        return $this->status === 'completed' && ! is_null($this->end_time);
    }

    public function isForceTerminated(): bool
    {
        return $this->status === 'force_terminated';
    }

    public function scopeActive($query)
    {
        return $query->where('status', 'active')->whereNull('end_time');
    }

    public function scopeCompleted($query)
    {
        return $query->where('status', 'completed');
    }

    public function scopeForAdmin($query, User $admin)
    {
        return $query->where('admin_id', $admin->id);
    }

    public function scopeForTarget($query, User $target)
    {
        return $query->where('target_user_id', $target->id);
    }

    public function scopeToday($query)
    {
        return $query->whereDate('start_time', today());
    }

    public function scopeThisWeek($query)
    {
        return $query->whereBetween('start_time', [now()->startOfWeek(), now()->endOfWeek()]);
    }

    public function scopeThisMonth($query)
    {
        return $query->whereBetween('start_time', [now()->startOfMonth(), now()->endOfMonth()]);
    }

    public function addPageVisited(string $page): void
    {
        $pages = $this->pages_visited ?? [];
        $pages[] = [
            'page' => $page,
            'timestamp' => now()->toISOString(),
        ];

        $this->update(['pages_visited' => $pages]);
    }

    public function addActionTaken(string $action, array $data = []): void
    {
        $actions = $this->actions_taken ?? [];
        $actions[] = [
            'action' => $action,
            'data' => $data,
            'timestamp' => now()->toISOString(),
        ];

        $this->update(['actions_taken' => $actions]);
    }
}
