"""CharacterGenerateRequest.role_mix 校验单测（⑦ 群像按定位配比）。

纯 pydantic 校验，无 DB/网关。契约：role_mix 在场时 count 取各值之和，
每项数量须 ≥ 1、总和须 ≤ MAX_GENERATE_COUNT。
"""

from __future__ import annotations

import pytest
from pydantic import ValidationError
from ww_api.schemas.generation import MAX_GENERATE_COUNT, CharacterGenerateRequest


def test_role_mix_absent_keeps_explicit_count() -> None:
    req = CharacterGenerateRequest(brief="剑修", count=3)
    assert req.role_mix is None
    assert req.count == 3


def test_role_mix_sets_count_to_sum() -> None:
    req = CharacterGenerateRequest(brief="群像", role_mix={"主角": 1, "对手": 2, "配角": 3})
    assert req.count == 6


def test_role_mix_overrides_provided_count() -> None:
    # role_mix 在场时 count 取各值之和，忽略客户端显式传入的 count
    req = CharacterGenerateRequest(brief="群像", count=1, role_mix={"主角": 2, "对手": 2})
    assert req.count == 4


def test_role_mix_total_at_max_allowed() -> None:
    req = CharacterGenerateRequest(brief="群像", role_mix={"主角": MAX_GENERATE_COUNT})
    assert req.count == MAX_GENERATE_COUNT


def test_role_mix_sum_over_max_rejected() -> None:
    with pytest.raises(ValidationError):
        # 6 + 7 = 13 > 12
        CharacterGenerateRequest(brief="群像", role_mix={"主角": 6, "对手": 7})


def test_role_mix_empty_dict_rejected() -> None:
    with pytest.raises(ValidationError):
        CharacterGenerateRequest(brief="群像", role_mix={})


def test_role_mix_nonpositive_value_rejected() -> None:
    with pytest.raises(ValidationError):
        CharacterGenerateRequest(brief="群像", role_mix={"主角": 0})
    with pytest.raises(ValidationError):
        CharacterGenerateRequest(brief="群像", role_mix={"主角": -1})
