<?php

namespace Licenzo\Model;

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

use Licenzo\Framework\Database\Model;

class SubscriptionEvent extends Model
{
    protected $table = 'licenzo_subscription_events';

    // Status event types
    const EVENT_SUBSCRIPTION_CREATED = 'subscription_created';
    const EVENT_SUBSCRIPTION_ACTIVATED = 'subscription_activated';
    const EVENT_SUBSCRIPTION_PAUSED = 'subscription_paused';
    const EVENT_SUBSCRIPTION_RESUMED = 'subscription_resumed';
    const EVENT_SUBSCRIPTION_CANCELED = 'subscription_canceled';
    const EVENT_SUBSCRIPTION_EXPIRED = 'subscription_expired';
    const EVENT_STATUS_CHANGED = 'status_changed';

    // Trial event types
    const EVENT_TRIAL_STARTED = 'trial_started';
    const EVENT_TRIAL_CONVERTED = 'trial_converted';
    const EVENT_TRIAL_EXPIRED = 'trial_expired';
    const EVENT_TRIAL_EXTENDED = 'trial_extended';

    // License event types
    const EVENT_LICENSE_CREATED = 'license_created';
    const EVENT_LICENSE_ACTIVATED = 'license_activated';
    const EVENT_LICENSE_DEACTIVATED = 'license_deactivated';
    const EVENT_LICENSE_REVOKED = 'license_revoked';
    const EVENT_LICENSE_RENEWED = 'license_renewed';
    const EVENT_LICENSE_EXPIRED = 'license_expired';

    // Schedule event types
    const EVENT_SCHEDULE_CREATED = 'schedule_created';
    const EVENT_SCHEDULE_EXECUTED = 'schedule_executed';
    const EVENT_SCHEDULE_CANCELED = 'schedule_canceled';

    // Product event types
    const EVENT_PRODUCT_UPGRADED = 'product_upgraded';
    const EVENT_PRODUCT_DOWNGRADED = 'product_downgraded';
    const EVENT_PRODUCT_CHANGED = 'product_changed';

    // Payment event types (references)
    const EVENT_PAYMENT_SUCCEEDED = 'payment_succeeded';
    const EVENT_PAYMENT_FAILED = 'payment_failed';
    const EVENT_REFUND_ISSUED = 'refund_issued';

    // Webhook event types (references)
    const EVENT_WEBHOOK_RECEIVED = 'webhook_received';
    const EVENT_WEBHOOK_PROCESSED = 'webhook_processed';

    // Event source constants
    const SOURCE_STRIPE = 'stripe';
    const SOURCE_PAYPAL = 'paypal';
    const SOURCE_WOOCOMMERCE = 'woocommerce';
    const SOURCE_SYSTEM = 'system';
    const SOURCE_ADMIN = 'admin';
    const SOURCE_API = 'api';

    // Event status constants
    const STATUS_PENDING = 'pending';
    const STATUS_PROCESSED = 'processed';
    const STATUS_FAILED = 'failed';

    // Related type constants
    const RELATED_TYPE_TRANSACTION = 'transaction';
    const RELATED_TYPE_WEBHOOK = 'webhook';
    const RELATED_TYPE_LICENSE = 'license';
    const RELATED_TYPE_SCHEDULE = 'schedule';

    protected $fillable = [
        'subscription_id', 'customer_id', 'event_type', 'event_source',
        'event_data', 'related_id', 'related_type', 'status', 'triggered_by'
    ];

    protected $casts = [
        'id' => 'int',
        'subscription_id' => 'int',
        'customer_id' => 'int',
        'related_id' => 'int',
        'triggered_by' => 'int',
        'event_data' => 'array',
        'created_at' => 'datetime'
    ];

    public $timestamps = false; // Only created_at

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

    public function customer()
    {
        return $this->belongsTo(Customer::class);
    }

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

    // Polymorphic relationship
    public function related()
    {
        return $this->morphTo();
    }

    // Scopes - Status Events
    public function scopeStatusEvents($query)
    {
        return $query->where('event_type', 'LIKE', 'subscription_%')
                     ->orWhere('event_type', 'status_changed');
    }

    // Scopes - Trial Events
    public function scopeTrialEvents($query)
    {
        return $query->where('event_type', 'LIKE', 'trial_%');
    }

    // Scopes - License Events
    public function scopeLicenseEvents($query)
    {
        return $query->where('event_type', 'LIKE', 'license_%');
    }

    // Scopes - Schedule Events
    public function scopeScheduleEvents($query)
    {
        return $query->where('event_type', 'LIKE', 'schedule_%');
    }

    // Scopes - Product Events
    public function scopeProductEvents($query)
    {
        return $query->where('event_type', 'LIKE', 'product_%');
    }

    // Scopes - Payment Events
    public function scopePaymentEvents($query)
    {
        return $query->whereIn('event_type', [
            static::EVENT_PAYMENT_SUCCEEDED,
            static::EVENT_PAYMENT_FAILED,
            static::EVENT_REFUND_ISSUED
        ]);
    }

    // Scopes - By Source
    public function scopeBySource($query, $source)
    {
        return $query->where('event_source', $source);
    }

    // Scopes - System Events
    public function scopeSystemEvents($query)
    {
        return $query->where('event_source', static::SOURCE_SYSTEM);
    }

    // Scopes - Admin Events
    public function scopeAdminEvents($query)
    {
        return $query->where('event_source', static::SOURCE_ADMIN);
    }

    // Scopes - Processed
    public function scopeProcessed($query)
    {
        return $query->where('status', static::STATUS_PROCESSED);
    }

    // Scopes - Pending
    public function scopePending($query)
    {
        return $query->where('status', static::STATUS_PENDING);
    }

    // Scopes - Failed
    public function scopeFailed($query)
    {
        return $query->where('status', static::STATUS_FAILED);
    }

    // Helpers
    public function isStatusEvent(): bool
    {
        return str_starts_with($this->event_type, 'subscription_') ||
               $this->event_type === 'status_changed';
    }

    public function isTrialEvent(): bool
    {
        return str_starts_with($this->event_type, 'trial_');
    }

    public function isLicenseEvent(): bool
    {
        return str_starts_with($this->event_type, 'license_');
    }

    public function isScheduleEvent(): bool
    {
        return str_starts_with($this->event_type, 'schedule_');
    }

    public function isProductEvent(): bool
    {
        return str_starts_with($this->event_type, 'product_');
    }

    public function isPaymentEvent(): bool
    {
        return in_array($this->event_type, [
            static::EVENT_PAYMENT_SUCCEEDED,
            static::EVENT_PAYMENT_FAILED,
            static::EVENT_REFUND_ISSUED
        ]);
    }

    public function isSystemTriggered(): bool
    {
        return $this->event_source === static::SOURCE_SYSTEM || is_null($this->triggered_by);
    }

    public function isAdminTriggered(): bool
    {
        return $this->event_source === static::SOURCE_ADMIN && !is_null($this->triggered_by);
    }

    public function isProcessed(): bool
    {
        return $this->status === static::STATUS_PROCESSED;
    }

    public function isPending(): bool
    {
        return $this->status === static::STATUS_PENDING;
    }

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

    // Get event data field
    public function getEventDataField($key, $default = null)
    {
        return $this->event_data[$key] ?? $default;
    }

    // Set event data field
    public function setEventDataField($key, $value)
    {
        $data = $this->event_data ?? [];
        $data[$key] = $value;
        $this->event_data = $data;
    }
}

