"""POST /governance/complete/ — GSAP §5.4"""
import uuid
from datetime import datetime, UTC
from fastapi import APIRouter, Depends, HTTPException
from sqlmodel.ext.asyncio.session import AsyncSession
from sqlalchemy import text
from gsap_broker.db import get_session
from gsap_broker.models import CompleteRequest, CompleteResponse
from gsap_broker import chronicle

router = APIRouter()

@router.post("/complete/", response_model=CompleteResponse, summary="Receive CR (GSAP §5.4)")
async def complete(request: CompleteRequest, db: AsyncSession = Depends(get_session)):
    # Pure raw SQL to avoid all SQLModel/SQLAlchemy greenlet issues
    ctx_id_str = str(request.context_id).replace("-", "")
    result = await db.execute(
        text("SELECT context_id, status, session_mode FROM authorization_contexts WHERE context_id = :ctx_id AND status IN ('authorized', 'active')"),
        {"ctx_id": ctx_id_str},
    )
    ac_row = result.first()
    if not ac_row:
        raise HTTPException(status_code=404, detail="AC not found or already consumed.")

    ac_status = ac_row[1]
    is_session = bool(ac_row[2]) if len(ac_row) > 2 else False

    sig_verified = bool((request.signature or {}).get("value"))
    cr_id = uuid.uuid4()
    now = datetime.now(UTC)

    # Insert CR
    await db.execute(
        text("""INSERT INTO completion_receipts
            (id, context_id, outcome, completed_at, received_at, failure_reason,
             chronicle_session_id, chronicle_events, merkle_root,
             behavioral_attestation_status, ffc_did, ffc_signature,
             signature_verified, chronicle_event_cid)
            VALUES (:id, :ctx_id, :outcome, :completed_at, :received_at, :failure_reason,
             :session_id, :events, :merkle_root,
             :ba_status, :ffc_did, :ffc_sig,
             :sig_verified, '')"""),
        {
            "id": str(cr_id).replace("-", ""), "ctx_id": ctx_id_str,
            "outcome": request.outcome.value,
            "completed_at": str(request.completed_at),
            "received_at": str(now),
            "failure_reason": request.failure_reason or "",
            "session_id": request.chronicle_session_id or "",
            "events": str(request.chronicle_evidence.events),
            "merkle_root": request.chronicle_evidence.merkle_root or "",
            "ba_status": request.behavioral_attestation.status.value,
            "ffc_did": request.ffc.get("did", ""),
            "ffc_sig": (request.signature or {}).get("value", ""),
            "sig_verified": sig_verified,
        },
    )

    # Update AC status based on session mode:
    # - Session mode + non-final outcome → 'active' (stays open for more CRs)
    # - Session mode + session_end outcome → 'consumed' (session finished)
    # - Non-session mode → 'consumed' (single-use, original behavior)
    is_final = request.outcome.value == "session_end" or not is_session
    new_status = "consumed" if is_final else "active"

    await db.execute(
        text("UPDATE authorization_contexts SET status = :status, consumed_at = :now WHERE context_id = :ctx_id"),
        {"status": new_status, "now": str(now) if is_final else None, "ctx_id": ctx_id_str},
    )

    # Chronicle event
    cid = await chronicle.emit("GSAP_CR_RECEIVED", {
        "event_code": "0x2706",
        "context_id": str(request.context_id).replace("-", ""),
        "outcome": request.outcome.value,
    })

    # Update CR with chronicle CID
    if cid:
        await db.execute(
            text("UPDATE completion_receipts SET chronicle_event_cid = :cid WHERE id = :id"),
            {"cid": cid, "id": str(cr_id).replace("-", "")},
        )

    await db.commit()

    return CompleteResponse(receipt_id=cr_id, signature_verified=sig_verified, chronicle_event_cid=cid or None)
