<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

/**
 * PRC-82 — persistent provisioning / module-call log entry.
 */
class ProvisioningLog extends Model
{
    public const STATUS_PENDING = 'pending';

    public const STATUS_RUNNING = 'running';

    public const STATUS_COMPLETED = 'completed';

    public const STATUS_FAILED = 'failed';

    public const STATUS_DISMISSED = 'dismissed';

    public const FAMILY_REGISTRAR = 'registrar';

    public const FAMILY_PRODUCT = 'product';

    public const FAMILY_VM = 'vm';

    public const FAMILY_SSL = 'ssl';

    public const FAMILY_SOFTWARE = 'software';

    public const FAMILY_LICENSE = 'license';

    protected $fillable = [
        'provisioning_id',
        'entity_type',
        'entity_id',
        'module_family',
        'module_name',
        'action',
        'payload',
        'error_message',
        'error_details',
        'response_data',
        'status',
        'attempts',
        'last_attempt_at',
        'next_retry_at',
        'resolved_by_admin_id',
        'resolved_at',
    ];

    protected $casts = [
        'payload' => 'array',
        'error_details' => 'array',
        'response_data' => 'array',
        'attempts' => 'integer',
        'last_attempt_at' => 'datetime',
        'next_retry_at' => 'datetime',
        'resolved_at' => 'datetime',
    ];

    public function scopeFailed($q)
    {
        return $q->where('status', self::STATUS_FAILED);
    }

    public function scopePending($q)
    {
        return $q->whereIn('status', [self::STATUS_PENDING, self::STATUS_RUNNING]);
    }

    public function scopeForEntity($q, string $type, int $id)
    {
        return $q->where('entity_type', $type)->where('entity_id', $id);
    }

    public function scopeDueForRetry($q)
    {
        return $q->where('status', self::STATUS_FAILED)
            ->whereNotNull('next_retry_at')
            ->where('next_retry_at', '<=', now());
    }

    public function isFailed(): bool
    {
        return $this->status === self::STATUS_FAILED;
    }

    public function canRetry(): bool
    {
        $max = (int) Setting::getValue('provisioning_queue_max_retries', 5);

        return $this->isFailed() && $this->attempts < $max;
    }
}
