"""Webhook configuration CRUD router — admin only.

Endpoints
---------
GET    /webhooks              — list all webhook configs
POST   /webhooks              — create a new webhook config
GET    /webhooks/{id}         — get a single webhook config
PATCH  /webhooks/{id}         — update a webhook config
DELETE /webhooks/{id}         — hard-delete a webhook config
POST   /webhooks/{id}/test    — send a test ping
"""

import uuid

from fastapi import APIRouter, Depends, status
from sqlalchemy.orm import Session

from app.database import get_db
from app.dependencies.auth import require_any_role
from app.domain.unit_of_work import UnitOfWork
from app.models.user import User
from app.schemas.webhook import WebhookConfigCreate, WebhookConfigOut, WebhookConfigUpdate
from app.services.webhook_service import (
    create_webhook,
    delete_webhook,
    dispatch_webhook,
    get_webhook_or_raise,
    list_webhooks,
    update_webhook,
)

router = APIRouter(prefix="/webhooks", tags=["webhooks"])


def _mask_secret(wh) -> WebhookConfigOut:
    """Return a WebhookConfigOut with the secret masked."""
    out = WebhookConfigOut.model_validate(wh)
    if wh.secret:
        out.secret = "***"  # nosec B105
    else:
        out.secret = None
    return out


# ---------------------------------------------------------------------------
# GET /webhooks
# ---------------------------------------------------------------------------


@router.get("", response_model=list[WebhookConfigOut])
def list_webhooks_route(
    offset: int = 0,
    limit: int = 50,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_any_role("admin")),
):
    """Return all webhook configurations. **Requires admin role.**"""
    webhooks = list_webhooks(db, offset=offset, limit=limit)
    return [_mask_secret(wh) for wh in webhooks]


# ---------------------------------------------------------------------------
# POST /webhooks
# ---------------------------------------------------------------------------


@router.post("", response_model=WebhookConfigOut, status_code=status.HTTP_201_CREATED)
def create_webhook_route(
    payload: WebhookConfigCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_any_role("admin")),
):
    """Create a new webhook configuration. **Requires admin role.**"""
    with UnitOfWork(db) as uow:
        wh = create_webhook(db, created_by=current_user.id, payload=payload)
        uow.commit()
    db.refresh(wh)
    return _mask_secret(wh)


# ---------------------------------------------------------------------------
# GET /webhooks/{id}
# ---------------------------------------------------------------------------


@router.get("/{webhook_id}", response_model=WebhookConfigOut)
def get_webhook_route(
    webhook_id: uuid.UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_any_role("admin")),
):
    """Return a single webhook configuration. **Requires admin role.**"""
    wh = get_webhook_or_raise(db, webhook_id)
    return _mask_secret(wh)


# ---------------------------------------------------------------------------
# PATCH /webhooks/{id}
# ---------------------------------------------------------------------------


@router.patch("/{webhook_id}", response_model=WebhookConfigOut)
def update_webhook_route(
    webhook_id: uuid.UUID,
    payload: WebhookConfigUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_any_role("admin")),
):
    """Update one or more fields of a webhook configuration. **Requires admin role.**"""
    with UnitOfWork(db) as uow:
        wh = update_webhook(db, webhook_id, payload)
        uow.commit()
    db.refresh(wh)
    return _mask_secret(wh)


# ---------------------------------------------------------------------------
# DELETE /webhooks/{id}
# ---------------------------------------------------------------------------


@router.delete("/{webhook_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_webhook_route(
    webhook_id: uuid.UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_any_role("admin")),
):
    """Hard-delete a webhook configuration. **Requires admin role.**"""
    with UnitOfWork(db) as uow:
        delete_webhook(db, webhook_id)
        uow.commit()


# ---------------------------------------------------------------------------
# POST /webhooks/{id}/test
# ---------------------------------------------------------------------------


@router.post("/{webhook_id}/test", status_code=status.HTTP_202_ACCEPTED)
def test_webhook_route(
    webhook_id: uuid.UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(require_any_role("admin")),
):
    """Send a test ping to the webhook endpoint. **Requires admin role.**"""
    # Verify the webhook exists before dispatching
    get_webhook_or_raise(db, webhook_id)
    dispatch_webhook("webhook.test", {"webhook_id": str(webhook_id), "message": "Test ping from Aegis"})
    return {"detail": "Test ping dispatched"}
