<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Package extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'slug',
        'description',
        'price',
        'type',
        'features',
        'actions',
        'image_path',
        'is_active',
        'sort_order',
        'stock_enabled',
        'stock_quantity',
        'stock_remaining',
        'is_subscription',
        'subscription_duration',
    ];

    protected $casts = [
        'features' => 'array',
        'actions' => 'array',
        'is_active' => 'boolean',
        'price' => 'decimal:2',
        'stock_enabled' => 'boolean',
        'stock_quantity' => 'integer',
        'stock_remaining' => 'integer',
        'is_subscription' => 'boolean',
        'subscription_duration' => 'integer',
    ];

    public function transactions()
    {
        return $this->hasMany(Transaction::class);
    }

    /**
     * The servers that this package is assigned to.
     */
    public function servers()
    {
        return $this->belongsToMany(Server::class, 'package_server');
    }

    /**
     * Scope to filter packages by server.
     */
    public function scopeForServer($query, $serverId)
    {
        return $query->whereHas('servers', function ($q) use ($serverId) {
            $q->where('servers.id', $serverId);
        });
    }

    /**
     * Check if package is available on a specific server.
     */
    public function isAvailableOnServer($serverId)
    {
        return $this->servers()->where('servers.id', $serverId)->exists();
    }

    /**
     * Get packages that are available on any server.
     */
    public function scopeWithServers($query)
    {
        return $query->has('servers');
    }

    /**
     * Check if package is in stock
     */
    public function isInStock(): bool
    {
        if (!$this->stock_enabled) {
            return true; // Unlimited stock
        }

        return $this->stock_remaining > 0;
    }

    /**
     * Check if package is sold out
     */
    public function isSoldOut(): bool
    {
        return $this->stock_enabled && $this->stock_remaining <= 0;
    }

    /**
     * Decrement stock when purchased
     */
    public function decrementStock(): bool
    {
        if (!$this->stock_enabled) {
            return true; // No stock management needed
        }

        if ($this->stock_remaining <= 0) {
            return false; // Out of stock
        }

        $this->decrement('stock_remaining');
        return true;
    }

    /**
     * Increment stock (for refunds)
     */
    public function incrementStock(): void
    {
        if ($this->stock_enabled && $this->stock_remaining < $this->stock_quantity) {
            $this->increment('stock_remaining');
        }
    }

    /**
     * Get stock percentage remaining
     */
    public function getStockPercentageAttribute(): int
    {
        if (!$this->stock_enabled || $this->stock_quantity <= 0) {
            return 100;
        }

        return (int) (($this->stock_remaining / $this->stock_quantity) * 100);
    }

    /**
     * Get stock status badge class
     */
    public function getStockBadgeClassAttribute(): string
    {
        if (!$this->stock_enabled) {
            return 'unlimited';
        }

        $percentage = $this->stock_percentage;

        if ($percentage <= 0) {
            return 'sold-out';
        } elseif ($percentage <= 25) {
            return 'low-stock';
        } elseif ($percentage <= 50) {
            return 'medium-stock';
        }

        return 'in-stock';
    }

    /**
     * Scope to only show in-stock packages
     */
    public function scopeInStock($query)
    {
        return $query->where(function ($q) {
            $q->where('stock_enabled', false)
              ->orWhere('stock_remaining', '>', 0);
        });
    }

    /**
     * Get subscription duration in human-readable format
     */
    public function getSubscriptionDurationHumanAttribute(): ?string
    {
        if (!$this->is_subscription || !$this->subscription_duration) {
            return null;
        }

        $days = $this->subscription_duration;

        if ($days >= 365) {
            $years = floor($days / 365);
            return $years . ' ' . Str::plural('year', $years);
        } elseif ($days >= 30) {
            $months = floor($days / 30);
            return $months . ' ' . Str::plural('month', $months);
        } elseif ($days >= 7) {
            $weeks = floor($days / 7);
            return $weeks . ' ' . Str::plural('week', $weeks);
        }

        return $days . ' ' . Str::plural('day', $days);
    }

    /**
     * Get subscription type (one-time, recurring, etc.)
     */
    public function getSubscriptionTypeAttribute(): string
    {
        return $this->is_subscription ? 'subscription' : 'one-time';
    }
}