"""目标页数与一级篇章区间。"""
import random
import unittest

from utils import volume_chapters as vc


class TestVolumeChapters(unittest.TestCase):
    def test_top_level_default_pages_zero(self):
        lo, hi = vc.top_level_chapter_range_from_pages(0)
        self.assertEqual((lo, hi), (8, 10))

    def test_ranges_match_effective_volume_bands(self):
        self.assertEqual(vc.top_level_chapter_range_from_pages(100), (6, 8))
        self.assertEqual(vc.top_level_chapter_range_from_pages(125), (6, 8))
        self.assertEqual(vc.top_level_chapter_range_from_pages(150), (8, 10))
        self.assertEqual(vc.top_level_chapter_range_from_pages(200), (10, 12))
        self.assertEqual(vc.top_level_chapter_range_from_pages(300), (12, 16))

    def test_hint_default_no_pages(self):
        h = vc.outline_chapter_count_hint(0, 'standard')
        self.assertIn('8-10', h)
        self.assertIn('不超过10', h)

    def test_hint_with_pages(self):
        h = vc.outline_chapter_count_hint(150, 'standard', 700)
        self.assertIn('约 8–10', h)
        self.assertIn('150', h)
        self.assertIn('105000', h)  # 150×700 总字目标
        self.assertIn('过细', h)

    def test_subchapter_base_anchor_points(self):
        self.assertAlmostEqual(vc.subchapter_total_base_from_pages(100), 78.0, places=5)
        self.assertAlmostEqual(vc.subchapter_total_base_from_pages(300), 212.0, places=5)
        self.assertEqual(vc.SUBCHAPTER_PAGES_SLOPE, 0.67)
        self.assertEqual(vc.SUBCHAPTER_PAGES_INTERCEPT, 11.0)

    def test_subchapter_jitter_bounds_78_anchor(self):
        """100 页基线 78 章，±10% 严格为 [70, 86]。"""
        self.assertEqual(vc.subchapter_jitter_bounds(78.0), (70, 86))

    def test_subchapter_jitter_bounds_300_pages(self):
        self.assertEqual(vc.subchapter_jitter_bounds(212.0), (191, 233))

    def test_allocate_subchapters_to_mains(self):
        self.assertEqual(vc.allocate_subchapters_to_mains(10, 3), [4, 3, 3])
        self.assertEqual(vc.allocate_subchapters_to_mains(0, 3), [0, 0, 0])
        self.assertEqual(vc.allocate_subchapters_to_mains(5, 2), [3, 2])
        self.assertEqual(vc.allocate_subchapters_to_mains(7, 0), [])
        # n < k 时多出的主章 quota 为 0
        a = vc.allocate_subchapters_to_mains(70, 100)
        self.assertEqual(len(a), 100)
        self.assertEqual(sum(a), 70)
        self.assertEqual(a.count(1), 70)
        self.assertEqual(a.count(0), 30)

    def test_subchapter_effective_respects_k_floor_and_jitter(self):
        # round(78 * u) for u in [0.9, 1.1] stays in [70, 86] for 78.0 base
        for seed in range(800):
            n = vc.subchapter_total_effective(100, 1, random.Random(seed))
            self.assertGreaterEqual(n, 70)
            self.assertLessEqual(n, 86)
        # 主章数很大时，总条数仍须在 [70, 86]（不得被 max(n,k) 抬到数百）
        for seed in range(20):
            nk = vc.subchapter_total_effective(100, 500, random.Random(seed))
            self.assertGreaterEqual(nk, 70, msg=f'seed={seed}')
            self.assertLessEqual(nk, 86, msg=f'seed={seed}')

    def test_subchapter_effective_zero_pages(self):
        self.assertEqual(vc.subchapter_total_effective(0, 5), 0)
        self.assertEqual(vc.subchapter_total_effective(100, 0), 0)

    def test_resolve_expand_target_pages(self):
        self.assertEqual(vc.resolve_expand_target_pages(None, True, 100, 200), 0)
        self.assertEqual(vc.resolve_expand_target_pages(200, False, 100, 50), 200)
        self.assertEqual(vc.resolve_expand_target_pages(0, False, 80, 0), 80)
        self.assertEqual(vc.resolve_expand_target_pages(0, False, 0, 50), 50)
        self.assertEqual(
            vc.resolve_expand_target_pages(0, False, 0, 0),
            vc.EXPAND_OUTLINE_DEFAULT_TARGET_PAGES,
        )
        self.assertEqual(vc.EXPAND_OUTLINE_DEFAULT_TARGET_PAGES, 100)


if __name__ == '__main__':
    unittest.main()
