"""计划组需求明细：物化与读取。"""
from __future__ import annotations

from typing import Any

from supply_infra.db.repositories.demand_belong_category_repo import DemandBelongCategoryRepository
from supply_infra.db.repositories.demand_belong_pool_rel_repo import DemandBelongPoolRelRepository
from supply_infra.db.repositories.multi_demand_pool_di_repo import MultiDemandPoolDiRepository
from supply_infra.db.session import get_session

MAX_DEMANDS_PER_BATCH = 30


def split_even_batches(items: list[Any], *, max_per_batch: int = MAX_DEMANDS_PER_BATCH) -> list[list[Any]]:
    """按总数均分子批次：总数不超过上限则一批；否则递增组数直到每组不超过上限，余数从前组分配。"""
    n = len(items)
    if n == 0:
        return []
    cap = max(1, int(max_per_batch))
    if n <= cap:
        return [items]

    k = 2
    while True:
        base = n // k
        rem = n % k
        max_size = base + 1 if rem > 0 else base
        if max_size <= cap:
            break
        k += 1

    batches: list[list[Any]] = []
    idx = 0
    for i in range(k):
        size = base + (1 if i < rem else 0)
        batches.append(items[idx : idx + size])
        idx += size
    return batches


def _priority_sort_key(name: str, priority_index: dict) -> tuple:
    return (
        priority_index.get(name, {}).get("source_rank_score") is None,
        -float(priority_index.get(name, {}).get("source_rank_score") or 0),
        float(priority_index.get(name, {}).get("global_demand_rank") or float("inf")),
        name,
    )


def resolve_demands_for_category_ids(
    biz_dt: str,
    category_ids: list[int],
) -> list[dict[str, Any]]:
    """按分类节点解析全部需求池记录（pool_id + demand_name）。"""
    selected_ids = list(dict.fromkeys(int(value) for value in category_ids))
    with get_session() as session:
        belongs = DemandBelongCategoryRepository(session).list_by_category_ids(selected_ids)
        pool_ids_by_belong = DemandBelongPoolRelRepository(session).get_pool_ids_by_belong_ids(
            [int(row.id) for row in belongs]
        )
        pool_ids = sorted({pool_id for values in pool_ids_by_belong.values() for pool_id in values})
        pool_repo = MultiDemandPoolDiRepository(session)
        pool_rows = pool_repo.get_by_ids(pool_ids)
        from agents.demand_grade_agent.tools.demand_priority import build_demand_priority_index

        priority_index = build_demand_priority_index(pool_repo.list_by_biz_dt(biz_dt))
        candidates: list[dict[str, Any]] = []
        for row in pool_rows:
            if row.biz_dt != biz_dt or not row.demand_name:
                continue
            candidates.append({
                "pool_id": int(row.id),
                "demand_name": str(row.demand_name),
            })

    candidates.sort(
        key=lambda item: (
            *_priority_sort_key(item["demand_name"], priority_index),
            item["pool_id"],
        )
    )
    return candidates
