"""Authenticated platform-admin readback for Forms submissions."""
from __future__ import annotations

from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, ConfigDict
from sqlalchemy.ext.asyncio import AsyncSession

from src.core.database import get_db
from src.core.exceptions import ForbiddenError, NotFoundError
from src.domain.auth.models import User
from src.domain.auth.router import get_current_user
from src.domain.forms.repository import FormSubmissionRepository
from src.domain.forms.persistence import FormPersistenceContext
from src.domain.projects.repository import ProjectRepository
from src.domain.workspaces.repository import MembershipRepository

router = APIRouter(prefix="/api/admin/projects/{project_id}/forms", tags=["admin-forms"])


async def require_forms_project_admin(
    project_id: UUID,
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> User:
    """Require workspace-admin authority for this exact project."""
    project = await ProjectRepository(db).get_by_id(project_id)
    if project is None:
        raise NotFoundError("Project not found")
    if not await MembershipRepository(db).has_permission(
        project.workspace_id, user.id, "workspaces.manage"
    ):
        raise ForbiddenError("Project forms admin access required")
    return user


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

    submission_id: str
    project_id: UUID
    form_key: str
    values: dict
    accepted_at: str
    persisted_at: str
    status: str


class FormSubmissionListResponse(BaseModel):
    items: list[FormSubmissionRead]
    total: int
    limit: int
    offset: int


def _read(row) -> FormSubmissionRead:
    return FormSubmissionRead(
        submission_id=row.submission_id,
        project_id=UUID(row.project_id),
        form_key=row.accepted.submission.form_key,
        values=row.accepted.submission.values,
        accepted_at=row.accepted.accepted_at.isoformat(),
        persisted_at=row.persisted_at.isoformat(),
        status=row.status,
    )


@router.get("/submissions", response_model=FormSubmissionListResponse)
async def list_form_submissions(
    project_id: UUID,
    form_key: str | None = Query(default=None, min_length=1, max_length=64),
    status: str | None = Query(default=None, min_length=1, max_length=32),
    limit: int = Query(default=50, ge=1, le=200),
    offset: int = Query(default=0, ge=0),
    _admin: User = Depends(require_forms_project_admin),
    db: AsyncSession = Depends(get_db),
) -> FormSubmissionListResponse:
    rows, total = await FormSubmissionRepository(db).list(
        project_id, form_key=form_key, status=status, limit=limit, offset=offset
    )
    return FormSubmissionListResponse(
        items=[_read(row) for row in rows], total=total, limit=limit, offset=offset
    )


@router.get("/submissions/{submission_id}", response_model=FormSubmissionRead)
async def get_form_submission(
    project_id: UUID,
    submission_id: str,
    _admin: User = Depends(require_forms_project_admin),
    db: AsyncSession = Depends(get_db),
) -> FormSubmissionRead:
    row = await FormSubmissionRepository(db).get(
        FormPersistenceContext(project_id=str(project_id)), submission_id
    )
    if row is None:
        raise HTTPException(status_code=404, detail="Form submission not found")
    return _read(row)
