"""
Temporal Workflows Router - Proxy to control-plane-temporal service

This router provides access to Temporal workflow management APIs with authentication.
All endpoints are proxied to the control-plane-temporal service.

The proxy is intentionally thin - it only handles authentication and forwarding.
All request validation is done by the control-plane-temporal service itself.
"""

import httpx
from fastapi import APIRouter, Depends, HTTPException, Request, Response
from typing import Optional, Dict, Any
import structlog

from control_plane_api.app.middleware.auth import get_current_organization
from control_plane_api.app.config import settings

logger = structlog.get_logger()

router = APIRouter(prefix="/temporal-workflows", tags=["temporal-workflows"])


async def proxy_temporal_request(
    request: Request,
    path: str,
    organization: dict = None,
) -> Response:
    """
    Generic proxy function for Temporal Workflows API requests.

    Thin proxy that forwards requests directly to control-plane-temporal service.
    All validation is handled by the downstream service.

    Args:
        request: FastAPI request object (contains method, body, query params)
        path: Path to proxy (e.g., "/api/v1/workflows")
        organization: Organization context

    Returns:
        FastAPI Response with proxied content
    """
    try:
        token = request.state.kubiya_token
        auth_type = getattr(request.state, "kubiya_auth_type", "Bearer")
        org_id = organization["id"] if organization else None

        # Prepare headers for Temporal Workflows API
        headers = {
            "Authorization": f"{auth_type} {token}",
            "Accept": "application/json",
            "Content-Type": "application/json",
            "X-Kubiya-Client": "agent-control-plane",
        }

        if org_id:
            headers["X-Organization-ID"] = org_id

        # Forward Accept-Encoding header to disable gzip if requested by client
        if "accept-encoding" in request.headers:
            headers["Accept-Encoding"] = request.headers["accept-encoding"]

        # Build full URL
        base_url = settings.temporal_workflows_api_base.rstrip("/")
        full_url = f"{base_url}{path}"

        # Add query parameters from original request
        if request.url.query:
            full_url = f"{full_url}?{request.url.query}"

        # Read body for POST/PUT/PATCH requests
        body = None
        if request.method in ["POST", "PUT", "PATCH"]:
            try:
                body = await request.json()
            except:
                body = None

        # Make request to Temporal Workflows API
        async with httpx.AsyncClient(timeout=settings.temporal_workflows_api_timeout) as client:
            if request.method == "GET":
                response = await client.get(full_url, headers=headers)
            elif request.method == "POST":
                response = await client.post(full_url, headers=headers, json=body)
            elif request.method == "PUT":
                response = await client.put(full_url, headers=headers, json=body)
            elif request.method == "PATCH":
                response = await client.patch(full_url, headers=headers, json=body)
            elif request.method == "DELETE":
                response = await client.delete(full_url, headers=headers)
            else:
                raise HTTPException(status_code=405, detail=f"Method {request.method} not allowed")

            logger.info(
                "temporal_workflows_request",
                org_id=org_id,
                path=path,
                method=request.method,
                status=response.status_code,
            )

            # Clean response headers - remove compression headers since we handle encoding
            response_headers = dict(response.headers)
            # Remove headers that might cause decompression issues
            response_headers.pop("content-encoding", None)
            response_headers.pop("content-length", None)  # Will be recalculated

            # Return response with original status code
            return Response(
                content=response.content,
                status_code=response.status_code,
                headers=response_headers,
                media_type=response.headers.get("content-type", "application/json"),
            )

    except httpx.TimeoutException:
        logger.error("temporal_workflows_timeout", path=path, method=request.method)
        raise HTTPException(status_code=504, detail="Temporal Workflows API request timed out")
    except httpx.RequestError as e:
        logger.error("temporal_workflows_request_error", error=str(e), path=path)
        raise HTTPException(status_code=502, detail=f"Failed to connect to Temporal Workflows API: {str(e)}")
    except HTTPException:
        raise
    except Exception as e:
        logger.error("temporal_workflows_unexpected_error", error=str(e), error_type=type(e).__name__)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


# ============================================================================
# Workflow Management Endpoints (Thin Proxy - No Validation)
# ============================================================================

@router.api_route("/workflows", methods=["GET", "POST"])
async def workflows_endpoint(
    request: Request,
    organization: dict = Depends(get_current_organization),
):
    """
    Proxy for workflow operations:
    - GET: List workflow executions with optional filtering
    - POST: Start a new workflow execution

    All query parameters and body validation handled by control-plane-temporal service.
    """
    return await proxy_temporal_request(
        request=request,
        path="/api/v1/workflows",
        organization=organization,
    )


@router.get("/workflows/stats")
async def get_workflow_stats(
    request: Request,
    organization: dict = Depends(get_current_organization),
):
    """
    Get workflow statistics for dashboard.

    Returns counts of workflows by status (running, completed, failed, etc.).
    """
    return await proxy_temporal_request(
        request=request,
        path="/api/v1/workflows/stats",
        organization=organization,
    )


@router.get("/workflows/{workflow_id}")
async def get_workflow(
    request: Request,
    workflow_id: str,
    organization: dict = Depends(get_current_organization),
):
    """
    Get workflow execution status and details.

    Returns detailed information about a workflow execution,
    optionally including the result if the workflow has completed.

    Query parameters (handled by downstream service):
    - run_id: Specific run ID to query
    - include_result: Include workflow result if completed
    """
    return await proxy_temporal_request(
        request=request,
        path=f"/api/v1/workflows/{workflow_id}",
        organization=organization,
    )


@router.post("/workflows/{workflow_id}/signal")
async def signal_workflow(
    request: Request,
    workflow_id: str,
    organization: dict = Depends(get_current_organization),
):
    """
    Send a signal to a running workflow.

    Signals allow external events to be sent to a running workflow.

    Query parameters (handled by downstream service):
    - run_id: Specific run ID to signal

    Body (validated by downstream service):
    - signal_name: Name of the signal to send
    - args: Arguments to pass with the signal
    """
    return await proxy_temporal_request(
        request=request,
        path=f"/api/v1/workflows/{workflow_id}/signal",
        organization=organization,
    )


@router.post("/workflows/{workflow_id}/cancel")
async def cancel_workflow(
    request: Request,
    workflow_id: str,
    organization: dict = Depends(get_current_organization),
):
    """
    Cancel a running workflow.

    Sends a cancellation request to the workflow. The workflow can handle
    the cancellation gracefully by catching the CancelledError.

    Query parameters (handled by downstream service):
    - run_id: Specific run ID to cancel
    """
    return await proxy_temporal_request(
        request=request,
        path=f"/api/v1/workflows/{workflow_id}/cancel",
        organization=organization,
    )


@router.post("/workflows/{workflow_id}/terminate")
async def terminate_workflow(
    request: Request,
    workflow_id: str,
    organization: dict = Depends(get_current_organization),
):
    """
    Terminate a running workflow.

    Forcefully terminates the workflow without allowing it to handle cleanup.
    Use cancel for graceful shutdown when possible.

    Query parameters (handled by downstream service):
    - run_id: Specific run ID to terminate

    Body (validated by downstream service):
    - reason: Termination reason
    """
    return await proxy_temporal_request(
        request=request,
        path=f"/api/v1/workflows/{workflow_id}/terminate",
        organization=organization,
    )


@router.get("/health")
async def health_check(
    request: Request,
    organization: dict = Depends(get_current_organization),
):
    """
    Health check endpoint for Temporal Workflows API.

    Verifies connectivity to the control-plane-temporal service.
    """
    return await proxy_temporal_request(
        request=request,
        path="/health",
        organization=organization,
    )
