import sys
import os
import pathlib
import json
from typing import List, Union


class ThemeManager:

    theme: dict = {}  # contains all the theme data
    _built_in_themes: List[str] = ["blue", "green", "gold", "dark-blue"]
    _currently_loaded_theme: Union[str, None] = None

    @classmethod
    def load_theme(cls, theme_name_or_path: str):
        script_directory = os.path.dirname(os.path.abspath(__file__))

        if theme_name_or_path in cls._built_in_themes:
            customtkinter_path = pathlib.Path(script_directory).parent.parent.parent
            with open(os.path.join(customtkinter_path, "assets", "themes", f"{theme_name_or_path}.json"), "r") as f:
                cls.theme = json.load(f)
        else:
            with open(theme_name_or_path, "r") as f:
                cls.theme = json.load(f)

        # store theme path for saving
        cls._currently_loaded_theme = theme_name_or_path

        # filter theme values for platform
        for key in cls.theme.keys():
            # check if values for key differ on platforms
            if "macOS" in cls.theme[key].keys():
                if sys.platform == "darwin":
                    cls.theme[key] = cls.theme[key]["macOS"]
                elif sys.platform.startswith("win"):
                    cls.theme[key] = cls.theme[key]["Windows"]
                else:
                    cls.theme[key] = cls.theme[key]["Linux"]

        # fix name inconsistencies
        if "CTkCheckbox" in cls.theme.keys():
            cls.theme["CTkCheckBox"] = cls.theme.pop("CTkCheckbox")
        if "CTkRadiobutton" in cls.theme.keys():
            cls.theme["CTkRadioButton"] = cls.theme.pop("CTkRadiobutton")
        if "CTkLabel" in cls.theme.keys():
            if "border_width" not in cls.theme["CTkLabel"].keys():
                cls.theme["CTkLabel"]["border_width"] = 0
            if "border_color" not in cls.theme["CTkLabel"].keys():
                cls.theme["CTkLabel"]["border_color"] = ["black", "white"]

    @classmethod
    def save_theme(cls):
        if cls._currently_loaded_theme is not None:
            if cls._currently_loaded_theme not in cls._built_in_themes:
                with open(cls._currently_loaded_theme, "r") as f:
                    json.dump(cls.theme, f, indent=2)
            else:
                raise ValueError(f"cannot modify builtin theme '{cls._currently_loaded_theme}'")
        else:
            raise ValueError(f"cannot save theme, no theme is loaded")
