from dataclasses import dataclass, field
from typing import Optional

from config.v2_config import V2Config, SlackConfig, DiscordConfig, TelegramConfig, LarkConfig, WeChatConfig


@dataclass
class ClaudeCompatConfig:
    permission_mode: str
    cwd: str
    system_prompt: Optional[str] = None
    default_model: Optional[str] = None
    cli_path: Optional[str] = None

    def __post_init__(self) -> None:
        self.permission_mode = str(self.permission_mode)
        self.cwd = str(self.cwd)
        if self.cli_path is not None:
            self.cli_path = str(self.cli_path)


@dataclass
class CodexCompatConfig:
    binary: str
    extra_args: list[str]
    default_model: Optional[str] = None


@dataclass
class OpenCodeCompatConfig:
    binary: str
    port: int
    request_timeout_seconds: int
    error_retry_limit: int = 1  # Max retries on LLM stream errors (0 = no retry)


@dataclass
class AppCompatConfig:
    platform: str
    slack: SlackConfig
    claude: ClaudeCompatConfig
    log_level: str
    ack_mode: str
    language: str
    platforms: dict = field(default_factory=lambda: {"enabled": ["slack"], "primary": "slack"})
    discord: Optional[DiscordConfig] = None
    telegram: Optional[TelegramConfig] = None
    lark: Optional[LarkConfig] = None
    wechat: Optional[WeChatConfig] = None
    codex: Optional[CodexCompatConfig] = None
    opencode: Optional[OpenCodeCompatConfig] = None
    show_duration: bool = False
    include_user_info: bool = True
    reply_enhancements: bool = True
    default_backend: str = "opencode"

    def enabled_platforms(self) -> list[str]:
        enabled = self.platforms.get("enabled") if isinstance(self.platforms, dict) else None
        if isinstance(enabled, list) and enabled:
            return [str(platform) for platform in enabled]
        return [self.platform]


def to_app_config(v2: V2Config) -> AppCompatConfig:
    claude = ClaudeCompatConfig(
        permission_mode="bypassPermissions",
        cwd=v2.runtime.default_cwd,
        system_prompt=None,
        default_model=v2.agents.claude.default_model,
        cli_path=v2.agents.claude.cli_path,
    )
    codex = None
    if v2.agents.codex.enabled:
        codex = CodexCompatConfig(
            binary=v2.agents.codex.cli_path,
            extra_args=[],
            default_model=v2.agents.codex.default_model,
        )
    opencode = None
    if v2.agents.opencode.enabled:
        opencode = OpenCodeCompatConfig(
            binary=v2.agents.opencode.cli_path,
            port=4096,
            request_timeout_seconds=60,
            error_retry_limit=v2.agents.opencode.error_retry_limit,
        )
    slack = SlackConfig(**v2.slack.__dict__)
    return AppCompatConfig(
        platform=v2.platform,
        platforms={
            "enabled": v2.platforms.enabled,
            "primary": v2.platforms.primary,
        },
        slack=slack,
        discord=v2.discord,
        telegram=v2.telegram,
        lark=v2.lark,
        wechat=v2.wechat,
        claude=claude,
        codex=codex,
        opencode=opencode,
        log_level=v2.runtime.log_level,
        ack_mode=v2.ack_mode,
        language=v2.language,
        show_duration=v2.show_duration,
        include_user_info=v2.include_user_info,
        reply_enhancements=v2.reply_enhancements,
        default_backend=v2.agents.default_backend,
    )
