use std::borrow::Cow;

use once_cell::sync::Lazy;
use regex::Regex;

#[derive(Debug, Clone)]
pub(super) struct SectionHeading {
    pub(super) title: Cow<'static, str>,
    pub(super) summary: Cow<'static, str>,
}

static ARRAY_INDEX_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"\[(\d+)\]").expect("valid regex"));

static SECTION_HEADINGS: &[(&str, &str, &str)] = &[
    (
        "acp",
        "ACP Bridge",
        "IDE and Agent Client Protocol integrations.",
    ),
    (
        "acp.zed",
        "Zed Integration",
        "How VT Code connects commands and trust settings to Zed.",
    ),
    (
        "acp.zed.auth",
        "Zed Authentication",
        "Default authentication flow for ACP sessions in Zed.",
    ),
    (
        "acp.zed.tools",
        "Zed Tool Bridge",
        "Which file tools are exposed to the Zed client.",
    ),
    (
        "agent",
        "Agent Defaults",
        "Primary model, prompt, and chat behavior.",
    ),
    (
        "agent.checkpointing",
        "Checkpoints",
        "Automatic turn snapshots and retention limits.",
    ),
    (
        "agent.circuit_breaker",
        "Circuit Breaker",
        "Failure pause thresholds and recovery guardrails.",
    ),
    (
        "agent.codex_app_server",
        "Codex App Server",
        "Local Codex sidecar launch command, startup timeout, and experimental integration switches.",
    ),
    (
        "agent.harness",
        "Harness Limits",
        "Per-turn tool call and timing safety limits.",
    ),
    (
        "agent.onboarding",
        "Onboarding",
        "Welcome message, tips, and first-run guidance.",
    ),
    (
        "agent.open_responses",
        "Open Responses",
        "Compatibility events and response item mapping.",
    ),
    (
        "agent.prompt_suggestions",
        "Prompt Suggestions",
        "Inline composer suggestions and lightweight model routing.",
    ),
    (
        "agent.persistent_memory",
        "Persistent Memory",
        "Per-repository memory summary, rollout staging, and learned durable notes.",
    ),
    (
        "agent.small_model",
        "Lightweight Model Helpers",
        "Low-cost lightweight-model routing for memory and other side tasks.",
    ),
    (
        "agent.vibe_coding",
        "Vibe Coding",
        "Loose-input parsing and extra contextual assistance.",
    ),
    (
        "auth",
        "Authentication",
        "Provider login and token handling.",
    ),
    (
        "auth.openrouter",
        "OpenRouter OAuth",
        "Browser login flow and token refresh behavior.",
    ),
    (
        "automation",
        "Automation",
        "Autonomous run controls and safety defaults.",
    ),
    (
        "automation.full_auto",
        "Full Auto",
        "Guardrails for unattended execution.",
    ),
    (
        "automation.scheduled_tasks",
        "Scheduled Tasks",
        "Session-scoped loops and durable local automation jobs.",
    ),
    (
        "chat",
        "Chat Surface",
        "Interactive chat features and assistant affordances.",
    ),
    (
        "chat.askQuestions",
        "Ask Questions Tool",
        "Inline clarification prompts during chat sessions.",
    ),
    (
        "commands",
        "Command Policies",
        "Allow and deny rules for shell execution.",
    ),
    (
        "custom_providers",
        "Custom Providers",
        "Named OpenAI-compatible endpoints configured in vtcode.toml.",
    ),
    (
        "custom_providers[]",
        "Custom Provider",
        "Display name, base URL, and API key settings for one endpoint.",
    ),
    (
        "context",
        "Context Budget",
        "How much history and workspace context is retained.",
    ),
    (
        "context.dynamic",
        "Dynamic Context",
        "Spooled outputs and generated workspace context artifacts.",
    ),
    (
        "context.ledger",
        "Decision Ledger",
        "Important decisions kept across the session.",
    ),
    (
        "debug",
        "Debug Logging",
        "Tracing and local diagnostics output.",
    ),
    (
        "dotfile_protection",
        "Dotfile Protection",
        "Extra safeguards for shell and editor dotfiles.",
    ),
    (
        "hooks",
        "Lifecycle Hooks",
        "Automations triggered around session events.",
    ),
    (
        "hooks.lifecycle",
        "Lifecycle Events",
        "Hook groups for session and tool milestones.",
    ),
    (
        "ide_context",
        "IDE Context",
        "Cross-IDE active editor context injected into prompts and inline UI.",
    ),
    (
        "ide_context.providers",
        "IDE Providers",
        "Per-editor-family enablement for editor context ingestion.",
    ),
    (
        "ide_context.providers.vscode_compatible",
        "VS Code Family",
        "Enable context snapshots from VS Code, Cursor, Windsurf, and compatible editors.",
    ),
    (
        "ide_context.providers.zed",
        "Zed Family",
        "Enable context snapshots from Zed integrations.",
    ),
    (
        "ide_context.providers.generic",
        "Generic Bridge",
        "Enable file-bridge snapshots from JetBrains and other external adapters.",
    ),
    (
        "mcp",
        "MCP Servers",
        "Model Context Protocol providers and defaults.",
    ),
    (
        "mcp.allowlist",
        "MCP Allowlist",
        "Default restrictions for MCP resources, prompts, and config.",
    ),
    (
        "mcp.allowlist.default",
        "Default MCP Rules",
        "Fallback allowlist applied to every MCP provider.",
    ),
    (
        "mcp.allowlist.providers",
        "Provider Overrides",
        "Per-provider MCP allowlist exceptions.",
    ),
    (
        "mcp.requirements",
        "MCP Requirements",
        "Startup checks and required capabilities for MCP providers.",
    ),
    (
        "mcp.security",
        "MCP Security",
        "Validation and runtime protection for MCP.",
    ),
    (
        "mcp.security.rate_limit",
        "MCP Rate Limits",
        "Concurrency and throughput guardrails for MCP traffic.",
    ),
    (
        "mcp.security.validation",
        "MCP Validation",
        "Schema and payload checks for MCP requests.",
    ),
    (
        "mcp.server",
        "MCP Server Transport",
        "How VT Code hosts its own MCP server.",
    ),
    (
        "mcp.ui",
        "MCP UI",
        "How MCP tools and events appear in the interface.",
    ),
    (
        "mcp.ui.renderers",
        "MCP Renderers",
        "Presentation rules for specific MCP tool outputs.",
    ),
    (
        "model",
        "Model Defaults",
        "Shared model selection and context settings.",
    ),
    (
        "model_config",
        "Model Config",
        "Focused main-model and lightweight-model configuration.",
    ),
    (
        "model_config.main",
        "Main Model",
        "Provider and default model for the active conversation model.",
    ),
    (
        "model_config.lightweight",
        "Lightweight Model",
        "Shared lower-cost route for memory, prompt suggestions, and smaller delegated tasks.",
    ),
    (
        "optimization",
        "Performance",
        "Caching and runtime performance tuning.",
    ),
    (
        "optimization.agent_execution",
        "Agent Execution",
        "Concurrency and execution scheduling for agent turns.",
    ),
    (
        "optimization.async_pipeline",
        "Async Pipeline",
        "Background streaming and async pipeline tuning.",
    ),
    (
        "optimization.command_cache",
        "Command Cache",
        "Cache repeated shell command results.",
    ),
    (
        "optimization.file_read_cache",
        "File Read Cache",
        "Reuse hot file reads to reduce I/O churn.",
    ),
    (
        "optimization.llm_client",
        "LLM Client",
        "HTTP client behavior for model requests.",
    ),
    (
        "optimization.memory_pool",
        "Memory Pool",
        "Allocator and buffer reuse settings.",
    ),
    (
        "optimization.profiling",
        "Profiling",
        "Performance instrumentation and trace sampling.",
    ),
    (
        "optimization.tool_registry",
        "Tool Registry",
        "Startup and lookup behavior for tool metadata.",
    ),
    (
        "output_style",
        "Output Style",
        "Formatting and readability preferences.",
    ),
    (
        "permissions",
        "Permissions",
        "Default approval and trust behavior.",
    ),
    (
        "prompt_cache",
        "Prompt Cache",
        "Reuse prompts to cut duplicate provider work.",
    ),
    (
        "prompt_cache.providers",
        "Prompt Cache Providers",
        "Provider-specific prompt cache behavior.",
    ),
    (
        "provider",
        "Provider Endpoints",
        "Network and provider-specific API settings.",
    ),
    (
        "provider.anthropic",
        "Anthropic",
        "Anthropic-specific request settings.",
    ),
    (
        "provider.anthropic.tool_search",
        "Anthropic Tool Search",
        "Hosted search tool configuration for Anthropic models.",
    ),
    (
        "provider.openai",
        "OpenAI",
        "OpenAI-specific request settings.",
    ),
    (
        "provider.openai.tool_search",
        "OpenAI Tool Search",
        "Hosted search tool configuration for OpenAI Responses models.",
    ),
    (
        "pty",
        "Terminal Sessions",
        "PTY limits, buffering, and shell defaults.",
    ),
    (
        "sandbox",
        "Sandboxing",
        "Process isolation and filesystem boundaries.",
    ),
    (
        "sandbox.external",
        "External Sandbox",
        "Container or VM-backed isolation settings.",
    ),
    (
        "sandbox.external.docker",
        "Docker Sandbox",
        "Docker-based sandbox execution settings.",
    ),
    (
        "sandbox.external.microvm",
        "MicroVM Sandbox",
        "MicroVM-backed isolation settings.",
    ),
    (
        "sandbox.network",
        "Sandbox Network",
        "Outbound network restrictions inside the sandbox.",
    ),
    (
        "sandbox.resource_limits",
        "Resource Limits",
        "CPU, memory, and disk ceilings for sandbox runs.",
    ),
    (
        "sandbox.seccomp",
        "Seccomp Filters",
        "Linux syscall restrictions for sandboxed processes.",
    ),
    (
        "sandbox.sensitive_paths",
        "Sensitive Paths",
        "Protected host paths denied to sandboxed runs.",
    ),
    (
        "security",
        "Security Gate",
        "Approvals and blocking rules for risky actions.",
    ),
    (
        "security.gatekeeper",
        "Gatekeeper",
        "Extra approval checks and enforcement rules.",
    ),
    (
        "skills",
        "Skills",
        "Skill discovery, rendering, and loading behavior.",
    ),
    (
        "syntax_highlighting",
        "Syntax Highlighting",
        "Language-aware rendering in the transcript.",
    ),
    (
        "telemetry",
        "Telemetry",
        "Local analytics, metrics, and reporting.",
    ),
    ("timeouts", "Timeouts", "Global operation time limits."),
    (
        "tools",
        "Tool Defaults",
        "Loop limits and default tool behavior.",
    ),
    (
        "tools.editor",
        "External Editor",
        "Editor launch command and editor fallback.",
    ),
    (
        "tools.loop_thresholds",
        "Loop Thresholds",
        "Warn or stop when repeated tool loops are detected.",
    ),
    (
        "tools.plugins",
        "Tool Plugins",
        "Plugin loading and trust settings.",
    ),
    (
        "tools.policies",
        "Tool Policies",
        "Per-tool allow, prompt, or deny rules.",
    ),
    (
        "tools.web_fetch",
        "Web Fetch",
        "Remote fetch limits and safety checks.",
    ),
    (
        "ui",
        "Interface",
        "Appearance, layout, and transcript behavior.",
    ),
    (
        "ui.keyboard_protocol",
        "Keyboard Protocol",
        "Enhanced terminal keyboard reporting.",
    ),
    (
        "ui.notifications",
        "Notifications",
        "Desktop and in-app notification delivery.",
    ),
    (
        "ui.status_line",
        "Status Line",
        "Bottom status bar content and refresh behavior.",
    ),
];

