import json
import os
from dataclasses import dataclass, asdict
from typing import Dict, Any, List


def get_app_dir(app_name="AutoKeyPremium") -> str:
    base = os.environ.get("APPDATA") or os.path.expanduser("~")
    path = os.path.join(base, app_name)
    os.makedirs(path, exist_ok=True)
    return path


def get_config_path() -> str:
    return os.path.join(get_app_dir(), "profiles.json")


@dataclass
class Profile:
    name: str = "Default"
    keys: List[str] = None
    stop_key: str = "f12"

    interval_mode: str = "fixed"     # fixed | random | smart
    interval_fixed: int = 13

    interval_min: int = 10
    interval_max: int = 18

    smart_base: int = 13
    smart_jitter_pct: int = 12

    auto_start: bool = False

    def to_dict(self) -> Dict[str, Any]:
        d = asdict(self)
        d["keys"] = self.keys or ["e"]
        return d

    @staticmethod
    def from_dict(data: Dict[str, Any]) -> "Profile":
        p = Profile()
        p.name = str(data.get("name", "Default"))
        p.keys = list(data.get("keys") or ["e"])
        p.stop_key = str(data.get("stop_key", "f12")).lower()

        p.interval_mode = str(data.get("interval_mode", "fixed"))
        p.interval_fixed = int(data.get("interval_fixed", 13))

        p.interval_min = int(data.get("interval_min", 10))
        p.interval_max = int(data.get("interval_max", 18))

        p.smart_base = int(data.get("smart_base", 13))
        p.smart_jitter_pct = int(data.get("smart_jitter_pct", 12))

        p.auto_start = bool(data.get("auto_start", False))
        return p


class ProfileStore:
    def __init__(self):
        self.path = get_config_path()
        self.data = {"active": "Default", "profiles": {}}
        self.load()

    def load(self):
        if not os.path.exists(self.path):
            # create default
            self.data["profiles"]["Default"] = Profile(name="Default", keys=["e"]).to_dict()
            self.save()
            return

        try:
            with open(self.path, "r", encoding="utf-8") as f:
                self.data = json.load(f)
            if "profiles" not in self.data:
                self.data = {"active": "Default", "profiles": {}}
        except Exception:
            self.data = {"active": "Default", "profiles": {}}

        if "Default" not in self.data["profiles"]:
            self.data["profiles"]["Default"] = Profile(name="Default", keys=["e"]).to_dict()

        if "active" not in self.data or self.data["active"] not in self.data["profiles"]:
            self.data["active"] = "Default"

        self.save()

    def save(self):
        with open(self.path, "w", encoding="utf-8") as f:
            json.dump(self.data, f, indent=2)

    def list_profiles(self):
        return sorted(self.data["profiles"].keys())

    def get_active_name(self) -> str:
        return self.data.get("active", "Default")

    def set_active(self, name: str):
        if name in self.data["profiles"]:
            self.data["active"] = name
            self.save()

    def get_profile(self, name: str) -> Profile:
        if name not in self.data["profiles"]:
            name = "Default"
        return Profile.from_dict(self.data["profiles"][name])

    def upsert_profile(self, profile: Profile):
        self.data["profiles"][profile.name] = profile.to_dict()
        if self.data.get("active") not in self.data["profiles"]:
            self.data["active"] = profile.name
        self.save()

    def delete_profile(self, name: str):
        if name == "Default":
            return
        if name in self.data["profiles"]:
            del self.data["profiles"][name]
            if self.data.get("active") == name:
                self.data["active"] = "Default"
            self.save()
