"""feature_packs domain — HTTP routes.

Currently just the one owner-facing action that install_pack cannot do on its own: supplying a
provider-generated webhook signing secret (Stripe et al.) once the owner has created the
dashboard endpoint install_pack's response pointed them at. See PackInstallService.complete_webhook_setup.
"""
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.core.exceptions import NotFoundError, ValidationError
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 (
    FunctionLibraryRepository,
    FunctionLibraryVersionRepository,
    ProjectFunctionRepository,
    ProjectFunctionTokenRepository,
    ProjectFunctionVersionRepository,
    ProjectWebhookEndpointRepository,
    WorkerRuntimeVersionRepository,
)
from src.domain.edge_functions.service import EdgeFunctionsService
from src.domain.feature_packs.service import PackInstallService
from src.domain.projects.repository import ProjectRepository
from src.domain.projects.schemas import WebhookSetupComplete
from src.integrations.cloud_control_client import CloudControlClient

router = APIRouter(prefix="/api", tags=["feature-packs"])


def _get_service(db: AsyncSession = Depends(get_db)) -> PackInstallService:
    edge_functions = EdgeFunctionsService(
        library_repo=FunctionLibraryRepository(db),
        library_version_repo=FunctionLibraryVersionRepository(db),
        fn_repo=ProjectFunctionRepository(db),
        version_repo=ProjectFunctionVersionRepository(db),
        webhook_repo=ProjectWebhookEndpointRepository(db),
        runtime_repo=WorkerRuntimeVersionRepository(db),
        token_repo=ProjectFunctionTokenRepository(db),
        project_repo=ProjectRepository(db),
        connector_repo=ConnectorRepository(db),
        cloud_client=CloudControlClient(),
    )
    return PackInstallService(db, edge_functions, CloudControlClient())


@router.post("/projects/{project_id}/feature-packs/{pack_slug}/webhooks/{provider}/complete-setup")
async def complete_webhook_setup(
    pack_slug: str,
    provider: str,
    body: WebhookSetupComplete,
    project_id: UUID = Depends(require_active_billing_for_project_id),
    user: User = Depends(get_current_user),
    svc: PackInstallService = Depends(_get_service),
    db: AsyncSession = Depends(get_db),
):
    """Supply the signing secret for a pack webhook left blocked by install_pack.

    Stripe (and similarly dashboard-registered providers) only hand back a signing secret once
    the owner creates the webhook endpoint using the `webhook_url` from the pack's install
    response — install_pack cannot obtain it up front, so it leaves the subscription unverified
    and the pack blocked until this is called.
    """
    result = await svc.complete_webhook_setup(
        project_id=project_id,
        pack_slug=pack_slug,
        provider=provider,
        signing_secret=body.signing_secret,
        signing_header=body.signing_header,
    )
    if not result.get("ok"):
        error = result.get("error")
        if error in ("pack_not_installed", "webhook_not_found"):
            raise NotFoundError(error)
        raise ValidationError(error or "webhook_setup_failed")
    await db.commit()
    return result
