<?php

namespace App\Models\Inventory;

use App\Models\Catalog\Product;
use App\Models\Concerns\BelongsToTenant;
use App\Models\Concerns\HasDefaultUnitFromProduct;
use App\Models\Lookups\UnitOfMeasure;
use App\Support\SerialInput;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class GrnItem extends Model
{
    use BelongsToTenant, HasDefaultUnitFromProduct;

    protected $fillable = [
        'grn_id', 'product_id', 'unit_id',
        'expiry_date', 'manufacture_date', 'batch_cost', 'stock_batch_id',
        'serial_numbers',
        'quantity', 'unit_cost', 'sale_price',
    ];

    protected function casts(): array
    {
        return [
            'quantity' => 'decimal:4',
            'unit_cost' => 'decimal:2',
            'sale_price' => 'decimal:2',
            'batch_cost' => 'decimal:2',
            'expiry_date' => 'date',
            'manufacture_date' => 'date',
            'serial_numbers' => 'array',
        ];
    }

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

    /**
     * The GRN form submits serials as comma-separated text; the 'array' cast
     * would otherwise json_encode that as a single string and every
     * array-shaped read (count/foreach/implode) would break. Normalize to a
     * real array before the value reaches the column.
     */
    public function setSerialNumbersAttribute(mixed $value): void
    {
        $numbers = SerialInput::numbers($value);

        $this->attributes['serial_numbers'] = $numbers === [] ? null : json_encode($numbers);
    }

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

    public function unit(): BelongsTo
    {
        return $this->belongsTo(UnitOfMeasure::class, 'unit_id');
    }

    public function stockBatch(): BelongsTo
    {
        return $this->belongsTo(StockBatch::class, 'stock_batch_id');
    }

    public function serials(): HasMany
    {
        return $this->hasMany(ProductSerial::class, 'stock_batch_id', 'stock_batch_id');
    }
}
