"""Optimization suggestions for bloated MCP tools."""

from __future__ import annotations

from dataclasses import dataclass

from rich.console import Console
from rich.panel import Panel

from mcp_diet.analyzer import AnalysisSummary, ToolAnalysis


@dataclass
class Suggestion:
    tool_name: str
    category: str
    message: str
    potential_savings: str | None = None


def _check_description_length(tool: ToolAnalysis) -> list[Suggestion]:
    suggestions = []
    if tool.desc_length > 500:
        suggestions.append(Suggestion(
            tool_name=tool.name,
            category="Long description",
            message=f"Description is {tool.desc_length} chars. Consider trimming to under 500 chars — "
                    f"LLMs don't need verbose instructions to understand tool purpose.",
            potential_savings=f"~{(tool.desc_length - 300) // 4} tokens",
        ))
    return suggestions


def _check_schema_depth(tool: ToolAnalysis) -> list[Suggestion]:
    suggestions = []
    if tool.schema_depth > 3:
        suggestions.append(Suggestion(
            tool_name=tool.name,
            category="Deep schema nesting",
            message=f"Schema depth is {tool.schema_depth}. Flatten nested objects where possible — "
                    f"deeply nested schemas consume extra tokens and confuse models.",
        ))
    return suggestions


def _check_optional_params(tool: ToolAnalysis) -> list[Suggestion]:
    suggestions = []
    schema = tool.input_schema
    if not schema or not isinstance(schema, dict):
        return suggestions

    properties = schema.get("properties", {})
    required = set(schema.get("required", []))
    optional = [k for k in properties if k not in required]

    if len(optional) > 5:
        suggestions.append(Suggestion(
            tool_name=tool.name,
            category="Too many optional parameters",
            message=f"Has {len(optional)} optional parameters: {', '.join(optional[:8])}{'...' if len(optional) > 8 else ''}. "
                    f"Consider removing rarely-used ones to reduce schema size.",
            potential_savings=f"~{len(optional) * 20} tokens",
        ))
    return suggestions


def _find_duplicates(tools: list[ToolAnalysis]) -> list[Suggestion]:
    suggestions = []
    names = [t.name for t in tools]
    # Simple heuristic: look for tools with similar prefixes
    prefix_groups: dict[str, list[str]] = {}
    for name in names:
        parts = name.replace("-", "_").split("_")
        if len(parts) > 1:
            prefix = parts[0]
            prefix_groups.setdefault(prefix, []).append(name)

    for prefix, group in prefix_groups.items():
        if len(group) > 4:
            suggestions.append(Suggestion(
                tool_name=f"{prefix}_*",
                category="Potential overlap",
                message=f"{len(group)} tools share the prefix '{prefix}_': {', '.join(group[:6])}{'...' if len(group) > 6 else ''}. "
                        f"Consider consolidating related operations into fewer tools with a mode/action parameter.",
            ))
    return suggestions


def generate_suggestions(summary: AnalysisSummary) -> list[Suggestion]:
    """Generate optimization suggestions for tools graded C or worse."""
    suggestions = []

    # Per-tool suggestions (only for C, D, F grades)
    for tool in summary.tools:
        if tool.grade in ("C", "D", "F"):
            suggestions.extend(_check_description_length(tool))
            suggestions.extend(_check_schema_depth(tool))
            suggestions.extend(_check_optional_params(tool))

    # Cross-tool suggestions
    suggestions.extend(_find_duplicates(summary.tools))

    return suggestions


def print_suggestions(suggestions: list[Suggestion]) -> None:
    """Print suggestions using rich formatting."""
    console = Console()

    if not suggestions:
        console.print("[green]No optimization suggestions — all tools look efficient![/green]")
        return

    console.print(f"\n[bold]Optimization Suggestions ({len(suggestions)}):[/bold]\n")

    for s in suggestions:
        savings = f" | Potential savings: {s.potential_savings}" if s.potential_savings else ""
        console.print(Panel(
            f"{s.message}{savings}",
            title=f"[cyan]{s.tool_name}[/cyan] — {s.category}",
            border_style="yellow",
        ))
