from platformdirs import user_config_dir
from typing import Literal
from pathlib import Path

from texmemo.types import ConfigType, SplitConfig

CONFIG_DIR = Path(user_config_dir("ankisync"))
CONFIG_FILE = CONFIG_DIR / "config.json"


class Config():
    def __init__(self):
        pass

    def get_default_config(self) -> ConfigType:
        """Gets the default configuration

        Returns:
            ConfigType: the configuration object
        """
        config = {
            "split": [
                {"env": "theorem", "on": "next"},
                {"env": "example", "on": "subtitle"},
                {"env": "proposition", "on": "next"},
                {"env": "lemma", "on": "next"},
                {"env": "definition", "on": "subtitle"}
            ]
        }
        return ConfigType.model_validate(config)

    def setup_config(self):
        """Creates the configuration file with default if it doesn't exist.
        """
        if not CONFIG_FILE.exists():
            CONFIG_DIR.mkdir(parents=True, exist_ok=True)
            config = self.get_default_config()
            CONFIG_FILE.write_text(config.model_dump_json(indent=2))

    def _read_config(self) -> ConfigType:
        """Reads the configuration file

        Returns:
            ConfigType: Config object
        """
        with open(CONFIG_FILE, "r") as f:
            return ConfigType.model_validate_json(f.read())

    def get_split_config(self, environment: str) -> SplitConfig:
        """Gets the split configuration for a particular environment

        Args:
            environment (str): name of the TeX environment

        Raises:
            ValueError: If the environment is not in the configuration

        Returns:
            SplitConfig: The configuration object
        """
        split = self.get_field('split')
        config = [x for x in split if x.env == environment]
        if not config:
            raise ValueError(
                f"Could not find config for environment {environment}")
        return config[0]

    def get_field(self, field: Literal["split"]) -> list[SplitConfig]:
        """Get the field of the configuration object

        Args:
            field (Literal[&quot;split&quot;]): the desired field

        Returns:
            list[SplitConfig]: the configuration of the desired field
        """
        config = self._read_config()
        return getattr(config, field)

    def set_field(self, field: Literal["split"], value: list[SplitConfig]):
        """Sets the field in the configuration object

        Args:
            field (Literal[&quot;split&quot;]): the field to be set
            value (list[SplitConfig]): the new value to be set
        """
        config = self._read_config()
        setattr(config, field, value)
        CONFIG_FILE.write_text(config.model_dump_json(indent=2))
