from __future__ import annotations

from dataclasses import dataclass
from typing import Any


@dataclass(frozen=True)
class V2ApiConfig:
    host: str = "0.0.0.0"
    port: int = 8080


@dataclass(frozen=True)
class V2AuthConfig:
    token_env: str = "MVP_INTERNAL_TOKEN"


@dataclass(frozen=True)
class V2SqliteConfig:
    db_path: str


@dataclass(frozen=True)
class V2SchedulerConfig:
    tick_s: int = 5
    retry_interval_s: int = 60
    max_running_tasks: int = 1


@dataclass(frozen=True)
class V2Config:
    api: V2ApiConfig
    auth: V2AuthConfig
    sqlite: V2SqliteConfig
    scheduler: V2SchedulerConfig

    @staticmethod
    def from_root_dict(root: dict[str, Any]) -> "V2Config":
        # New format: root.service
        # Backward compatible: root.v2
        service = root.get("service")
        if service is None:
            service = root.get("v2") or {}
        if not isinstance(service, dict):
            raise ValueError("config.service must be a mapping")

        api = service.get("api") or {}
        auth = service.get("auth") or {}
        sqlite = service.get("sqlite") or {}
        scheduler = service.get("scheduler") or {}

        if not isinstance(api, dict) or not isinstance(auth, dict) or not isinstance(sqlite, dict) or not isinstance(scheduler, dict):
            raise ValueError("config.service.{api,auth,sqlite,scheduler} must be mappings")

        ray = root.get("ray")
        if isinstance(ray, dict) and ray.get("shared_root"):
            shared_root = str(ray.get("shared_root"))
        else:
            shared_root = str(root.get("shared_root") or "/private")

        default_db_path = f"{shared_root}/common/db/mvp.sqlite3"
        db_path = str(sqlite.get("db_path") or default_db_path)

        return V2Config(
            api=V2ApiConfig(
                host=str(api.get("host") or "0.0.0.0"),
                port=int(api.get("port") or 8080),
            ),
            auth=V2AuthConfig(token_env=str(auth.get("token_env") or "MVP_INTERNAL_TOKEN")),
            sqlite=V2SqliteConfig(db_path=db_path),
            scheduler=V2SchedulerConfig(
                tick_s=int(scheduler.get("tick_s") or 5),
                retry_interval_s=int(scheduler.get("retry_interval_s") or 60),
                max_running_tasks=int(scheduler.get("max_running_tasks") or 1),
            ),
        )
