# fitz_ai/ingestion/enrichment/config.py
"""
Configuration schema for the enrichment pipeline.

All retrieval intelligence is BAKED IN - always on, no opt-in needed.

Enrichment automatically provides:
1. Chunk-level: summary, keywords, entities (via unified enrichment bus)
2. Hierarchy-level: L1 group summaries, L2 corpus summary
3. Project-level: artifacts (auto-detected plugins)

The enrichment bus batches chunks efficiently (~15 per LLM call), making
the cost negligible even for large codebases.

Config structure in .fitz/config.yaml:
    enrichment:
      hierarchy:
        group_by: source_file  # How to group chunks for L1 summaries
      artifacts:
        auto: true
"""

from __future__ import annotations

from pydantic import BaseModel, Field


class ArtifactConfig(BaseModel):
    """
    Configuration for project-level artifacts.

    Artifacts are high-level project summaries generated by plugins.
    Each plugin declares which content types it supports. Plugins are
    auto-discovered from the artifacts/plugins/ directory.

    Attributes:
        auto: Auto-discover and run all applicable plugins
        enabled: Explicit list of plugins to run (overrides auto)
        disabled: Plugins to skip even if applicable
    """

    auto: bool = True
    enabled: list[str] = Field(default_factory=list)
    disabled: list[str] = Field(default_factory=list)


class HierarchyRule(BaseModel):
    """
    A single hierarchy rule for grouping and summarizing chunks.

    Users configure rules to enable multi-level summarization of content.
    Chunks matching the path patterns are grouped by a metadata key, and
    LLM summaries are generated at group and corpus levels.

    Attributes:
        name: Unique identifier for this rule (e.g., "video_comments")
        paths: Glob patterns to filter files (e.g., ["comments/**", "*.txt"])
        group_by: Metadata key to group chunks by (e.g., "video_id")
        prompt: LLM prompt for generating group-level summaries
        corpus_prompt: Optional prompt for corpus-level summary
    """

    name: str
    paths: list[str]
    group_by: str
    prompt: str
    corpus_prompt: str | None = None


class HierarchyConfig(BaseModel):
    """
    Configuration for hierarchical enrichment.

    Hierarchical enrichment generates multi-level summaries:
    - Level 0: Original chunks (unchanged)
    - Level 1: Group summaries (chunks grouped by metadata key or semantic similarity)
    - Level 2: Corpus summary (summary of all groups)

    Zero-config mode (recommended):
        Just set enabled=True or use `fitz ingest --hierarchy`.
        Uses smart defaults: group_by="source", default prompts.

    Semantic grouping mode:
        Set grouping_strategy="semantic" to cluster chunks by embedding similarity.
        Requires embedder to be provided.

    Power-user mode:
        Configure custom rules for complex grouping scenarios.

    Attributes:
        grouping_strategy: "metadata" (default) or "semantic" for embedding-based clustering
        group_by: Metadata key for grouping (used when strategy is "metadata")
        n_clusters: Number of clusters for semantic grouping (None = auto-detect)
        max_clusters: Maximum clusters for auto-detection
        group_prompt: Custom prompt for group summaries (optional)
        corpus_prompt: Custom prompt for corpus summary (optional)
        rules: Advanced rules for power users (optional, overrides simple mode)
    """

    # No enabled field - hierarchy is always on
    grouping_strategy: str = "metadata"  # "metadata" or "semantic"
    group_by: str = "source_file"  # Default: each file is a group (metadata mode)
    n_clusters: int | None = None  # For semantic grouping (None = auto-detect)
    max_clusters: int = 10  # Upper bound for auto-detection
    group_prompt: str | None = None  # Uses DEFAULT_GROUP_PROMPT if None
    corpus_prompt: str | None = None  # Uses DEFAULT_CORPUS_PROMPT if None
    rules: list[HierarchyRule] = Field(default_factory=list)  # Power user

    # Minimum thresholds to skip LLM calls for trivial groups
    min_group_chunks: int = 2  # Skip L1 summary if group has fewer chunks
    min_group_content: int = 1000  # Skip L1 summary if total content below this (chars)


class EnrichmentConfig(BaseModel):
    """
    Configuration for the enrichment pipeline.

    Enrichment is always on - baked into the ingestion pipeline.
    Extracts keywords, entities, and generates hierarchical summaries.

    Attributes:
        artifacts: Project-level artifact configuration
        hierarchy: Hierarchical summarization configuration
        min_batch_content: Minimum content chars to trigger chunk enrichment LLM call

    Example in .fitz/config.yaml:
        enrichment:
          artifacts:
            auto: true
            disabled:
              - architecture_narrative
          hierarchy:
            group_by: source_file
            rules:
              - name: video_comments
                paths: ["comments/**"]
                group_by: video_id
                prompt: "Summarize sentiment and themes"
    """

    artifacts: ArtifactConfig = Field(default_factory=ArtifactConfig)
    hierarchy: HierarchyConfig = Field(default_factory=HierarchyConfig)

    # Minimum thresholds to skip LLM calls for trivial batches
    min_batch_content: int = 500  # Skip chunk enrichment if batch content below this (chars)


__all__ = [
    "EnrichmentConfig",
    "ArtifactConfig",
    "HierarchyConfig",
    "HierarchyRule",
]
