"""Configure project drift monitoring — API endpoint.

POST /v1/dashboard/projects/{project_id}/configure
"""

from __future__ import annotations

import contextlib
import logging
import secrets
from typing import Any

from fastapi import APIRouter, Depends
from fastapi.responses import JSONResponse

from backend.api.middleware.api_key_auth import APIKeyContext, require_api_key
from backend.drift.models import (
    DriftConfigureRequest,
    DriftConfigureResponse,
    DriftSetupInstructions,
)

_log = logging.getLogger(__name__)

router = APIRouter()

_auth_dep = Depends(require_api_key)


@router.post("/v1/dashboard/projects/{project_id}/configure")
async def configure_project_drift(
    project_id: str,
    body: DriftConfigureRequest,
    auth: APIKeyContext = _auth_dep,
) -> JSONResponse:
    """Configure project drift monitoring."""
    from backend.shared.firestore import get_db

    # 1. Tier checks
    if "drift_alerts" not in auth.features:
        return JSONResponse(
            {"error": "Drift monitoring requires Team tier or above"},
            status_code=403,
        )

    if body.drift_mode == "event_driven" and "drift_event_driven" not in auth.features:
        return JSONResponse(
            {"error": "Event-driven drift requires Team tier or above"},
            status_code=403,
        )

    customer_id = auth.customer_id
    db = get_db()

    # 2. Verify project exists
    project_ref = (
        db.collection("customers")
        .document(customer_id)
        .collection("projects")
        .document(project_id)
    )
    project_doc = await project_ref.get()
    if not project_doc.exists:
        return JSONResponse({"error": "Project not found"}, status_code=404)

    project_data: dict[str, Any] = project_doc.to_dict() or {}
    current_drift_mode = project_data.get("drift_mode", "scheduled")

    # 3. Build project update
    project_update: dict[str, Any] = {}
    alert_config_update: dict[str, Any] = {}

    if body.drift_mode is not None:
        project_update["drift_mode"] = body.drift_mode

    if body.drift_alerts is not None:
        project_update["drift_monitoring"] = body.drift_alerts

    if body.state_source is not None:
        project_update["state_source"] = body.state_source

    if body.frameworks is not None:
        project_update["frameworks"] = body.frameworks

    if body.alert_webhook is not None:
        alert_config_update["webhook_url"] = body.alert_webhook

    if body.alert_email is not None:
        alert_config_update["alert_email"] = body.alert_email

    if body.alert_threshold is not None:
        alert_config_update["alert_threshold"] = body.alert_threshold

    if body.drift_alerts is True:
        # Ensure email_alerts is flagged in alert_config
        existing_config = project_data.get("alert_config", {})
        existing_config.update(alert_config_update)
        project_update["alert_config"] = existing_config
    elif alert_config_update:
        existing_config = project_data.get("alert_config", {})
        existing_config.update(alert_config_update)
        project_update["alert_config"] = existing_config

    # 4. Handle event_driven setup
    setup_instructions: DriftSetupInstructions | None = None
    webhook_secret_display: str | None = None

    switching_to_event_driven = (
        body.drift_mode == "event_driven" and current_drift_mode != "event_driven"
    )

    if switching_to_event_driven:
        # Generate webhook secret
        raw_secret = secrets.token_bytes(32)

        # Store in Secret Manager
        try:
            from google.cloud import secretmanager_v1

            sm_client = secretmanager_v1.SecretManagerServiceClient()
            secret_id = f"drift-secret-{project_id}"
            parent = "projects/complyform-prod"

            with contextlib.suppress(Exception):
                sm_client.create_secret(
                    request={
                        "parent": parent,
                        "secret_id": secret_id,
                        "secret": {"replication": {"automatic": {}}},
                    }
                )

            sm_client.add_secret_version(
                request={
                    "parent": f"{parent}/secrets/{secret_id}",
                    "payload": {"data": raw_secret},
                }
            )
        except Exception:
            _log.exception("Failed to store drift webhook secret")
            return JSONResponse(
                {"error": "Failed to configure event-driven drift"},
                status_code=500,
            )

        project_update["drift_webhook_secret_name"] = f"drift-secret-{project_id}"

        cloud = project_data.get("cloud", "gcp")
        cloud_account_id = project_data.get("cloud_account_id", "")
        webhook_url = "https://api.complyform.dev/v1/drift/event"
        hex_secret = raw_secret.hex()

        variables: dict[str, str] = {}
        if cloud == "gcp":
            variables = {
                "project_id": cloud_account_id,
                "webhook_url": webhook_url,
                "webhook_secret": hex_secret,
            }
        elif cloud == "aws":
            variables = {
                "region": "us-east-1",
                "webhook_url": webhook_url,
                "webhook_secret": hex_secret,
            }
        elif cloud == "azure":
            variables = {
                "subscription_id": cloud_account_id,
                "webhook_url": webhook_url,
                "webhook_secret": hex_secret,
            }

        terraform_module_url = f"https://complyform.dev/docs/drift-setup/{cloud}/"

        setup_instructions = DriftSetupInstructions(
            cloud=cloud,
            webhook_url=webhook_url,
            terraform_module_url=terraform_module_url,
            variables=variables,
            quickstart=(
                f"1. Download module from {terraform_module_url}\n"
                "2. Set variables in terraform.tfvars\n"
                "3. terraform apply"
            ),
        )
        webhook_secret_display = f"cf_drift_{hex_secret}"

    # 5. Store TFC token if provided
    if body.tfc_token is not None:
        try:
            from google.cloud import secretmanager_v1

            sm_client = secretmanager_v1.SecretManagerServiceClient()
            secret_id = f"tfc-token-{project_id}"
            parent = "projects/complyform-prod"

            with contextlib.suppress(Exception):
                sm_client.create_secret(
                    request={
                        "parent": parent,
                        "secret_id": secret_id,
                        "secret": {"replication": {"automatic": {}}},
                    }
                )

            sm_client.add_secret_version(
                request={
                    "parent": f"{parent}/secrets/{secret_id}",
                    "payload": {"data": body.tfc_token.encode("utf-8")},
                }
            )
        except Exception:
            _log.exception("Failed to store TFC token")

    # 6. Apply Firestore updates
    if project_update:
        await project_ref.update(project_update)

    # 7. Build response
    # Read back current state
    final_doc = await project_ref.get()
    final_data: dict[str, Any] = final_doc.to_dict() or {}

    response = DriftConfigureResponse(
        project_id=project_id,
        drift_mode=final_data.get("drift_mode", "scheduled"),
        drift_alerts=final_data.get("drift_monitoring", False),
        setup_instructions=setup_instructions,
        webhook_secret=webhook_secret_display,
    )

    return JSONResponse(response.model_dump(mode="json"), status_code=200)
