"""Revisions domain - FastAPI router."""
from __future__ import annotations
from typing import Optional
from uuid import UUID

from fastapi import APIRouter, Depends, Path, Query
from sqlalchemy.ext.asyncio import AsyncSession

from src.core.database import get_db
from src.core.dependencies import require_active_billing_for_project
from src.domain.auth.models import User
from src.domain.auth.router import get_current_user
from src.domain.revisions.repository import RevisionRepository, RevisionTagRepository
from src.domain.revisions.schemas import RevisionResponse, TagCreate, TagResponse
from src.domain.revisions.service import RevisionService
from src.domain.projects.repository import ProjectRepository

router = APIRouter(prefix="/api/projects/{project}", tags=["revisions"])


class _ProjectFacadeForRevisions:
    """Inline facade - wired at composition root."""

    def __init__(self, db: AsyncSession):
        self._project_repo = ProjectRepository(db)

    async def get_project_workspace_id(self, project_id: UUID) -> Optional[UUID]:
        p = await self._project_repo.get_by_id(project_id)
        return p.workspace_id if p else None

    async def get_project_repo_full_name(self, project_id: UUID) -> Optional[str]:
        p = await self._project_repo.get_with_repo(project_id)
        return p.repo.repo_full_name if p and p.repo else None


async def get_revision_service(db: AsyncSession = Depends(get_db)) -> RevisionService:
    return RevisionService(
        revision_repo=RevisionRepository(db),
        tag_repo=RevisionTagRepository(db),
        project_facade=_ProjectFacadeForRevisions(db),
    )


@router.get("/revisions", response_model=list[RevisionResponse])
async def list_revisions(
    project: UUID = Depends(require_active_billing_for_project),
    user: User = Depends(get_current_user),
    service: RevisionService = Depends(get_revision_service),
):
    revisions = await service.list_revisions(project)
    return [RevisionResponse.model_validate(r) for r in revisions]


@router.post("/revisions/{revision}/restore", response_model=RevisionResponse)
async def restore_revision(
    project: UUID = Depends(require_active_billing_for_project),
    revision: UUID = Path(...),
    user: User = Depends(get_current_user),
    service: RevisionService = Depends(get_revision_service),
):
    rev = await service.restore_revision(project, revision, user.id)
    return RevisionResponse.model_validate(rev)


@router.post("/revisions/{revision}/tag", response_model=TagResponse)
async def tag_revision(
    body: TagCreate,
    project: UUID = Depends(require_active_billing_for_project),
    revision: UUID = Path(...),
    user: User = Depends(get_current_user),
    service: RevisionService = Depends(get_revision_service),
):
    t = await service.tag_revision(revision, body.tag, user.id)
    return TagResponse(id=t.id, revision_id=t.revision_id, tag=t.tag, created_at=t.created_at)


@router.get("/revisions/{revision}/diff")
async def get_diff(
    project: UUID = Depends(require_active_billing_for_project),
    revision: UUID = Path(...),
    to: UUID = Query(...),
    user: User = Depends(get_current_user),
    service: RevisionService = Depends(get_revision_service),
):
    return await service.get_diff(project, revision, to)
