"""Protocol types for the MCP server."""

from enum import Enum
from typing import Any

from pydantic import BaseModel, ConfigDict, Field


class OperationType(str, Enum):
    """Types of operations the MCP server supports."""

    ANALYZE_COMPONENT = "analyze_component"
    ANALYZE_PROJECT = "analyze_project"
    GENERATE_DOCS = "generate_docs"
    SEARCH_COMPONENTS = "search_components"
    SEARCH_FUNCTIONS = "search_functions"
    FIND_PATTERNS = "find_patterns"
    EXTRACT_APIS = "extract_apis"


class ExtractionInstructions(BaseModel):
    """Guides the client LLM on how to extract data."""

    model_config = ConfigDict(populate_by_name=True)

    overview: str
    steps: list[str]
    field_guidance: dict[str, str] = Field(default_factory=dict, alias="fieldGuidance")
    privacy_notes: list[str] = Field(default_factory=list, alias="privacyNotes")


class SchemaResponse(BaseModel):
    """Contains the extraction schema and instructions (Phase 1 response)."""

    model_config = ConfigDict(populate_by_name=True)

    schema_id: str = Field(alias="schemaId")
    schema_: dict[str, Any] = Field(alias="schema")
    instructions: ExtractionInstructions
    required_files: list[str] | None = Field(default=None, alias="requiredFiles")


class ProcessingResponse(BaseModel):
    """Contains the analysis results (Phase 2 response)."""

    model_config = ConfigDict(populate_by_name=True)

    success: bool
    result: Any
    suggestions: list[str] | None = None
    follow_up_queries: list[str] | None = Field(default=None, alias="followUpQueries")


class AnalysisResult(BaseModel):
    """Component or project analysis results."""

    type: str = "analysis"
    summary: str
    details: dict[str, Any]
    metrics: dict[str, float] | None = None


class DocumentationResult(BaseModel):
    """Generated documentation."""

    type: str = "documentation"
    content: str
    format: str = "markdown"


class MatchContext(BaseModel):
    """Additional context for a search match."""

    signature: str | None = None
    description: str | None = None


class SearchMatch(BaseModel):
    """A single search result."""

    model_config = ConfigDict(populate_by_name=True)

    name: str
    file_path: str = Field(alias="filePath")
    match_type: str = Field(alias="matchType")  # "component", "function", "hook", "pattern"
    context: MatchContext | None = None


class SearchResult(BaseModel):
    """Search operation results."""

    model_config = ConfigDict(populate_by_name=True)

    type: str = "search"
    matches: list[SearchMatch]
    total_count: int = Field(alias="totalCount")
