import copy
import json
import tempfile
import unittest
from pathlib import Path
from build_workbook import validate, build

ROOT = Path(__file__).resolve().parents[1]


class ChecklistTests(unittest.TestCase):
    def setUp(self):
        self.data = json.loads((ROOT / 'assets/example.json').read_text())

    def rejects(self, change):
        change(self.data)
        with self.assertRaises(ValueError):
            validate(self.data)

    def test_valid_two_sheet_mapping(self):
        self.assertEqual(validate(self.data)['requirement_count'], 3)

    def test_missing_critical_requirement(self):
        self.rejects(lambda d: d['procurement'][0]['refs'].remove('T2'))

    def test_comparator_or_unit_changed(self):
        self.rejects(lambda d: d['procurement'][0].update(summary='库存≤43英寸；监控≥65英寸'))

    def test_start_condition_lost(self):
        self.rejects(lambda d: d['commercial'][0].update(action='地点待确认'))

    def test_unknown_source(self):
        self.rejects(lambda d: d['requirements'][0].update(source_id='unknown'))

    def test_duplicate_requirement(self):
        self.rejects(lambda d: d['requirements'].append(copy.deepcopy(d['requirements'][0])))

    def test_missing_locator(self):
        self.rejects(lambda d: d['requirements'][0].update(locator=''))

    def test_unknown_reference(self):
        self.rejects(lambda d: d['commercial'][0]['refs'].append('unknown'))

    def test_duplicate_visible_row(self):
        self.rejects(lambda d: d['procurement'].append(copy.deepcopy(d['procurement'][0])))

    def test_empty_visible_sheet(self):
        self.rejects(lambda d: d.update(commercial=[]))

    def test_critical_needs_preserved_terms(self):
        self.rejects(lambda d: d['requirements'][1].update(must_keep=[]))

    def test_workbook_shape_text_and_no_overwrite(self):
        from openpyxl import load_workbook
        self.data['commercial'][0]['agreement'] = '=1+1'
        with tempfile.TemporaryDirectory() as folder:
            out = Path(folder) / 'checklist.xlsx'
            build(self.data, out)
            wb = load_workbook(out)
            self.assertEqual(wb.sheetnames, ['采购内容总览', '商务履约清单'])
            self.assertTrue(all(ws.max_column == 4 for ws in wb))
            self.assertEqual(wb['商务履约清单']['B2'].data_type, 's')
            self.assertEqual(wb['商务履约清单']['B2'].value, '=1+1')
            self.assertTrue(out.with_suffix('.trace.json').is_file())
            with self.assertRaises(ValueError):
                build(self.data, out)


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