from __future__ import annotations

from dataclasses import dataclass, field
from typing import Literal

from loushang.agent import ThinkingLevel
from loushang.ai.options import ThinkingBudgets, Transport
from loushang.coding.package import PackageSourceConfig
from loushang.coding.types import ModelSelection

QueueMode = Literal["all", "one-at-a-time"]
DoubleEscapeAction = Literal["fork", "tree", "none"]
TreeFilterMode = Literal["default", "no-tools", "user-only", "labeled-only", "all"]
ExternalToolPolicy = Literal["never", "auto", "required"]
HeadlessApprovalMode = Literal["allow", "deny"]
KeybindingValue = str | tuple[str, ...] | None


@dataclass(frozen=True)
class CompactionSettings:
    enabled: bool = True
    compact_percent: float = 80.0
    reserve_tokens: int = 8_192
    keep_recent_tokens: int = 32_768


@dataclass(frozen=True)
class BranchSummarySettings:
    enabled: bool = True
    reserve_tokens: int = 8_192
    skip_prompt: bool = False


@dataclass(frozen=True)
class RetrySettings:
    enabled: bool = True
    max_retries: int = 2
    base_delay_ms: int = 250
    provider_timeout_ms: int | None = None
    provider_max_retries: int | None = None
    provider_max_retry_delay_ms: int = 60_000


@dataclass(frozen=True)
class ImageSettings:
    auto_resize: bool = True
    block_images: bool = False


@dataclass(frozen=True)
class TerminalSettings:
    show_images: bool = True
    image_width_cells: int = 60
    clear_on_shrink: bool = False
    show_terminal_progress: bool = False


@dataclass(frozen=True)
class MarkdownSettings:
    code_block_indent: str = "  "


@dataclass(frozen=True)
class WarningSettings:
    anthropic_extra_usage: bool = True


@dataclass(frozen=True)
class MethodSettings:
    mode: str = "explicit"
    selected_method: str | None = None


@dataclass(frozen=True)
class ToolSettings:
    external_tool_policy: ExternalToolPolicy = "auto"
    blocked_tools: tuple[str, ...] = ()
    ask_tools: tuple[str, ...] = ()
    blocked_substrings: tuple[str, ...] = ()
    ask_substrings: tuple[str, ...] = ()
    blocked_path_substrings: tuple[str, ...] = ()
    ask_path_substrings: tuple[str, ...] = ()
    approval_mode: HeadlessApprovalMode | None = None
    approval_reason: str | None = None


@dataclass(frozen=True)
class ControlConfig:
    default_model: ModelSelection | None = None
    thinking_level: ThinkingLevel = "off"
    steering_mode: QueueMode = "one-at-a-time"
    follow_up_mode: QueueMode = "one-at-a-time"
    transport: Transport = "sse"
    theme: str | None = None
    system_prompt: str = ""
    hide_thinking_block: bool = False
    shell_path: str | None = None
    quiet_startup: bool = False
    shell_command_prefix: str | None = None
    npm_command: tuple[str, ...] | None = None
    collapse_changelog: bool = False
    enable_install_telemetry: bool = True
    enable_skill_commands: bool = True
    enabled_models: tuple[str, ...] | None = None
    double_escape_action: DoubleEscapeAction = "tree"
    tree_filter_mode: TreeFilterMode = "default"
    show_hardware_cursor: bool = False
    editor_padding_x: int = 0
    autocomplete_max_visible: int = 5
    keybindings: dict[str, KeybindingValue] = field(default_factory=dict)
    thinking_budgets: ThinkingBudgets | None = None
    compaction: CompactionSettings = field(default_factory=CompactionSettings)
    branch_summary: BranchSummarySettings = field(default_factory=BranchSummarySettings)
    retry: RetrySettings = field(default_factory=RetrySettings)
    images: ImageSettings = field(default_factory=ImageSettings)
    terminal: TerminalSettings = field(default_factory=TerminalSettings)
    markdown: MarkdownSettings = field(default_factory=MarkdownSettings)
    warnings: WarningSettings = field(default_factory=WarningSettings)
    method: MethodSettings = field(default_factory=MethodSettings)
    tools: ToolSettings = field(default_factory=ToolSettings)
    session_dir: str | None = None
    resource_roots: tuple[str, ...] = ()
    package_roots: tuple[str, ...] = ()
    package_sources: tuple[PackageSourceConfig, ...] = ()
    plugin_sources: tuple[str, ...] = ()
    disabled_skills: tuple[str, ...] = ()
    disabled_plugins: tuple[str, ...] = ()

__all__ = [
    "BranchSummarySettings",
    "CompactionSettings",
    "ControlConfig",
    "DoubleEscapeAction",
    "ExternalToolPolicy",
    "HeadlessApprovalMode",
    "ImageSettings",
    "KeybindingValue",
    "MarkdownSettings",
    "MethodSettings",
    "QueueMode",
    "RetrySettings",
    "TerminalSettings",
    "ToolSettings",
    "TreeFilterMode",
    "WarningSettings",
]
