"""图表意图栈与特征计分。"""
import unittest

from utils import diagram_intent as di


def _base_rules() -> dict:
    return {
        'schema_version': 1,
        'threshold_figure': 1.0,
        'threshold_table': 1.0,
        'title_weight': 1.0,
        'context_weight': 0.6,
        'outline_context_lines': {'before': 2, 'after': 2},
        'stack_order_when_both': 'score_desc',
        'figure_keywords': [
            {'text': '进度', 'weight': 1.2},
            {'text': '横道', 'weight': 1.5},
        ],
        'table_keywords': [
            {'text': '一览表', 'weight': 1.5},
            {'text': '人员', 'weight': 1.0},
        ],
    }


class TestScoreFigureTable(unittest.TestCase):
    def test_figure_higher_on_progress(self):
        r = _base_rules()
        f, t = di.score_figure_table('施工进度与横道计划', '', r)
        self.assertGreater(f, t)

    def test_table_higher_on_roster(self):
        r = _base_rules()
        f, t = di.score_figure_table('主要管理人员配置一览表', '', r)
        self.assertGreater(t, f)


class TestBuildStack(unittest.TestCase):
    def test_gate_figure_off(self):
        r = _base_rules()
        st = di.build_stack(5.0, 5.0, r, enable_figure=False, enable_table=True)
        self.assertEqual(len(st), 1)
        self.assertEqual(st[0].kind, 'table')

    def test_score_desc_order(self):
        r = dict(_base_rules())
        r['stack_order_when_both'] = 'score_desc'
        st = di.build_stack(3.0, 1.0, r, True, True)
        self.assertEqual(len(st), 2)
        self.assertEqual(st[0].kind, 'figure')
        self.assertGreater(st[0].score, st[1].score)

    def test_figure_first(self):
        r = dict(_base_rules())
        r['stack_order_when_both'] = 'figure_first'
        st = di.build_stack(2.0, 5.0, r, True, True)
        self.assertEqual(st[0].kind, 'figure')
        self.assertEqual(st[1].kind, 'table')

    def test_below_threshold_empty(self):
        r = dict(_base_rules())
        r['threshold_figure'] = 10.0
        r['threshold_table'] = 10.0
        st = di.build_stack(1.0, 1.0, r, True, True)
        self.assertEqual(st, [])


class TestOutlineWindow(unittest.TestCase):
    def test_finds_title_line(self):
        outline = '一、总则\n二、进度\n  2.1 横道计划\n三、尾'
        w = di.extract_outline_window(outline, '2.1 横道计划', 1, 1)
        self.assertIn('横道', w)

    def test_fallback_prefix(self):
        w = di.extract_outline_window('abc' * 400, '不存在的标题', 2, 2)
        self.assertTrue(len(w) > 0)


class TestAgentRender(unittest.TestCase):
    def test_render_non_empty_when_match(self):
        r = dict(_base_rules())
        r['threshold_figure'] = 0.5
        r['threshold_table'] = 0.5
        agent = di.DiagramIntentAgent(r)
        s = agent.render_for_section(
            '施工进度横道图编制说明',
            '大纲\n进度\n横道',
            True,
            True,
        )
        self.assertIn('图示生成规范', s)
        self.assertIn('本节图表生成优先级', s)

    def test_render_empty_when_scores_low(self):
        r = dict(_base_rules())
        r['threshold_figure'] = 100.0
        r['threshold_table'] = 100.0
        agent = di.DiagramIntentAgent(r)
        s = agent.render_for_section('无关标题', '无关', True, True)
        self.assertEqual(s, '')


class TestStackHelpers(unittest.TestCase):
    def test_stack_compact_labels(self):
        st = [
            di.DiagramIntent('figure', 1.0, 't'),
            di.DiagramIntent('table', 1.0, 't'),
        ]
        lab = di.stack_compact_labels(st)
        self.assertEqual(len(lab), 2)
        self.assertIn('[FIGURE]', lab[0])

    def test_make_fallback_stack(self):
        st = di.make_fallback_stack('figure')
        self.assertEqual(len(st), 1)
        self.assertEqual(st[0].kind, 'figure')


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