from __future__ import annotations

from typing import Any

from app.core.database import get_repo_sync_db
from app.models.repos import RepoEntry, RepoStages


class RepoRepository:
    """Read-only access to repositories and indexing_runs in adpilot_repo_sync."""

    async def list_repos(self) -> list[RepoEntry]:
        db = get_repo_sync_db()
        repos: list[RepoEntry] = []

        cursor = db.repositories.find({})
        async for doc in cursor:
            repo_id = doc.get("repo_id") or doc.get("_id")
            if not repo_id:
                continue
            repo_id = str(repo_id)

            queryable_run = await db.indexing_runs.find_one(
                {
                    "repo_id": repo_id,
                    "stages.graph_finalize": "completed",
                    "$or": [
                        {"expected_code_files": {"$gt": 0}},
                        {"processed_code_files": {"$gt": 0}},
                    ],
                },
                sort=[("created_at", -1)],
            )
            latest_run = queryable_run or await db.indexing_runs.find_one(
                {"repo_id": repo_id},
                sort=[("created_at", -1)],
            )

            stages = RepoStages()
            indexing_status = None
            latest_snapshot_id = None

            if latest_run:
                latest_snapshot_id = latest_run.get("snapshot_id")
                indexing_status = latest_run.get("status")
                run_stages = latest_run.get("stages") or {}
                if isinstance(run_stages, dict):
                    stages = RepoStages(embedding=run_stages.get("embedding"))

            repos.append(
                RepoEntry(
                    repo_id=repo_id,
                    clone_url=doc.get("clone_url"),
                    last_sync_at=_format_datetime(doc.get("last_sync_at")),
                    latest_snapshot_id=latest_snapshot_id,
                    indexing_status=indexing_status,
                    stages=stages,
                )
            )

        return repos


def _format_datetime(value: Any) -> str | None:
    if value is None:
        return None
    if hasattr(value, "isoformat"):
        return value.isoformat()
    return str(value)
