# Path: socceraction/spadl/schema.py
# class SPADLSchema(pa.SchemaModel):
#     """Definition of a SPADL dataframe."""
# 
#     game_id: Series[Any] = pa.Field()
#     original_event_id: Series[Any] = pa.Field(nullable=True)
#     action_id: Series[int] = pa.Field()
#     period_id: Series[int] = pa.Field(ge=1, le=5)
#     time_seconds: Series[float] = pa.Field(ge=0)
#     team_id: Series[Any] = pa.Field()
#     player_id: Series[Any] = pa.Field()
#     start_x: Series[float] = pa.Field(ge=0, le=spadlconfig.field_length)
#     start_y: Series[float] = pa.Field(ge=0, le=spadlconfig.field_width)
#     end_x: Series[float] = pa.Field(ge=0, le=spadlconfig.field_length)
#     end_y: Series[float] = pa.Field(ge=0, le=spadlconfig.field_width)
#     bodypart_id: Series[int] = pa.Field(isin=spadlconfig.bodyparts_df().bodypart_id)
#     bodypart_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.bodyparts_df().bodypart_name)
#     type_id: Series[int] = pa.Field(isin=spadlconfig.actiontypes_df().type_id)
#     type_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.actiontypes_df().type_name)
#     result_id: Series[int] = pa.Field(isin=spadlconfig.results_df().result_id)
#     result_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.results_df().result_name)
# 
#     class Config:  # noqa: D106
#         strict = True
#         coerce = True
# 
# Path: socceraction/spadl/config.py
# def actiontypes_df() -> pd.DataFrame:
# def results_df() -> pd.DataFrame:
# def bodyparts_df() -> pd.DataFrame:


import json
import numpy as np
import pandas as pd
import pytest
import socceraction.spadl as spadl
import socceraction.xthreat as xt
from pathlib import Path
from pandera.typing import DataFrame, Series
from pytest_mock import MockerFixture
from sklearn.exceptions import NotFittedError
from socceraction.spadl import SPADLSchema
from socceraction.spadl.config import field_length, field_width
            model.save_model(str(p))
        model.xT = np.zeros((model.w, model.l))
        with pytest.raises(NotFittedError):
            model.save_model(str(p))

    def test_save_model_file_exists(self, tmp_path: Path) -> None:
        """It should raise an exception when the file exists."""
        p = tmp_path / "xt_model.json"
        p.write_text("create file")
        model = xt.ExpectedThreat()
        model.xT = np.ones((model.w, model.l))
        with pytest.raises(ValueError):
            model.save_model(str(p), overwrite=False)
        model.save_model(str(p), overwrite=True)

    def test_load_model(self, tmp_path: Path) -> None:
        """It should load a saved xT grid from a JSON file."""
        # xT grid
        gridv = [[0.1, 0.2], [0.1, 0.0]]
        # write to file
        p = tmp_path / "xt_model.json"
        p.write_text(json.dumps(gridv))
        # load model
        model = xt.load_model(str(p))
        # verify
        assert model.w == 2
        assert model.l == 2
        np.testing.assert_array_equal(model.xT, gridv)



# Path: socceraction/spadl/schema.py
# class SPADLSchema(pa.SchemaModel):
#     """Definition of a SPADL dataframe."""
# 
#     game_id: Series[Any] = pa.Field()
#     original_event_id: Series[Any] = pa.Field(nullable=True)
#     action_id: Series[int] = pa.Field()
#     period_id: Series[int] = pa.Field(ge=1, le=5)
#     time_seconds: Series[float] = pa.Field(ge=0)
#     team_id: Series[Any] = pa.Field()
#     player_id: Series[Any] = pa.Field()
#     start_x: Series[float] = pa.Field(ge=0, le=spadlconfig.field_length)
#     start_y: Series[float] = pa.Field(ge=0, le=spadlconfig.field_width)
#     end_x: Series[float] = pa.Field(ge=0, le=spadlconfig.field_length)
#     end_y: Series[float] = pa.Field(ge=0, le=spadlconfig.field_width)
#     bodypart_id: Series[int] = pa.Field(isin=spadlconfig.bodyparts_df().bodypart_id)
#     bodypart_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.bodyparts_df().bodypart_name)
#     type_id: Series[int] = pa.Field(isin=spadlconfig.actiontypes_df().type_id)
#     type_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.actiontypes_df().type_name)
#     result_id: Series[int] = pa.Field(isin=spadlconfig.results_df().result_id)
#     result_name: Optional[Series[str]] = pa.Field(isin=spadlconfig.results_df().result_name)
# 
#     class Config:  # noqa: D106
#         strict = True
#         coerce = True
# 
# Path: socceraction/spadl/config.py
# def actiontypes_df() -> pd.DataFrame:
# def results_df() -> pd.DataFrame:
# def bodyparts_df() -> pd.DataFrame:


# Path: tests/test_xthreat.py
import json
import numpy as np
import pandas as pd
import pytest
import socceraction.spadl as spadl
import socceraction.xthreat as xt
from pathlib import Path
from pandera.typing import DataFrame, Series
from pytest_mock import MockerFixture
from sklearn.exceptions import NotFittedError
from socceraction.spadl import SPADLSchema
from socceraction.spadl.config import field_length, field_width

            model.save_model(str(p))
        model.xT = np.zeros((model.w, model.l))
        with pytest.raises(NotFittedError):
            model.save_model(str(p))

    def test_save_model_file_exists(self, tmp_path: Path) -> None:
        """It should raise an exception when the file exists."""
        p = tmp_path / "xt_model.json"
        p.write_text("create file")
        model = xt.ExpectedThreat()
        model.xT = np.ones((model.w, model.l))
        with pytest.raises(ValueError):
            model.save_model(str(p), overwrite=False)
        model.save_model(str(p), overwrite=True)

    def test_load_model(self, tmp_path: Path) -> None:
        """It should load a saved xT grid from a JSON file."""
        # xT grid
        gridv = [[0.1, 0.2], [0.1, 0.0]]
        # write to file
        p = tmp_path / "xt_model.json"
        p.write_text(json.dumps(gridv))
        # load model
        model = xt.load_model(str(p))
        # verify
        assert model.w == 2
        assert model.l == 2
        np.testing.assert_array_equal(model.xT, gridv)



def test_get_move_actions(spadl_actions: DataFrame[SPADLSchema]) -> None: