"""仓库操作纯逻辑：调拨配对、盘点差异、组合装展开。DB 装配在 services 层。"""
from dataclasses import dataclass
from decimal import Decimal


@dataclass(frozen=True)
class TransferLeg:
    warehouse_id: int
    qty_delta: Decimal


def transfer_legs(from_wh: int, to_wh: int, qty: Decimal) -> list[TransferLeg]:
    """调拨拆成一出一入两条流水腿，净量守恒（总和为 0）。"""
    if qty <= 0:
        raise ValueError("调拨数量必须大于 0")
    if from_wh == to_wh:
        raise ValueError("调出与调入仓库不能相同")
    return [TransferLeg(from_wh, -qty), TransferLeg(to_wh, qty)]


def stocktake_diff(system_qty: Decimal, counted_qty: Decimal) -> Decimal:
    """盘点差异 = 实盘 - 账面。正数报溢、负数报损、0 无差异。"""
    return counted_qty - system_qty


@dataclass(frozen=True)
class KitComponent:
    child_product_id: int
    qty: Decimal


def explode_kit(components: list[KitComponent], kit_qty: Decimal
                ) -> list[tuple[int, Decimal]]:
    """组装/拆解按配方展开子件用量。

    组装 kit_qty 个父件 → 每个子件消耗 qty*kit_qty；拆解取负 kit_qty 即回补子件。
    返回 [(child_product_id, 子件数量变化)]。
    """
    if kit_qty == 0:
        raise ValueError("组合装数量不能为 0")
    if not components:
        raise ValueError("组合装配方为空，无法组装")
    return [(c.child_product_id, c.qty * kit_qty) for c in components]
