import json

import pytest
from loguru import logger
from pydantic import ValidationError

from mlgame.core.exceptions import ErrorEnum
from mlgame.core.model import (
    MLGameEntityWrapperSchema,
    GameProgressSchema,
    GameInfoSchema,
    GameErrorSchema,
    MLGameDataType, SystemMsgSchema,
)
from mlgame.view.view_model import get_dummy_progress_data


def test_game_progress_schema():
    data = [
        {
            "frame": 1,
            "background": [],
            "object_list": [
                {
                    "type": "image",
                    "x": 490,
                    "y": 391,
                    "width": 10,
                    "height": 10,
                    "image_id": "ball",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 400,
                    "width": 40,
                    "height": 10,
                    "image_id": "board",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 425,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 500,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 60,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 60,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 70,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 425,
                    "y": 80,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 450,
                    "y": 80,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 500,
                    "y": 80,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 525,
                    "y": 80,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 80,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 90,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 100,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 110,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 110,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 110,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 120,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 120,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 425,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 450,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 500,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 525,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 140,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 150,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 150,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 150,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 150,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 425,
                    "y": 160,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 160,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 525,
                    "y": 160,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 450,
                    "y": 170,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 170,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 500,
                    "y": 170,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 180,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 190,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 450,
                    "y": 200,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 500,
                    "y": 200,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 425,
                    "y": 210,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 525,
                    "y": 210,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 220,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 220,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 220,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
            ],
            "toggle_with_bias": [],
            "toggle": [],
            "foreground": [
                {
                    "type": "text",
                    "content": "catching ball: 0",
                    "color": "#FFFFFF",
                    "x": 430,
                    "y": 479,
                    "font-style": "16px Arial",
                },
                {
                    "type": "text",
                    "content": "remain brick: 36",
                    "color": "#FFFFFF",
                    "x": 430,
                    "y": 459,
                    "font-style": "16px Arial",
                },
                {
                    "type": "text",
                    "content": "remain hard brick: 11",
                    "color": "#FFFFFF",
                    "x": 430,
                    "y": 439,
                    "font-style": "16px Arial",
                },
            ],
            "user_info": [],
            "game_sys_info": {},
        },
        {
            "frame": 2,
            "background": [],
            "object_list": [
                {
                    "type": "image",
                    "x": 483,
                    "y": 384,
                    "width": 10,
                    "height": 10,
                    "image_id": "ball",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 470,
                    "y": 400,
                    "width": 40,
                    "height": 10,
                    "image_id": "board",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 425,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 500,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 50,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 60,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 60,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 70,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 425,
                    "y": 80,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 450,
                    "y": 80,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 500,
                    "y": 80,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 525,
                    "y": 80,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 80,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 90,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 100,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 110,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 110,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 110,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 120,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 120,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 425,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 450,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 500,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 525,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 130,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 140,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 150,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 150,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 150,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 150,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 425,
                    "y": 160,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 160,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 525,
                    "y": 160,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 450,
                    "y": 170,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 170,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 500,
                    "y": 170,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 180,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 475,
                    "y": 190,
                    "width": 25,
                    "height": 10,
                    "image_id": "hard_brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 450,
                    "y": 200,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 500,
                    "y": 200,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 425,
                    "y": 210,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 525,
                    "y": 210,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 400,
                    "y": 220,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 550,
                    "y": 220,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
                {
                    "type": "image",
                    "x": 575,
                    "y": 220,
                    "width": 25,
                    "height": 10,
                    "image_id": "brick",
                    "angle": 0,
                },
            ],
            "toggle_with_bias": [],
            "toggle": [],
            "foreground": [
                {
                    "type": "text",
                    "content": "catching ball: 0",
                    "color": "#FFFFFF",
                    "x": 430,
                    "y": 479,
                    "font-style": "16px Arial",
                },
                {
                    "type": "text",
                    "content": "remain brick: 36",
                    "color": "#FFFFFF",
                    "x": 430,
                    "y": 459,
                    "font-style": "16px Arial",
                },
                {
                    "type": "text",
                    "content": "remain hard brick: 11",
                    "color": "#FFFFFF",
                    "x": 430,
                    "y": 439,
                    "font-style": "16px Arial",
                },
            ],
            "user_info": [],
            "game_sys_info": {},
        },
    ]
    progress = []
    for obj in data:
        progress.append(GameProgressSchema.model_validate(obj).__dict__)
    dummy_progress =get_dummy_progress_data()
    key_of_dummy = dummy_progress.keys()
    assert key_of_dummy == progress[0].keys()

    invalid_data = {
        "frame": "invalid_frame",
        "background": "invalid_background",
        "object_list": "invalid_object_list",
        "toggle": "invalid_toggle",
        "toggle_with_bias": "invalid_toggle_with_bias",
        "foreground": "invalid_foreground",
        "game_sys_info": "invalid_game_sys_info",
        "musics": "invalid_musics",
        "sounds": "invalid_sounds"
    }

    with pytest.raises(ValidationError):
        GameProgressSchema(**invalid_data)


def test_game_info_schema():
    game_info ={"scene": {"color": "#54AFE3", "width": 1000, "bias_x": 0, "bias_y": 0, "height": 500}, "assets": [{"url": "https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/arkanoid/main/asset/img/brick.png", "type": "image", "width": 25, "height": 10, "image_id": "brick", "file_path": "/game/src/../asset/img/brick.png"}, {"url": "https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/arkanoid/main/asset/img/hard_brick.png", "type": "image", "width": 25, "height": 10, "image_id": "hard_brick", "file_path": "/game/src/../asset/img/hard_brick.png"}, {"url": "https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/arkanoid/main/asset/img/ball.png", "type": "image", "width": 5, "height": 5, "image_id": "ball", "file_path": "/game/src/../asset/img/ball.png"}, {"url": "https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/arkanoid/main/asset/img/board.png", "type": "image", "width": 40, "height": 5, "image_id": "board", "file_path": "/game/src/../asset/img/board.png"}, {"url": "https://raw.githubusercontent.com/PAIA-Playful-AI-Arena/arkanoid/main/asset/img/bg.png", "type": "image", "width": 1000, "height": 500, "image_id": "bg", "file_path": "/game/src/../asset/img/bg.png"}], "background": [{"x": 0, "y": 0, "type": "image", "angle": 0, "width": 1000, "height": 500, "image_id": "bg"}],"musics":[],"sounds":[] }
    validated_obj = GameInfoSchema.model_validate(game_info).__dict__

    invalid_game_info = {
        "scene": "invalid_scene",
        "assets": "invalid_assets",
        "background": "invalid_background",
        "musics": "invalid_musics",
        "sounds": "invalid_sounds"
    }

    with pytest.raises(ValidationError):
        GameInfoSchema(**invalid_game_info)
    # assert game_info.keys() == validated_obj.keys()
    pass

def test_ml_game_entity_wrapper_schema():
    # Test with GameProgressSchema
    progress_data = GameProgressSchema(frame=1)
    wrapper = MLGameEntityWrapperSchema(data=progress_data)
    assert wrapper.type == MLGameDataType.GAME_PROGRESS

    # Test with GameInfoSchema
    info_data = GameInfoSchema(scene={"key": "value"})
    wrapper = MLGameEntityWrapperSchema(data=info_data)
    assert wrapper.type == MLGameDataType.GAME_INFO

    # Test with GameErrorSchema
    error_data = GameErrorSchema(message="An error occurred", error_type=ErrorEnum.GAME_EXEC_ERROR, frame=123)
    wrapper = MLGameEntityWrapperSchema(data=error_data)
    assert wrapper.type == MLGameDataType.GAME_ERROR

    # Test with invalid data type
    with pytest.raises(ValueError):
        wrapper = MLGameEntityWrapperSchema(data="Invalid data type")

def test_json_dumps_entity():
    obj = MLGameEntityWrapperSchema(
        type=MLGameDataType.SYSTEM_MSG,
        data=SystemMsgSchema(message="system")
    )
    logger.info(obj)
    json_str = obj.model_dump_json()
    logger.info(json_str)
    assert json.loads(json_str)

    obj = MLGameEntityWrapperSchema(
        type=MLGameDataType.GAME_INFO,
        # data=GameInfoSchema(scene={})
        data=GameErrorSchema(error_type=ErrorEnum.GAME_EXEC_ERROR, frame=1)
    )
    assert obj.type == MLGameDataType.GAME_ERROR
    logger.info(obj)
    json_str = obj.model_dump_json()
    logger.info(json_str)


    obj = MLGameEntityWrapperSchema(
        type=MLGameDataType.GAME_INFO,
        data=GameInfoSchema(scene={})
    )
    assert obj.type == MLGameDataType.GAME_INFO
    logger.info(obj)
    json_str = obj.model_dump_json()
    logger.info(json_str)
    result = obj.model_dump(mode='json')
    logger.info(result)

def test_game_info():
    obj = GameInfoSchema(scene={"key": "value"})
    logger.info(obj)
    json_str = obj.model_dump_json()

    logger.info(json_str)