<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Inventory extends Model
{
    use HasFactory;

    protected $fillable = [
        'product_variant_id',
        'quantity',
        'reserved_quantity',
        'low_stock_threshold',
    ];

    protected function casts(): array
    {
        return [
            'quantity' => 'integer',
            'reserved_quantity' => 'integer',
            'low_stock_threshold' => 'integer',
        ];
    }

    public function variant(): BelongsTo
    {
        return $this->belongsTo(ProductVariant::class, 'product_variant_id');
    }

    /** What's actually sellable right now — on hand minus what's held by pending orders. */
    protected function availableQuantity(): Attribute
    {
        return Attribute::get(fn () => max(0, $this->quantity - $this->reserved_quantity));
    }

    protected function isOutOfStock(): Attribute
    {
        return Attribute::get(fn () => $this->available_quantity <= 0);
    }

    protected function isLowStock(): Attribute
    {
        return Attribute::get(fn () => ! $this->is_out_of_stock && $this->available_quantity <= $this->low_stock_threshold
        );
    }

    /**
     * Movements for this variant, via the variant rather than a direct FK
     * on inventories — inventory_movements keys off product_variant_id
     * (Step 2/3), since it needs to keep logging even if an inventory row
     * were ever recreated.
     */
    public function movements(): HasMany
    {
        return $this->hasMany(InventoryMovement::class, 'product_variant_id', 'product_variant_id');
    }

    /** whereColumn can't express "quantity - reserved_quantity", so these compare against raw SQL rather than PHP-side accessors. */
    public function scopeLowStock(Builder $query): void
    {
        $query->whereRaw('(quantity - reserved_quantity) > 0')
            ->whereRaw('(quantity - reserved_quantity) <= low_stock_threshold');
    }

    public function scopeOutOfStock(Builder $query): void
    {
        $query->whereRaw('(quantity - reserved_quantity) <= 0');
    }
}
