<?php

namespace App\Models\Inventory;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Mtc\Shop\Item;
use Mtc\Shop\Item\Size;

class Inventory extends Model
{
    use HasFactory;

    public $timestamps = true;

    protected $table = 'inventories';

    protected $fillable = [
        'sku',
        'warehouse_code',
        'quantity',
    ];

    public function warehouse()
    {
        return $this->belongsTo(Warehouse::class, 'warehouse_code', 'code');
    }

    public function size()
    {
        return $this->belongsTo(Size::class, 'sku', 'PLU');
    }

    public function item()
    {
        return $this->belongsTo(Item::class, 'sku', 'epos_code');
    }

    private static function parseSKUParam(string|array $sku)
    {
        if (! is_array($sku)) {
            $sku = [$sku];
        }

        $type = $sku[1] ?? null;
        $is_variant = empty($type) || $type === 'variant';
        $is_product = empty($type) || $type === 'product';

        return [
            'sku' => $sku[0],
            'type' => $type,
            'product' => $is_product,
            'variant' => $is_variant,
        ];
    }

    public static function deductQuantity(string|array $sku, int $amount)
    {
        $sku = self::parseSKUParam($sku);
        $warehouses = self::query()
            ->leftJoin('warehouses', 'warehouses.code', '=', 'inventories.warehouse_code')
            ->where('sku', $sku['sku'])
            ->orderBy('warehouses.priority', 'ASC')
            ->get(['inventories.*']);

        foreach ($warehouses as $warehouse) {
            if ($amount <= 0)
                break;

            $diff = $warehouse->quantity - $amount;
            $warehouse->quantity = max($diff, 0);
            $amount = $diff * -1;
            $warehouse->save();
        }

        self::updateStock([$sku['sku'], $sku['type']], []);
    }

    public static function updateStock(string|array $sku, array $quantities)
    {
        $sku = self::parseSKUParam($sku);

        foreach ($quantities as $warehouse => $quantity) {
            if (! is_numeric($quantity))
                continue;

            self::query()
                ->updateOrCreate([
                    'sku' => $sku['sku'],
                    'warehouse_code' => $warehouse,
                ], [
                    'quantity' => (int) $quantity,
                ]);
        }

        $total = self::query()
            ->where('sku', $sku['sku'])
            ->pluck('quantity')
            ->sum();

        if ($sku['variant']) {
            \Mtc\Shop\Item\Size::query()
                ->where('PLU', $sku)
                ->update(['stock' => $total]);
        }

        if ($sku['product']) {
            \Mtc\Shop\Item::query()
                ->where('epos_code', $sku)
                ->update(['stock' => $total]);
        }

        return $total;
    }
    #[\Override]
    protected function casts(): array
    {
        return [
            'quantity' => 'integer',
        ];
    }
}
