use std::sync::Arc;

use axum::routing::post;
use axum::{Extension, Router};

use crate::agent::ComplianceAgent;
use crate::error::AgentError;
use crate::webhooks::{gitea, github, gitlab};

pub async fn start_webhook_server(agent: &ComplianceAgent) -> Result<(), AgentError> {
    let app = Router::new()
        // Per-tenant per-repo webhook URLs: /webhook/{tenant_id}/{platform}/{repo_id}
        // The tenant_id is resolved from the URL path because webhooks
        // arrive without a JWT — they're authenticated via per-repo HMAC,
        // not via the tenant gate. The dashboard surfaces the full URL
        // including the tenant_id when the repo is registered.
        .route(
            "/webhook/{tenant_id}/github/{repo_id}",
            post(github::handle_github_webhook),
        )
        .route(
            "/webhook/{tenant_id}/gitlab/{repo_id}",
            post(gitlab::handle_gitlab_webhook),
        )
        .route(
            "/webhook/{tenant_id}/gitea/{repo_id}",
            post(gitea::handle_gitea_webhook),
        )
        .layer(Extension(Arc::new(agent.clone())));

    let addr = "0.0.0.0:3002";
    let listener = tokio::net::TcpListener::bind(addr)
        .await
        .map_err(|e| AgentError::Other(format!("Failed to bind webhook server: {e}")))?;

    tracing::info!("Webhook server listening on {addr}");
    axum::serve(listener, app)
        .await
        .map_err(|e| AgentError::Other(format!("Webhook server error: {e}")))?;

    Ok(())
}
