from __future__ import annotations

from typing import Any

from pydantic import BaseModel, Field, field_validator


class CommitAnalysisDocument(BaseModel):
    """Upstream `commit_analyses` document (Commit Intelligence)."""

    analysis_id: str
    repo_id: str
    commit_sha: str
    summary: str
    base_commit_sha: str | None = None
    snapshot_id: str | None = None
    impacted_symbols: list[str] = Field(default_factory=list)
    changed_files: list[str] = Field(default_factory=list)
    related_doc_chunks: list[str] = Field(default_factory=list)
    author_name: str | None = None
    author_email: str | None = None
    committer_name: str | None = None
    committer_email: str | None = None
    authored_at: str | None = None
    committed_at: str | None = None
    commit_message: str | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)

    @field_validator("impacted_symbols", "changed_files", "related_doc_chunks", mode="before")
    @classmethod
    def _default_lists(cls, value: list[str] | None) -> list[str]:
        return value or []

    @field_validator("metadata", mode="before")
    @classmethod
    def _default_metadata(cls, value: Any) -> dict[str, Any]:
        return value or {}

    @classmethod
    def from_mongo(cls, doc: dict[str, Any]) -> CommitAnalysisDocument:
        payload = dict(doc)
        if "_id" in payload and "analysis_id" not in payload:
            payload["analysis_id"] = str(payload.pop("_id"))
        elif "_id" in payload:
            payload.pop("_id", None)
        return cls.model_validate(payload)

    def resolved_snapshot_id(self) -> str | None:
        if self.snapshot_id:
            return self.snapshot_id
        meta = self.metadata.get("snapshot_id")
        return str(meta).strip() if meta else None
