<?php

declare(strict_types=1);

namespace App\Business\Inventory;

use App\Business\Product\InventoryPostingProductSkuResolver;
use App\Business\Product\LedgerProductSkuResolver;
use App\Models\DberpInventoryBalance;
use App\Models\DberpProduct;
use App\Support\DberpNumberFormatter;

/**
 * 库存类单据明细录入：只读库存参考数量（不参与过账，与确认时服务规则一致）。
 */
final class InventoryDocumentLineHintService
{
    public function sumRealtimeQuantity(int $warehouseId, int $productId, int $productSkuId): string
    {
        if ($warehouseId <= 0 || $productId <= 0 || $productSkuId <= 0) {
            return '0.0000';
        }

        $sum = (float) DberpInventoryBalance::query()
            ->where('warehouse_id', $warehouseId)
            ->where('product_id', $productId)
            ->where('product_sku_id', $productSkuId)
            ->sum('realtime_quantity');

        return number_format(max(0, $sum), 4, '.', '');
    }

    public function sumAvailableQuantity(int $warehouseId, int $productId, int $productSkuId): string
    {
        if ($warehouseId <= 0 || $productId <= 0 || $productSkuId <= 0) {
            return '0.0000';
        }

        $sum = (float) DberpInventoryBalance::query()
            ->where('warehouse_id', $warehouseId)
            ->where('product_id', $productId)
            ->where('product_sku_id', $productSkuId)
            ->sum('available_quantity');

        return number_format(max(0, $sum), 4, '.', '');
    }

    public function formattedBookQuantityHint(int $warehouseId, int $productId, int $productSkuId): ?string
    {
        if ($warehouseId <= 0 || $productId <= 0 || $productSkuId <= 0) {
            return null;
        }

        $qty = $this->sumRealtimeQuantity($warehouseId, $productId, $productSkuId);

        return (string) __('dberp.hints.document_line_book_quantity_reference', [
            'quantity' => DberpNumberFormatter::quantity($qty),
        ]);
    }

    /**
     * 盘点录入：商品已选、规格未选时，在可安全解析默认规格的前提下仍展示账面参考。
     */
    public function formattedBookQuantityHintForLine(int $warehouseId, int $productId, int $productSkuId): ?string
    {
        $resolvedSkuId = $this->resolveProductSkuIdForInventoryHint($productId, $productSkuId);

        if ($resolvedSkuId === null) {
            return null;
        }

        return $this->formattedBookQuantityHint($warehouseId, $productId, $resolvedSkuId);
    }

    public function resolveProductSkuIdForInventoryHint(int $productId, int $productSkuId): ?int
    {
        if ($productSkuId > 0) {
            return $productSkuId;
        }

        if ($productId <= 0) {
            return null;
        }

        $product = DberpProduct::query()->find($productId);
        if ($product === null) {
            return null;
        }

        if (InventoryPostingProductSkuResolver::productRequiresExplicitSkuBeforeDefault($product)) {
            return null;
        }

        return (int) LedgerProductSkuResolver::defaultSkuForProductInventoryLine($product)->getKey();
    }

    public function formattedAvailableStockHint(int $warehouseId, int $productId, int $productSkuId): ?string
    {
        if ($warehouseId <= 0 || $productId <= 0 || $productSkuId <= 0) {
            return null;
        }

        $qty = $this->sumAvailableQuantity($warehouseId, $productId, $productSkuId);

        return (string) __('dberp.hints.document_line_available_stock_reference', [
            'quantity' => DberpNumberFormatter::quantity($qty),
        ]);
    }
}
