<?php

namespace App\Models\Tenant;

use App\Models\Concerns\BelongsToTenant;
use Illuminate\Database\Eloquent\Model;

class MarkupRule extends Model
{
    use BelongsToTenant;

    public const TYPES = [
        'category' => 'Categorie',
        'brand' => 'Brand',
        'range' => 'Interval preț',
    ];

    protected $fillable = [
        'company_id', 'type', 'key',
        'range_from', 'range_to', 'markup_pct',
        'priority', 'is_active',
    ];

    protected $casts = [
        'range_from' => 'decimal:2',
        'range_to' => 'decimal:2',
        'markup_pct' => 'decimal:2',
        'is_active' => 'boolean',
    ];

    /**
     * Find best matching rule for a given Part. Priority order:
     * 1) brand match  2) category match  3) range (buy_price intersect)  4) default 30%.
     */
    public static function bestForPart(Part $part): ?self
    {
        // Brand exact
        if ($part->brand) {
            $r = static::where('type', 'brand')
                ->where('is_active', true)
                ->where('key', $part->brand)
                ->orderBy('priority')->first();
            if ($r) return $r;
        }
        // Category exact
        if ($part->category) {
            $r = static::where('type', 'category')
                ->where('is_active', true)
                ->where('key', $part->category)
                ->orderBy('priority')->first();
            if ($r) return $r;
        }
        // Range (buy_price ∈ [from, to))
        $price = (float) $part->buy_price;
        $r = static::where('type', 'range')
            ->where('is_active', true)
            ->where('range_from', '<=', $price)
            ->where(function ($q) use ($price) {
                $q->whereNull('range_to')->orWhere('range_to', '>', $price);
            })
            ->orderBy('priority')->orderByDesc('range_from')->first();
        return $r;
    }

    public static function applyToPart(Part $part): bool
    {
        $rule = static::bestForPart($part);
        $pct = $rule?->markup_pct ?? 30;
        $part->sell_price = round((float) $part->buy_price * (1 + (float) $pct / 100), 2);
        return $part->save();
    }
}
