"""Private Core route for the generated app's own BFF to forward a Cloud-
verified webhook event into the external.entity_ingest pipeline.

Not public. The generated app has already checked Cloud's trusted-dispatch
secret (x-p2hs-webhook-secret) before ever calling this — this route only
trusts the generated app itself, via the same per-project function token
Forms submissions use (src/domain/forms/router.py).
"""
from __future__ import annotations

import hmac
from uuid import UUID

from fastapi import APIRouter, Depends, Request
from fastapi.responses import JSONResponse
from sqlalchemy.ext.asyncio import AsyncSession

from src.core.database import get_db
from src.core.security.encryption import decrypt_value
from src.domain.edge_functions.repository import ProjectFunctionTokenRepository
from src.domain.entity_ingest.service import EntityIngestError, EntityIngestService
from src.integrations.cloud_control_client import CloudControlClient

entity_ingest_router = APIRouter(
    prefix="/api/projects/{project_id}/entity-ingest",
    tags=["entity-ingest"],
)


def _bearer_token(request: Request) -> str:
    header = request.headers.get("authorization") or ""
    if header.lower().startswith("bearer "):
        return header[7:].strip()
    return ""


async def _project_service_token_ok(db: AsyncSession, project_id: UUID, token: str) -> bool:
    if not token:
        return False
    row = await ProjectFunctionTokenRepository(db).get(project_id)
    if row is None:
        return False
    try:
        expected = decrypt_value(row.token_enc)
    except Exception:
        return False
    if not expected or len(expected) != len(token):
        return False
    return hmac.compare_digest(expected, token)


_ERROR_STATUS = {
    "pack_not_installed": 404,
    "pack_not_found": 404,
    "binding_not_found": 404,
    "entity_not_found": 404,
    "invalid_payload": 400,
    "missing_provenance": 400,
    "missing_identity": 400,
}


@entity_ingest_router.post("/{pack_slug}/{provider}")
async def ingest_entity_event(
    request: Request,
    project_id: UUID,
    pack_slug: str,
    provider: str,
    db: AsyncSession = Depends(get_db),
) -> JSONResponse:
    token = _bearer_token(request)
    if not await _project_service_token_ok(db, project_id, token):
        return JSONResponse(status_code=401, content={"ok": False, "error": "unauthorized"})

    try:
        envelope = await request.json()
    except Exception:
        return JSONResponse(status_code=400, content={"ok": False, "error": "invalid_request"})
    if not isinstance(envelope, dict):
        return JSONResponse(status_code=400, content={"ok": False, "error": "invalid_request"})

    service = EntityIngestService(db, CloudControlClient())
    try:
        result = await service.ingest(
            project_id=project_id, pack_slug=pack_slug, provider=provider, envelope=envelope
        )
    except EntityIngestError as exc:
        return JSONResponse(
            status_code=_ERROR_STATUS.get(exc.code, 400),
            content={"ok": False, "error": exc.code, "message": str(exc)},
        )
    return JSONResponse(status_code=200, content=result)
