<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;

class CatalogPriceRule extends Model
{
    public const TYPE_ALWAYS = 'always';
    public const TYPE_WEEKDAY = 'weekday';
    public const TYPE_DATE_RANGE = 'date_range';
    public const TYPE_SPECIFIC_DATE = 'specific_date';

    protected $fillable = [
        'organization_id',
        'priceable_type',
        'priceable_id',
        'name',
        'rule_type',
        'weekday_values',
        'start_date',
        'end_date',
        'specific_date',
        'customer_price',
        'internal_cost',
        'gift_codes',
        'artist_codes',
        'other_cost_codes',
        'priority',
        'is_active',
    ];

    protected $casts = [
        'organization_id' => 'integer',
        'priceable_id' => 'integer',
        'weekday_values' => 'array',
        'start_date' => 'date:Y-m-d',
        'end_date' => 'date:Y-m-d',
        'specific_date' => 'date:Y-m-d',
        'customer_price' => 'float',
        'internal_cost' => 'float',
        'gift_codes' => 'array',
        'artist_codes' => 'array',
        'other_cost_codes' => 'array',
        'priority' => 'integer',
        'is_active' => 'boolean',
    ];

    public function organization(): BelongsTo
    {
        return $this->belongsTo(Organization::class);
    }

    public function priceable(): MorphTo
    {
        return $this->morphTo();
    }

    public function appliesToDate(Carbon $date): bool
    {
        return match ($this->rule_type) {
            self::TYPE_ALWAYS => true,
            self::TYPE_WEEKDAY => in_array((int) $date->dayOfWeekIso, array_map('intval', $this->weekday_values ?? []), true),
            self::TYPE_DATE_RANGE => $this->start_date && $this->end_date
                ? $date->betweenIncluded(Carbon::parse($this->start_date), Carbon::parse($this->end_date))
                : false,
            self::TYPE_SPECIFIC_DATE => $this->specific_date
                ? $date->toDateString() === Carbon::parse($this->specific_date)->toDateString()
                : false,
            default => false,
        };
    }
}
