import unittest

from fastapi.testclient import TestClient

from app.main import create_app


class SumWithImageReferenceEndpointTest(unittest.TestCase):
    def setUp(self) -> None:
        self.client = TestClient(create_app())
        self.first_picture = {
            "id": "red-flower",
            "name": "Red flower",
            "image_path": "/images/red-flower.png",
        }
        self.second_picture = {
            "id": "white-flower",
            "name": "White flower",
            "image_path": "/images/white-flower.png",
        }

    def test_creates_problem_with_one_correct_option(self) -> None:
        response = self.client.post(
            "/math/grade_1/sum_with_image_reference",
            json={
                "first_quantity": 5,
                "second_quantity": 4,
                "first_description": "flores rojas",
                "second_description": "flores blancas",
                "common_object": "flores",
                "first_picture": self.first_picture,
                "second_picture": self.second_picture,
                "option_count": 3,
                "seed": 1,
            },
        )

        self.assertEqual(response.status_code, 200)
        problem = response.json()
        correct_options = [option for option in problem["options"] if option["is_correct"]]

        self.assertEqual(
            problem["question"],
            "Hay 5 flores rojas y 4 flores blancas, ¿cuántas flores hay en total?",
        )
        self.assertEqual(problem["instructions"], "Escoge la imagen en la próxima página.")
        self.assertEqual(problem["total"], 9)
        self.assertEqual(len(problem["options"]), 3)
        self.assertEqual(len(correct_options), 1)
        self.assertEqual(correct_options[0]["quantity"], 9)
        self.assertEqual(correct_options[0]["first_group"]["quantity"], 5)
        self.assertEqual(correct_options[0]["second_group"]["quantity"], 4)

        for option in problem["options"]:
            first_group = option["first_group"]
            second_group = option["second_group"]

            self.assertEqual(option["quantity"], first_group["quantity"] + second_group["quantity"])
            self.assertEqual(first_group["description"], "flores rojas")
            self.assertEqual(second_group["description"], "flores blancas")
            self.assertEqual(first_group["picture"], self.first_picture)
            self.assertEqual(second_group["picture"], self.second_picture)

    def test_returns_bad_request_when_total_is_outside_option_range(self) -> None:
        response = self.client.post(
            "/math/grade_1/sum_with_image_reference",
            json={
                "first_quantity": 5,
                "second_quantity": 4,
                "first_description": "flores rojas",
                "second_description": "flores blancas",
                "common_object": "flores",
                "first_picture": self.first_picture,
                "second_picture": self.second_picture,
                "min_option_quantity": 1,
                "max_option_quantity": 8,
            },
        )

        self.assertEqual(response.status_code, 400)
        self.assertEqual(
            response.json(),
            {"detail": "option quantity range must include the correct total"},
        )


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