"""#1749 配音时长分配纯函数测试。"""

import pytest

from packages.domain.voice_duration_planner import (
    MIN_CLIP_DURATION,
    plan_clip_durations,
    total_output_duration,
    transition_overlap_seconds,
)


def test_cut_22s_3clips_even_split():
    d = plan_clip_durations(3, 22.0)
    assert len(d) == 3
    assert d == pytest.approx([7.333, 7.333, 7.334], abs=0.01)
    assert total_output_duration(d) == pytest.approx(22.0, abs=0.05)


def test_xfade_12s_3clips_two_transitions():
    effects = ["cut", "xfade", "xfade"]
    tdurs = [0.0, 0.5, 0.5]
    d = plan_clip_durations(3, 12.0, effects, tdurs)
    # Σ段长 − 2×0.5 = 12 → Σ段长 = 13
    assert sum(d) == pytest.approx(13.0, abs=0.01)
    assert total_output_duration(d, effects, tdurs) == pytest.approx(12.0, abs=0.05)


def test_cut_zero_overlap():
    assert transition_overlap_seconds("cut", 0.5) == 0.0
    assert transition_overlap_seconds(None, 0.5) == 0.0
    assert transition_overlap_seconds("none", 0.5) == 0.0
    assert transition_overlap_seconds("xfade", 0.5) == 0.5
    assert transition_overlap_seconds("fade", 0.0) == 0.0


def test_zero_voice_returns_empty():
    assert plan_clip_durations(3, 0.0) == []
    assert plan_clip_durations(3, -1.0) == []
    assert plan_clip_durations(0, 10.0) == []


def test_invalid_voice_returns_empty():
    assert plan_clip_durations(3, None) == []  # type: ignore[arg-type]
    assert plan_clip_durations(3, "abc") == []  # type: ignore[arg-type]


def test_short_voice_floors_min_clip():
    d = plan_clip_durations(5, 2.0)
    assert len(d) == 5
    assert all(x >= MIN_CLIP_DURATION - 0.001 for x in d)


def test_last_segment_absorbs_rounding():
    d = plan_clip_durations(3, 10.0)
    assert total_output_duration(d) == pytest.approx(10.0, abs=0.05)
    d2 = plan_clip_durations(7, 23.7)
    assert total_output_duration(d2) == pytest.approx(23.7, abs=0.05)


def test_all_effects_cut_total_equals_voice():
    effects = ["cut"] * 4
    d = plan_clip_durations(4, 30.0, effects, [0.0] * 4)
    assert total_output_duration(d, effects, [0.0] * 4) == pytest.approx(30.0, abs=0.05)


def test_mixed_transitions():
    effects = ["cut", "cut", "xfade", "slide"]
    tdurs = [0.0, 0.0, 0.4, 0.6]
    d = plan_clip_durations(4, 20.0, effects, tdurs)
    # 重叠 0.4 + 0.6 = 1.0 → Σ段长 = 21
    assert sum(d) == pytest.approx(21.0, abs=0.01)
    assert total_output_duration(d, effects, tdurs) == pytest.approx(20.0, abs=0.05)


def test_single_clip_no_transition():
    d = plan_clip_durations(1, 8.0)
    assert len(d) == 1
    assert d[0] == pytest.approx(8.0, abs=0.05)


def test_total_output_duration_empty():
    assert total_output_duration([]) == 0.0
