<?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 Promotion extends Model
{
    use HasFactory, SoftDeletes, BelongsToCompany;

    protected $fillable = [
        'company_id', 'name', 'slug', 'description', 'image_path',
        'discount_type', 'discount_value',
        'applies_to_all_services', 'service_ids',
        'starts_at', 'ends_at',
        'is_active', 'is_featured',
        'usage_limit', 'used_count',
    ];

    protected function casts(): array
    {
        return [
            'discount_value'           => 'decimal:2',
            'applies_to_all_services'  => 'boolean',
            'service_ids'              => 'array',
            'starts_at'                => 'datetime',
            'ends_at'                  => 'datetime',
            'is_active'                => 'boolean',
            'is_featured'              => '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))
            ->where(fn ($q2) => $q2->whereNull('usage_limit')->orWhereColumn('used_count', '<', 'usage_limit'));
    }

    public function appliesToService(int $serviceId): bool
    {
        $serviceIds = array_map('intval', (array) $this->service_ids);

        return $this->applies_to_all_services
            || in_array($serviceId, $serviceIds, true);
    }

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

        return round(min($amount, max(0, $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';
    }
}
