<?php

namespace Modules\AppManager\Entities; // Corrected namespace based on other AppManager models

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Str;

class License extends Model
{
    use HasFactory;

    protected $table = 'am_licenses';

    protected $fillable = [
        'managed_script_id',
        'license_key',
        'type',
        'customer_email',
        'customer_name',
        'purchase_code',
        'activation_limit',
        'current_activations',
        'status',
        'expires_at',
        'supported_until',
        'metadata',
        'notes', // Added notes
    ];

    protected $casts = [
        'expires_at' => 'datetime',
        'supported_until' => 'datetime',
        'metadata' => 'array',
        // 'is_boilerplate_core_license' => 'boolean', // Example if you have such a field, ensure it's in fillable if mass assignable
    ];

    // If you have a factory, uncomment and point to the correct path
    // protected static function newFactory()
    // {
    //     return \Modules\AppManager\Database\factories\LicenseFactory::new();
    // }

    public function managedScript(): BelongsTo
    {
        return $this->belongsTo(ManagedScript::class);
    }

    public function activationLogs(): HasMany
    {
        // Assuming ActivationLog model is in the same namespace
        return $this->hasMany(ActivationLog::class);
    }

    protected static function booted()
    {
        parent::boot(); // It's good practice to call parent::boot()
    
        static::creating(function ($license) {
            // Check for the temporary flag set by the controller
            if (empty($license->license_key) && ($license->attributes['auto_generate_key_flag'] ?? false)) {
                $maxAttempts = 5; // Prevent infinite loop in rare collision cases
                $attempt = 0;
                do {
                    // Generate a more robust key
                    // Example: LIC-SCRIPTNAME-RANDOM-RANDOM-RANDOM-RANDOM
                    $scriptPrefix = strtoupper(Str::slug($license->managedScript->name ?? 'APP', ''));
                    $prefix = "LIC-{$scriptPrefix}-";
                    $key = $prefix .
                           strtoupper(Str::random(6)) . '-' .
                           strtoupper(Str::random(6)) . '-' .
                           strtoupper(Str::random(6)) . '-' .
                           strtoupper(Str::random(6));
                    $attempt++;
                } while (static::where('license_key', $key)->exists() && $attempt < $maxAttempts);

                if ($attempt >= $maxAttempts && static::where('license_key', $key)->exists()) {
                    // Fallback or throw an exception if a unique key couldn't be generated
                    // For simplicity, appending a timestamp or more random chars
                    $key .= '-' . strtoupper(Str::random(4));
                }
                $license->license_key = $key;
            }
            // Remove the temporary flag as it's not a DB column
            unset($license->attributes['auto_generate_key_flag']);
        });

        static::updating(function ($license) {
            // Check if the license_key is being cleared/empty and auto_generate_key_flag is set
            if (empty($license->license_key) && ($license->attributes['auto_generate_key_flag'] ?? false)) {
                $maxAttempts = 5;
                $attempt = 0;
                do {
                    $scriptPrefix = strtoupper(Str::slug($license->managedScript->name ?? 'APP', ''));
                    $prefix = "LIC-{$scriptPrefix}-";
                    $key = $prefix .
                           strtoupper(Str::random(6)) . '-' .
                           strtoupper(Str::random(6)) . '-' .
                           strtoupper(Str::random(6)) . '-' .
                           strtoupper(Str::random(6));
                    $attempt++;
                } while (static::where('license_key', $key)->where('id', '!=', $license->id)->exists() && $attempt < $maxAttempts);

                if ($attempt >= $maxAttempts && static::where('license_key', $key)->where('id', '!=', $license->id)->exists()) {
                    $key .= '-' . strtoupper(Str::random(4));
                }
                $license->license_key = $key;
            }
            // Remove the temporary flag as it's not a DB column
            unset($license->attributes['auto_generate_key_flag']);
        });
    }

    /**
     * Get all unique successfully activated domains for this license.
     *
     * @return \Illuminate\Support\Collection
     */
    public function getActiveDomains(): \Illuminate\Support\Collection
    {
        return $this->activationLogs()
                    ->where('status', 'success') // Assuming 'success' is the status for successful activation
                    ->distinct('activated_domain')
                    ->orderBy('activated_at', 'desc') // Optional: get the most recent first
                    ->pluck('activated_domain');
    }

    /**
     * Increment the current activations count.
     *
     * @return bool
     */
    public function incrementActivations(): bool
    {
        $this->current_activations = ($this->current_activations ?? 0) + 1;
        return $this->save();
    }

    /**
     * Decrement the current activations count.
     *
     * @return bool
     */
    public function decrementActivations(): bool
    {
        if ($this->current_activations > 0) {
            $this->current_activations--;
            return $this->save();
        }
        return true; // Or false if you want to indicate no change was made
    }

    /**
     * Check if the license has reached its activation limit.
     * Considers 0 as unlimited.
     *
     * @return bool
     */
    public function hasReachedActivationLimit(): bool
    {
        if ($this->activation_limit == 0) { // 0 means unlimited
            return false;
        }
        return ($this->current_activations ?? 0) >= $this->activation_limit;
    }
}
