from __future__ import annotations

from enum import Enum
from typing import Any, Literal

from pydantic import BaseModel, ConfigDict, Field

from app.modules.agent.engine.orchestrator.models.plan import ArtifactType
from app.schemas.changeset import ChangeItem


class StepStatus(str, Enum):
    SUCCESS = "success"
    FAILED = "failed"
    SKIPPED = "skipped"
    RETRY_EXHAUSTED = "retry_exhausted"


class EvidenceItem(BaseModel):
    model_config = ConfigDict(extra="forbid")

    evidence_id: str
    source_type: Literal["rag_chunk", "project_file", "external_doc", "confluence"]
    source_ref: str
    snippet: str
    score: float = Field(ge=0.0, le=1.0)


class ArtifactItem(BaseModel):
    model_config = ConfigDict(extra="forbid")

    artifact_id: str
    key: str
    type: ArtifactType
    content: str | None = None
    path: str | None = None
    content_hash: str | None = None
    meta: dict[str, Any] = Field(default_factory=dict)


class StepResult(BaseModel):
    model_config = ConfigDict(extra="forbid")

    step_id: str
    status: StepStatus
    produced_artifact_ids: list[str] = Field(default_factory=list)
    evidence_ids: list[str] = Field(default_factory=list)
    warnings: list[str] = Field(default_factory=list)
    error_code: str | None = None
    error_message: str | None = None
    duration_ms: int = 0
    token_usage: int | None = None
    replan_hint: str | None = None


class OrchestratorResult(BaseModel):
    model_config = ConfigDict(extra="forbid")

    answer: str | None = None
    changeset: list[ChangeItem] = Field(default_factory=list)
    meta: dict[str, Any] = Field(default_factory=dict)
    steps: list[StepResult] = Field(default_factory=list)
