import unittest

from math_problems_structure.grade_1 import compose_and_decompose_numbers


class ComposeAndDecomposeNumbersTest(unittest.TestCase):
    def setUp(self) -> None:
        self.picture = {
            "id": "cube",
            "name": "Cube",
            "image_path": "/images/cube.png",
        }

    def test_creates_ordered_problem(self) -> None:
        problem = compose_and_decompose_numbers(picture=self.picture)

        rows = problem["rows"]

        self.assertEqual(problem["instructions"], "Compón y descompón el número.")
        self.assertEqual(problem["whole"], 10)
        self.assertEqual(problem["picture"], self.picture)
        self.assertEqual(len(rows), 9)
        self.assertEqual(
            [(row["first_part"], row["second_part"]) for row in rows],
            [(9, 1), (8, 2), (7, 3), (6, 4), (5, 5), (4, 6), (3, 7), (2, 8), (1, 9)],
        )

        for row in rows:
            self.assertEqual(row["whole"], 10)
            self.assertEqual(row["first_part"] + row["second_part"], 10)
            self.assertEqual(row["picture"], self.picture)

    def test_can_randomize_rows(self) -> None:
        problem = compose_and_decompose_numbers(
            picture=self.picture,
            randomize_rows=True,
            seed=1,
        )

        rows = problem["rows"]
        ordered_pairs = [(9, 1), (8, 2), (7, 3), (6, 4), (5, 5), (4, 6), (3, 7), (2, 8), (1, 9)]
        randomized_pairs = [(row["first_part"], row["second_part"]) for row in rows]

        self.assertNotEqual(randomized_pairs, ordered_pairs)
        self.assertCountEqual(randomized_pairs, ordered_pairs)

    def test_raises_for_whole_less_than_two(self) -> None:
        with self.assertRaisesRegex(ValueError, "whole must be at least 2"):
            compose_and_decompose_numbers(picture=self.picture, whole=1)


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