"""Reusable profile manager for per-integration configs."""

from __future__ import annotations

import json
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Dict, List


class ProfileNotFoundError(Exception):
    pass


@dataclass
class ProfileStore:
    path: Path
    default_profile: str = "default"
    current: str = ""
    profiles: Dict[str, Dict[str, Any]] = field(default_factory=dict)

    @classmethod
    def load(cls, path: Path, default_profile: str = "default") -> "ProfileStore":
        if not path.exists():
            return cls(path=path, default_profile=default_profile, current=default_profile, profiles={})
        try:
            raw = json.loads(path.read_text(encoding="utf-8"))
        except Exception:
            return cls(path=path, default_profile=default_profile, current=default_profile, profiles={})

        if isinstance(raw, dict) and "profiles" in raw:
            current = str(raw.get("current") or default_profile)
            profiles = raw.get("profiles") or {}
            if not isinstance(profiles, dict):
                profiles = {}
            return cls(path=path, default_profile=default_profile, current=current, profiles=profiles)

        # Legacy single-profile format (flat dict)
        if isinstance(raw, dict):
            return cls(
                path=path,
                default_profile=default_profile,
                current=default_profile,
                profiles={default_profile: raw},
            )

        return cls(path=path, default_profile=default_profile, current=default_profile, profiles={})

    def save(self) -> None:
        payload = {
            "current": self.current or self.default_profile,
            "profiles": self.profiles,
        }
        self.path.parent.mkdir(parents=True, exist_ok=True)
        self.path.write_text(json.dumps(payload, indent=2), encoding="utf-8")

    def list_profiles(self) -> List[str]:
        return sorted(self.profiles.keys())

    def get_profile(self, name: str | None = None) -> Dict[str, Any]:
        profile_name = name or self.current or self.default_profile
        if profile_name not in self.profiles:
            raise ProfileNotFoundError(f"Profile not found: {profile_name}")
        return self.profiles[profile_name]

    def set_profile(self, name: str, data: Dict[str, Any], *, set_current: bool = False) -> None:
        self.profiles[name] = data
        if set_current or not self.current or self.current not in self.profiles:
            # If current is unset, auto-promote first saved profile.
            self.current = name

    def set_current(self, name: str) -> None:
        if name not in self.profiles:
            raise ProfileNotFoundError(f"Profile not found: {name}")
        self.current = name

    def current_profile_name(self) -> str:
        if self.current and self.current in self.profiles:
            return self.current
        if self.default_profile in self.profiles:
            return self.default_profile
        if self.profiles:
            return sorted(self.profiles.keys())[0]
        return self.default_profile