pub(super) fn normalize_config_path(path: &str) -> String {
    ARRAY_INDEX_RE.replace_all(path, "[]").to_string()
}

pub(super) fn heading_for_path(path: &str) -> SectionHeading {
    let normalized_path = normalize_config_path(path);
    if let Some((_, title, summary)) = SECTION_HEADINGS
        .iter()
        .find(|(key, _, _)| *key == normalized_path)
    {
        return SectionHeading {
            title: Cow::Borrowed(title),
            summary: Cow::Borrowed(summary),
        };
    }

    if let Some(provider) = normalized_path.strip_prefix("prompt_cache.providers.") {
        return SectionHeading {
            title: Cow::Owned(format!("{} Prompt Cache", humanize_identifier(provider))),
            summary: Cow::Borrowed("Provider-specific prompt cache overrides."),
        };
    }

    if let Some(provider) = normalized_path.strip_prefix("mcp.allowlist.providers.") {
        return SectionHeading {
            title: Cow::Owned(format!("{} Allowlist", humanize_identifier(provider))),
            summary: Cow::Borrowed("MCP allowlist overrides for this provider."),
        };
    }

    let title = normalized_path
        .rsplit('.')
        .next()
        .map(humanize_identifier)
        .unwrap_or_else(|| "Settings".to_string());
    SectionHeading {
        title: Cow::Owned(title),
        summary: Cow::Borrowed(""),
    }
}

