<?php

namespace App\Models;

use App\Models\Concerns\BelongsToCompany;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Coupon extends Model
{
    use HasFactory, SoftDeletes, BelongsToCompany;

    protected $fillable = [
        'company_id', 'code', 'scope',
        'discount_type', 'discount_value',
        'min_amount', 'max_discount',
        'starts_at', 'ends_at',
        'usage_limit', 'usage_limit_per_customer', 'used_count',
        'is_active',
    ];

    protected function casts(): array
    {
        return [
            'discount_value' => 'decimal:2',
            'min_amount'     => 'decimal:2',
            'max_discount'   => 'decimal:2',
            'starts_at'      => 'datetime',
            'ends_at'        => 'datetime',
            'is_active'      => 'boolean',
        ];
    }

    public function scopeActive(Builder $q): Builder
    {
        $now = now();
        return $q->where('is_active', true)
            ->where(fn ($q2) => $q2->whereNull('starts_at')->orWhere('starts_at', '<=', $now))
            ->where(fn ($q2) => $q2->whereNull('ends_at')->orWhere('ends_at', '>=', $now));
    }

    public function isAvailable(): bool
    {
        if (! $this->is_active) return false;
        $now = now();
        if ($this->starts_at && $this->starts_at->gt($now)) return false;
        if ($this->ends_at && $this->ends_at->lt($now)) return false;
        if ($this->usage_limit && $this->used_count >= $this->usage_limit) return false;
        return true;
    }

    public function calculateDiscount(float $amount): float
    {
        if ($this->min_amount && $amount < (float) $this->min_amount) {
            return 0.0;
        }

        $discount = $this->discount_type === 'percentage'
            ? $amount * ((float) $this->discount_value / 100)
            : (float) $this->discount_value;

        if ($this->max_discount) {
            $discount = min($discount, (float) $this->max_discount);
        }

        return round($discount, 2);
    }

    public function discountLabel(): string
    {
        return $this->discount_type === 'percentage'
            ? rtrim(rtrim(number_format((float) $this->discount_value, 2, ',', '.'), '0'), ',').'% OFF'
            : '$ '.number_format((float) $this->discount_value, 0, ',', '.').' OFF';
    }
}
