<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;

class Coupon extends Model
{
    use HasFactory;

    protected $fillable = [
        'code',
        'type',
        'value',
        'min_purchase',
        'max_discount',
        'valid_from',
        'valid_until',
        'max_uses',
        'max_uses_per_customer',
        'current_uses',
        'description',
        'status',
    ];

    protected $casts = [
        'value' => 'decimal:2',
        'min_purchase' => 'decimal:2',
        'max_discount' => 'decimal:2',
        'max_uses' => 'integer',
        'max_uses_per_customer' => 'integer',
        'current_uses' => 'integer',
        'valid_from' => 'datetime',
        'valid_until' => 'datetime',
    ];

    // Relationships
    public function usages()
    {
        return $this->hasMany(CouponUsage::class);
    }

    public function orders()
    {
        return $this->hasManyThrough(Order::class, CouponUsage::class, 'coupon_id', 'id', 'id', 'order_id');
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->where('status', 'active')
            ->where(function($q) {
                $q->whereNull('valid_from')
                  ->orWhere('valid_from', '<=', Carbon::now());
            })
            ->where(function($q) {
                $q->whereNull('valid_until')
                  ->orWhere('valid_until', '>=', Carbon::now());
            });
    }

    public function scopeExpired($query)
    {
        return $query->where('status', 'expired')
            ->orWhere('valid_until', '<', Carbon::now());
    }

    public function scopePercentage($query)
    {
        return $query->where('type', 'percentage');
    }

    public function scopeFixed($query)
    {
        return $query->where('type', 'fixed');
    }

    // Accessors
    public function getIsValidAttribute()
    {
        if ($this->status !== 'active') {
            return false;
        }

        $now = Carbon::now();

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

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

        if ($this->max_uses && $this->current_uses >= $this->max_uses) {
            return false;
        }

        return true;
    }

    public function getIsExpiredAttribute()
    {
        return $this->valid_until && Carbon::now()->gt($this->valid_until);
    }

    public function getRemainingUsesAttribute()
    {
        if (!$this->max_uses) {
            return null;
        }

        return max(0, $this->max_uses - $this->current_uses);
    }

    public function getFormattedValueAttribute()
    {
        if ($this->type === 'percentage') {
            return $this->value . '%';
        }

        return 'MT ' . number_format($this->value, 2, ',', '.');
    }

    // Methods
    public function canBeUsedBy($customerId, $orderTotal = 0)
    {
        // Verificar se está válido
        if (!$this->is_valid) {
            return false;
        }

        // Verificar valor mínimo
        if ($this->min_purchase && $orderTotal < $this->min_purchase) {
            return false;
        }

        // Verificar usos por cliente
        if ($customerId) {
            $usageCount = $this->usages()
                ->where('customer_id', $customerId)
                ->count();

            if ($usageCount >= $this->max_uses_per_customer) {
                return false;
            }
        }

        return true;
    }

    public function calculateDiscount($orderTotal)
    {
        if ($this->type === 'percentage') {
            $discount = ($orderTotal * $this->value) / 100;
            
            // Aplicar desconto máximo
            if ($this->max_discount && $discount > $this->max_discount) {
                $discount = $this->max_discount;
            }

            return $discount;
        }

        // Fixed discount
        return min($this->value, $orderTotal);
    }

    // Events
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($coupon) {
            $coupon->code = strtoupper($coupon->code);
        });

        static::updating(function ($coupon) {
            // Auto-expirar se passou da data
            if ($coupon->valid_until && Carbon::now()->gt($coupon->valid_until)) {
                $coupon->status = 'expired';
            }
        });
    }
}
