<?php

namespace Licenzo\Model;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

use Licenzo\Framework\Database\Model;

/**
 * LicenseEvent Model
 *
 * Tracks all license-related events for audit trail and analytics
 */
class LicenseEvent extends Model
{
    protected $table = 'licenzo_license_events';

    public $timestamps = false; // Only has created_at

    // Event type constants
    const EVENT_ACTIVATED = 'activated';
    const EVENT_DEACTIVATED = 'deactivated';
    const EVENT_VALIDATED = 'validated';
    const EVENT_VALIDATION_FAILED = 'validation_failed';
    const EVENT_EXPIRED = 'expired';
    const EVENT_REVOKED = 'revoked';
    const EVENT_RENEWED = 'renewed';
    const EVENT_UPGRADED = 'upgraded';
    const EVENT_DOWNGRADED = 'downgraded';
    const EVENT_SUSPENDED = 'suspended';
    const EVENT_REACTIVATED = 'reactivated';
    const EVENT_HASH_GENERATED = 'hash_generated';
    const EVENT_HASH_VALIDATED = 'hash_validated';
    const EVENT_HASH_INVALID = 'hash_invalid';
    const EVENT_QUOTA_EXCEEDED = 'quota_exceeded';
    const EVENT_INSTANCE_CHANGED = 'instance_changed';
    const EVENT_SECURITY_ALERT = 'security_alert';
    const EVENT_FRAUD_DETECTED = 'fraud_detected';
    const EVENT_DOWNLOADED = 'downloaded';

    // Event source constants
    const SOURCE_API = 'api';
    const SOURCE_ADMIN = 'admin';
    const SOURCE_WEBHOOK = 'webhook';
    const SOURCE_CRON = 'cron';
    const SOURCE_SYSTEM = 'system';

    // Response status constants
    const STATUS_SUCCESS = 'success';
    const STATUS_FAILED = 'failed';
    const STATUS_ERROR = 'error';
    const STATUS_PENDING = 'pending';

    protected $fillable = [
        'license_id',
        'product_id',
        'variation_id',
        'activation_id',
        'product_name',
        'variation_name',
        'event_type',
        'event_source',
        'event_data',
        'instance_identifier',
        'ip_address',
        'user_agent',
        'request_hash',
        'response_status',
        'response_message',
        'response_data',
        'triggered_by',
    ];

    protected $casts = [
        'id'              => 'int',
        'license_id'      => 'int',
        'product_id'      => 'int',
        'variation_id'    => 'int',
        'activation_id'   => 'int',
        'triggered_by'    => 'int',
        'event_data'      => 'array',
        'response_data'   => 'array',
        'created_at'      => 'datetime',
    ];

    // Relationships
    public function license()
    {
        return $this->belongsTo(License::class);
    }

    public function product()
    {
        return $this->belongsTo(Product::class);
    }

    public function variation()
    {
        return $this->belongsTo(ProductVariation::class, 'variation_id');
    }

    public function activation()
    {
        return $this->belongsTo(LicenseActivation::class, 'activation_id');
    }

    // Scopes
    public function scopeActivationEvents($query)
    {
        return $query->whereIn('event_type', [
            static::EVENT_ACTIVATED,
            static::EVENT_DEACTIVATED,
            static::EVENT_REACTIVATED
        ]);
    }

    public function scopeValidationEvents($query)
    {
        return $query->whereIn('event_type', [
            static::EVENT_VALIDATED,
            static::EVENT_VALIDATION_FAILED,
            static::EVENT_HASH_VALIDATED,
            static::EVENT_HASH_INVALID
        ]);
    }

    public function scopeSecurityEvents($query)
    {
        return $query->whereIn('event_type', [
            static::EVENT_SECURITY_ALERT,
            static::EVENT_FRAUD_DETECTED,
            static::EVENT_QUOTA_EXCEEDED
        ]);
    }

    public function scopeByEventType($query, $type)
    {
        return $query->where('event_type', $type);
    }

    public function scopeByInstance($query, $identifier)
    {
        return $query->where('instance_identifier', $identifier);
    }

    public function scopeSuccessful($query)
    {
        return $query->where('response_status', static::STATUS_SUCCESS);
    }

    public function scopeFailed($query)
    {
        return $query->whereIn('response_status', [static::STATUS_FAILED, static::STATUS_ERROR]);
    }

    // Helpers
    public function isActivationEvent(): bool
    {
        return in_array($this->event_type, [
            static::EVENT_ACTIVATED,
            static::EVENT_DEACTIVATED,
            static::EVENT_REACTIVATED
        ]);
    }

    public function isValidationEvent(): bool
    {
        return in_array($this->event_type, [
            static::EVENT_VALIDATED,
            static::EVENT_VALIDATION_FAILED
        ]);
    }

    public function isSecurityEvent(): bool
    {
        return in_array($this->event_type, [
            static::EVENT_SECURITY_ALERT,
            static::EVENT_FRAUD_DETECTED,
            static::EVENT_QUOTA_EXCEEDED
        ]);
    }

    public function isSuccessful(): bool
    {
        return $this->response_status === static::STATUS_SUCCESS;
    }

    public function isFailed(): bool
    {
        return in_array($this->response_status, [static::STATUS_FAILED, static::STATUS_ERROR]);
    }

    /**
     * Sensitive fields that should be masked in event snapshots.
     */
    private static $sensitiveFields = ['license_key', 'activation_hash', 'request_hash'];

    // Static helper to log events
    public static function logEvent(array $data): self
    {
        // Mask sensitive fields in event_data if present
        if (isset($data['event_data']) && is_array($data['event_data'])) {
            foreach (self::$sensitiveFields as $field) {
                if (isset($data['event_data'][$field]) && is_string($data['event_data'][$field]) && strlen($data['event_data'][$field]) > 8) {
                    $data['event_data'][$field] = substr($data['event_data'][$field], 0, 4) . '***' . substr($data['event_data'][$field], -4);
                }
            }
        }

        return static::create($data);
    }
}

