import json
import os
from dataclasses import dataclass, field
from typing import List, Optional

CONFIG_VERSION = 2


@dataclass
class Profile:
    name: str
    esde_src: str = ""
    roms_src: str = ""
    esde_dst: str = ""
    roms_dst: str = ""
    selected: List[str] = field(default_factory=list)

    def to_dict(self) -> dict:
        return {
            "name": self.name,
            "esde_src": self.esde_src,
            "roms_src": self.roms_src,
            "esde_dst": self.esde_dst,
            "roms_dst": self.roms_dst,
            "selected": self.selected,
        }

    @staticmethod
    def from_dict(data: dict) -> "Profile":
        return Profile(
            name=data.get("name", "Default"),
            esde_src=data.get("esde_src", ""),
            roms_src=data.get("roms_src", ""),
            esde_dst=data.get("esde_dst", ""),
            roms_dst=data.get("roms_dst", ""),
            selected=data.get("selected", []),
        )


class ConfigManager:
    def __init__(self, config_path: str):
        self.config_path = config_path
        self.profiles: List[Profile] = [Profile(name="Default")]
        self.active_profile_name: str = "Default"

    @property
    def active_profile(self) -> Profile:
        for p in self.profiles:
            if p.name == self.active_profile_name:
                return p
        # Si el perfil activo no existe, devolver el primero
        return self.profiles[0]

    def profile_names(self) -> List[str]:
        return [p.name for p in self.profiles]

    def get_profile(self, name: str) -> Optional[Profile]:
        for p in self.profiles:
            if p.name == name:
                return p
        return None

    def add_profile(self, name: str) -> Profile:
        p = Profile(name=name)
        self.profiles.append(p)
        return p

    def rename_profile(self, old_name: str, new_name: str) -> bool:
        p = self.get_profile(old_name)
        if p is None or self.get_profile(new_name) is not None:
            return False
        p.name = new_name
        if self.active_profile_name == old_name:
            self.active_profile_name = new_name
        return True

    def delete_profile(self, name: str) -> bool:
        if len(self.profiles) <= 1:
            return False
        p = self.get_profile(name)
        if p is None:
            return False
        self.profiles.remove(p)
        if self.active_profile_name == name:
            self.active_profile_name = self.profiles[0].name
        return True

    def load(self) -> None:
        if not os.path.exists(self.config_path):
            return

        try:
            with open(self.config_path, "r", encoding="utf-8") as f:
                data = json.load(f)
        except Exception:
            return

        version = data.get("version", 1)

        if version == 1:
            self._migrate_v1(data)
            self.save()
        else:
            self._load_v2(data)

    def _migrate_v1(self, data: dict) -> None:
        default = Profile(
            name="Default",
            esde_src=data.get("esde_src", ""),
            roms_src=data.get("roms_src", ""),
            esde_dst=data.get("esde_dst", ""),
            roms_dst=data.get("roms_dst", ""),
            selected=data.get("selected", []),
        )
        self.profiles = [default]
        self.active_profile_name = "Default"

    def _load_v2(self, data: dict) -> None:
        raw_profiles = data.get("profiles", [])
        if not raw_profiles:
            return
        self.profiles = [Profile.from_dict(p) for p in raw_profiles]
        self.active_profile_name = data.get("active_profile", self.profiles[0].name)
        # Asegurar que el perfil activo existe
        if self.get_profile(self.active_profile_name) is None:
            self.active_profile_name = self.profiles[0].name

    def save(self) -> None:
        data = {
            "version": CONFIG_VERSION,
            "active_profile": self.active_profile_name,
            "profiles": [p.to_dict() for p in self.profiles],
        }
        with open(self.config_path, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=4, ensure_ascii=False)
