<?php

namespace Licenzo\Model;

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

use Licenzo\Framework\Database\Model;
use Licenzo\Traits\QueryBuilder\HasSearch;

/**
 * License Model
 *
 * Represents Licenzo licenses for WordPress users or external customers
 */
class License extends Model
{
    use HasSearch;

    protected $searchables = [
        'license_key',
        'status',
    ];

    // Ensure computed attributes are included in API responses
    protected $appends = [];

    /**
     * Table name
     */
    protected $table = 'licenzo_licenses';

    /**
     * Primary key
     */
    protected $primaryKey = 'id';

    // Status constants
    const STATUS_ACTIVE = 'active';
    const STATUS_INACTIVE = 'inactive';
    const STATUS_EXPIRED = 'expired';
    const STATUS_SUSPENDED = 'suspended';
    const STATUS_REVOKED = 'revoked';

    /**
     * Fillable attributes
     */
    protected $fillable = [
        'uuid',
        'license_key',
        'customer_id',
        'subscription_id',
        'activation_count',
        'activation_limit',
        'expire_date',
        'support_till',
        'activated_at',
        'config',
        'status',
        'created_at',
        'updated_at'
    ];

    /**
     * Attributes that should be cast
     */
    protected $casts = [
        'id'               => 'int',
        'customer_id'      => 'int',
        'subscription_id'  => 'int',
        'activation_count' => 'int',
        'activation_limit' => 'int',
        'expire_date'      => 'datetime',
        'support_till'     => 'datetime',
        'activated_at'     => 'datetime',
        'config'           => 'array',
        'created_at'       => 'datetime',
        'updated_at'       => 'datetime'
    ];

    /**
     * Enforce license-under-subscription invariant.
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            if (empty($model->subscription_id)) {
                throw new \InvalidArgumentException('Subscription is required for license creation.');
            }

            $subscription = Subscription::find((int) $model->subscription_id);
            if (!$subscription) {
                throw new \InvalidArgumentException('Subscription not found for this license.');
            }

            if (!empty($model->customer_id) && (int) $model->customer_id !== (int) $subscription->customer_id) {
                throw new \InvalidArgumentException('License customer must match subscription customer.');
            }
        });
    }

    /**
     * Get the customer that owns this license
     */
    public function customer()
    {
        return $this->belongsTo(Customer::class, 'customer_id');
    }

    /**
     * Get the subscription that owns this license
     */
    public function subscription()
    {
        return $this->belongsTo(Subscription::class, 'subscription_id');
    }

    /**
     * Get all activations for this license
     */
    public function activations()
    {
        return $this->hasMany(LicenseActivation::class, 'license_id');
    }

    public function licenseProducts()
    {
        return $this->hasMany(LicenseProduct::class, 'license_id');
    }

    public function events()
    {
        return $this->hasMany(LicenseEvent::class);
    }

    /**
     * Scope to get only subscription-based licenses
     */
    public function scopeSubscriptionBased($query)
    {
        return $query->whereNotNull('subscription_id');
    }

    /**
     * Scope to get only standalone licenses
     */
    public function scopeStandalone($query)
    {
        return $query->whereNull('subscription_id');
    }

    /**
     * Check if license is subscription-based
     */
    public function isSubscriptionBased(): bool
    {
        return !is_null($this->subscription_id);
    }

    /**
     * Check if license is standalone
     */
    public function isStandalone(): bool
    {
        return is_null($this->subscription_id);
    }
}
