from pathlib import Path
from typing import Any, Callable

from pydantic import BaseModel, Field


class Agent(BaseModel):
    name: str
    role: str
    scope: str
    dependencies: list[str] = Field(default_factory=list)
    output_format: str | None = None
    constraints: str | None = None
    raw_markdown: str = ""


class Principle(BaseModel):
    title: str
    content: str
    priority: str = "medium"
    category: str = ""
    subsections: list[str] = Field(default_factory=list)


class Hook(BaseModel):
    name: str
    file_path: Path
    content: str
    language: str  # 'python' or 'shell'


class Command(BaseModel):
    name: str
    file_path: Path
    content: str
    description: str = ""


class Section(BaseModel):
    """Represents a document section with metadata from numbered files."""

    filename: str
    order: int
    title: str
    content: str
    section_type: str = "content"  # content|directory|special
    template_var: str | None = None
    required: bool = True
    order_override: int | None = None


class ClaudeDocument(BaseModel):
    version: str = "v9.4.2"
    subtitle: str = "Self-Learning & Resilient Workflow"

    # Dynamic sections from numbered files
    sections: list[Section] = Field(default_factory=list)

    # Legacy fields for backward compatibility
    core_mission: str = ""
    principles: list[Principle] = Field(default_factory=list)
    agents: list[Agent] = Field(default_factory=list)
    agents_markdown: str = ""
    communication_patterns: dict[str, str] = Field(default_factory=dict)
    validation_system: dict[str, str] = Field(default_factory=dict)
    directory_management: str = ""
    workflow_execution: str = ""
    key_artifacts: str = ""
    token_optimization_rules: str = ""

    # Additional components
    hooks: list[Hook] = Field(default_factory=list)
    commands: list[Command] = Field(default_factory=list)
    settings: dict[str, Any] = Field(default_factory=dict)


class BuildTarget(BaseModel):
    """Configuration for a build target."""

    name: str
    output_path: Path
    template_name: str
    data_builder: str  # Method name on ClaudeBuilder
    post_process: Callable[[str], str] | None = None

    class Config:
        arbitrary_types_allowed = True


class BuildConfig(BaseModel):
    """Configuration for building multiple targets."""

    targets: list[BuildTarget]
    output_base_dir: Path = Path("output")