pub(super) fn humanize_identifier(value: &str) -> String {
    if value.is_empty() {
        return String::new();
    }

    let mut normalized = String::with_capacity(value.len() + 8);
    let mut previous_is_lower_or_digit = false;
    for ch in value.chars() {
        if matches!(ch, '_' | '-' | '.') {
            if !normalized.ends_with(' ') {
                normalized.push(' ');
            }
            previous_is_lower_or_digit = false;
            continue;
        }

        if ch.is_ascii_uppercase() && previous_is_lower_or_digit && !normalized.ends_with(' ') {
            normalized.push(' ');
        }

        previous_is_lower_or_digit = ch.is_ascii_lowercase() || ch.is_ascii_digit();
        normalized.push(ch);
    }

    normalized
        .split_whitespace()
        .map(format_human_token)
        .collect::<Vec<_>>()
        .join(" ")
}

fn format_human_token(token: &str) -> String {
    let lower = token.to_ascii_lowercase();
    match lower.as_str() {
        "acp" => "ACP".to_string(),
        "api" => "API".to_string(),
        "llm" => "LLM".to_string(),
        "mcp" => "MCP".to_string(),
        "oauth" => "OAuth".to_string(),
        "pty" => "PTY".to_string(),
        "ui" => "UI".to_string(),
        "vtcode" => "VT Code".to_string(),
        "openai" => "OpenAI".to_string(),
        "openrouter" => "OpenRouter".to_string(),
        "deepseek" => "DeepSeek".to_string(),
        "moonshot" => "Moonshot".to_string(),
        "zai" => "Z.AI".to_string(),
        _ => {
            let mut chars = lower.chars();
            match chars.next() {
                Some(first) => format!("{}{}", first.to_ascii_uppercase(), chars.as_str()),
                None => String::new(),
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn normalize_config_path_replaces_array_indexes() {
        assert_eq!(
            normalize_config_path("hooks.lifecycle.pre_tool_use[12].hooks[1]"),
            "hooks.lifecycle.pre_tool_use[].hooks[]"
        );
    }

    #[test]
    fn humanize_identifier_preserves_acronyms_and_camel_case() {
        assert_eq!(humanize_identifier("askQuestions"), "Ask Questions");
        assert_eq!(humanize_identifier("mcp_ui"), "MCP UI");
        assert_eq!(humanize_identifier("openai"), "OpenAI");
    }

    #[test]
    fn heading_for_path_builds_dynamic_provider_titles() {
        let heading = heading_for_path("prompt_cache.providers.openrouter");
        assert_eq!(heading.title, "OpenRouter Prompt Cache");
        assert_eq!(heading.summary, "Provider-specific prompt cache overrides.");
    }
}
