"""Allocation logic — net all of a book's strategy sleeves into one signed target weight per market,
capped at the book's gross leverage. Pure: takes prices in, returns target weights out."""
from __future__ import annotations

from fxhnt.domain.models import Market, PriceSeries
from fxhnt.domain.portfolio.models import Book
from fxhnt.domain.strategies.base import get_strategy


def compute_target_weights(book: Book, prices_by_market: dict[Market, PriceSeries]) -> dict[Market, float]:
    targets: dict[Market, float] = {}
    for alloc in book.allocations:
        prices = prices_by_market.get(alloc.market)
        if prices is None or len(prices) == 0:
            continue
        positions = get_strategy(alloc.spec.kind).positions(prices, alloc.spec.params)
        latest = float(positions[-1]) if len(positions) else 0.0
        targets[alloc.market] = targets.get(alloc.market, 0.0) + alloc.weight * latest

    gross = sum(abs(w) for w in targets.values())
    if gross > book.max_gross_leverage and gross > 0:
        scale = book.max_gross_leverage / gross
        targets = {m: w * scale for m, w in targets.items()}
    return targets
