<?php

namespace App\Modules\Inventory\Stock\Repositories;

use App\Modules\Inventory\Stock\Models\InventoryStockMovement;
use App\Modules\Inventory\Stock\Support\InventoryStockMovementType;
use Illuminate\Support\Collection;

class InventoryStockMovementRepository
{
    /**
     * @param  array<string, mixed>  $attributes
     */
    public function insert(array $attributes): InventoryStockMovement
    {
        $attributes['recorded_at'] ??= now();

        return InventoryStockMovement::query()->create($attributes);
    }

    public function maxIdForSlice(int $tenantId, int $warehouseId, int $itemId): int
    {
        $v = InventoryStockMovement::withoutGlobalScopes()
            ->where('tenant_id', $tenantId)
            ->where('warehouse_id', $warehouseId)
            ->where('item_id', $itemId)
            ->max('id');

        return (int) ($v ?? 0);
    }

    /**
     * @return \Illuminate\Support\LazyCollection<int, InventoryStockMovement>
     */
    public function cursorForTenantOrdered(int $tenantId): iterable
    {
        return InventoryStockMovement::withoutGlobalScopes()
            ->where('tenant_id', $tenantId)
            ->orderBy('id')
            ->cursor();
    }

    public function countForTenant(int $tenantId): int
    {
        return (int) InventoryStockMovement::withoutGlobalScopes()
            ->where('tenant_id', $tenantId)
            ->count();
    }

    /**
     * @return Collection<int, InventoryStockMovement>
     */
    public function listStockOutsForSalesOrderLine(int $tenantId, int $salesOrderLineId): Collection
    {
        return InventoryStockMovement::withoutGlobalScopes()
            ->where('tenant_id', $tenantId)
            ->where('movement_type', InventoryStockMovementType::StockOut->value)
            ->where('reference_type', 'sales_order_line')
            ->where('reference_id', $salesOrderLineId)
            ->orderBy('id')
            ->get();
    }

    public function sumStockInCompensationForStockOut(int $tenantId, int $stockOutMovementId): string
    {
        $v = InventoryStockMovement::withoutGlobalScopes()
            ->where('tenant_id', $tenantId)
            ->where('movement_type', InventoryStockMovementType::StockIn->value)
            ->where('reverses_movement_id', $stockOutMovementId)
            ->sum('quantity');

        return trim((string) ($v ?? '0'));
    }
}
