"""GitHub Webhooks - FastAPI router.

Single endpoint that receives all GitHub App webhook deliveries,
verifies the signature, and dispatches to the correct handler.
"""
from __future__ import annotations
import structlog
from typing import Optional
from fastapi import APIRouter, Header, Request
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi import Depends

from src.config import get_settings
from src.core.database import get_db
from src.core.exceptions import ForbiddenError
from src.domain.github_webhooks.handlers import EVENT_HANDLERS
from src.domain.github_webhooks.verification import verify_github_signature

logger = structlog.get_logger()
router = APIRouter(prefix="/api/webhooks", tags=["webhooks"])


@router.post("/github")
async def github_webhook(
    request: Request,
    db: AsyncSession = Depends(get_db),
    x_hub_signature_256: Optional[str] = Header(None),
    x_github_event: Optional[str] = Header(None),
    x_github_delivery: Optional[str] = Header(None),
):
    body = await request.body()

    if not verify_github_signature(body, x_hub_signature_256):
        secret_configured = bool((get_settings().github_webhook_secret or "").strip())
        if not x_hub_signature_256:
            reason = "missing_x_hub_signature_256"
        elif not secret_configured:
            reason = "github_webhook_secret_not_set"
        else:
            reason = "signature_mismatch_or_wrong_secret"
        logger.warning(
            "github_webhook_signature_rejected",
            reason=reason,
            hint="Set GITHUB_WEBHOOK_SECRET to the GitHub App webhook secret; ensure proxies forward X-Hub-Signature-256 and the raw body.",
        )
        raise ForbiddenError("Invalid webhook signature")

    import json
    payload = json.loads(body)

    event_type = x_github_event or ""
    delivery_id = x_github_delivery or ""

    logger.info(
        "github_webhook_received",
        github_event=event_type,
        github_delivery=delivery_id,
    )

    handler = EVENT_HANDLERS.get(event_type)
    if handler:
        result = await handler(db, payload)
        return {"event": event_type, "delivery": delivery_id, **result}

    logger.info("github_webhook_unhandled_event", github_event=event_type)
    return {"event": event_type, "delivery": delivery_id, "action": "ignored"}
