"""integrations domain — HTTP routes.

Two surfaces:
1. /api/integrations/providers           — static catalog (any authenticated user)
2. /api/projects/{id}/integrations       — per-project integration management
"""
from __future__ import annotations

from uuid import UUID

from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession

from src.core.database import get_db
from src.core.dependencies import require_active_billing_for_project_id
from src.domain.auth.models import User
from src.domain.auth.router import get_current_user
from src.domain.connectors.repository import ConnectorRepository
from src.domain.edge_functions.repository import ProjectWebhookEndpointRepository
from src.domain.integrations.repository import ProjectIntegrationRepository
from src.domain.integrations.schemas import (
    InstallIntegrationRequest,
    IntegrationResponse,
    ProviderInfoResponse,
    UpdateIntegrationSecretsRequest,
)
from src.domain.integrations.service import IntegrationsService
from src.domain.projects.repository import ProjectRepository
from src.integrations.cloud_control_client import CloudControlClient

catalog_router = APIRouter(prefix="/api/integrations", tags=["integrations"])
router = APIRouter(prefix="/api/projects/{project_id}/integrations", tags=["integrations"])


def _get_service(db: AsyncSession = Depends(get_db)) -> IntegrationsService:
    return IntegrationsService(
        integration_repo=ProjectIntegrationRepository(db),
        webhook_repo=ProjectWebhookEndpointRepository(db),
        cloud_client=CloudControlClient(),
        connector_repo=ConnectorRepository(db),
        project_repo=ProjectRepository(db),
    )


# ---------------------------------------------------------------------------
# Provider catalog
# ---------------------------------------------------------------------------


@catalog_router.get("/providers", response_model=list[ProviderInfoResponse])
async def list_providers(
    _: User = Depends(get_current_user),
    svc: IntegrationsService = Depends(_get_service),
) -> list[ProviderInfoResponse]:
    """List all supported integration providers and their required fields."""
    return svc.list_providers()


# ---------------------------------------------------------------------------
# Project integrations
# ---------------------------------------------------------------------------


@router.get("", response_model=list[IntegrationResponse])
async def list_integrations(
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: IntegrationsService = Depends(_get_service),
) -> list[IntegrationResponse]:
    return await svc.list_integrations(project_id)


@router.get("/{provider}", response_model=IntegrationResponse)
async def get_integration(
    provider: str,
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: IntegrationsService = Depends(_get_service),
) -> IntegrationResponse:
    return await svc.get_integration(project_id, provider)


@router.put("/{provider}", response_model=IntegrationResponse)
async def install_or_update_integration(
    provider: str,
    body: InstallIntegrationRequest,
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: IntegrationsService = Depends(_get_service),
) -> IntegrationResponse:
    """Install or update a provider integration.

    Idempotent — safe to call again to update config or rotate secrets.
    Secrets submitted here are stored encrypted and never returned.
    For webhook-capable providers (Stripe, GitHub), a webhook endpoint is
    auto-created on first install.
    """
    return await svc.install(project_id, provider, body)


@router.delete("/{provider}", status_code=204, response_model=None)
async def uninstall_integration(
    provider: str,
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: IntegrationsService = Depends(_get_service),
) -> None:
    """Disconnect an integration. Webhook endpoint is deactivated."""
    await svc.uninstall(project_id, provider)


@router.put("/{provider}/secrets", response_model=IntegrationResponse)
async def rotate_integration_secrets(
    provider: str,
    body: UpdateIntegrationSecretsRequest,
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: IntegrationsService = Depends(_get_service),
) -> IntegrationResponse:
    """Rotate one or more secrets without touching config."""
    return await svc.rotate_secrets(project_id, provider, body)
