<?php

namespace App\Models;

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

class SubscriptionFee extends Model
{
    use HasFactory, SoftDeletes;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'membership_category_id',
        'name',
        'description',
        'amount',
        'currency',
        'billing_cycle',
        'is_active',
        'is_default',
        'effective_from',
        'effective_until',
        'created_by',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'amount' => 'decimal:2',
        'is_active' => 'boolean',
        'is_default' => 'boolean',
        'effective_from' => 'date',
        'effective_until' => 'date',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'deleted_at' => 'datetime',
    ];

    /**
     * Get the membership category for the subscription fee.
     */
    public function membershipCategory(): BelongsTo
    {
        return $this->belongsTo(MembershipCategory::class);
    }

    /**
     * Get the user who created the fee.
     */
    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    /**
     * Get the history for the subscription fee.
     */
    public function history(): HasMany
    {
        return $this->hasMany(SubscriptionFeeHistory::class);
    }

    /**
     * Scope a query to only include active fees.
     */
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    /**
     * Scope a query to only include default fees.
     */
    public function scopeDefault($query)
    {
        return $query->where('is_default', true);
    }

    /**
     * Scope a query to filter by currency.
     */
    public function scopeCurrency($query, string $currency)
    {
        return $query->where('currency', $currency);
    }

    /**
     * Get formatted amount with currency.
     */
    public function getFormattedAmountAttribute(): string
    {
        $symbols = [
            'USD' => '$',
            'SSP' => '£',
            'KES' => 'KSh',
            'UGX' => 'USh',
        ];

        $symbol = $symbols[$this->currency] ?? $this->currency . ' ';
        return $symbol . number_format($this->amount, 2);
    }

    /**
     * Check if fee is currently effective.
     */
    public function isEffective(): bool
    {
        $now = now()->toDateString();

        if ($this->effective_from && $now < $this->effective_from) {
            return false;
        }

        if ($this->effective_until && $now > $this->effective_until) {
            return false;
        }

        return true;
    }

    /**
     * Get billing cycle display name.
     */
    public function getBillingCycleDisplayAttribute(): string
    {
        return match($this->billing_cycle) {
            'one_time' => 'One-time Payment',
            'monthly' => 'Monthly',
            'quarterly' => 'Quarterly',
            'biannual' => 'Bi-annually',
            'annual' => 'Annually',
            default => ucfirst($this->billing_cycle),
        };
    }
}
