"""Comparative route for canonical backend comparative analysis runtime."""

from __future__ import annotations

import logging
from typing import Any

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, Field

from app.core.security import verify_supabase_jwt
from app.services.ai.ai_gateway import (
    AIGatewayError,
    LLMPathExhaustedError,
    ProviderRequestError,
)
from app.services.analysis.comparative_schemas import (
    AnalisisPoin,
    PoinKritik,
)
from app.services.analysis.comparative_service import (
    ComparativeService,
    ComparativeServiceError,
    ComparativeValidationError,
)

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/comparative", tags=["Comparative Analysis"])


class ComparativeRequest(BaseModel):
    """Canonical comparative request DTO."""

    file_hashes: list[str] = Field(..., min_length=2)
    project_id: str = Field(..., min_length=1)
    aspects: list[str] | None = None
    llm_model: str | None = None
    top_k: int | None = None
    similarity_threshold: float | None = None


class ComparativeRequestContext(BaseModel):
    """Canonical request context response DTO."""

    project_id: str
    file_hashes: list[str]
    aspects_requested: list[str]


class ComparativeDiagnostics(BaseModel):
    """Canonical diagnostics DTO."""

    total_documents: int
    total_chunks_used: int
    llm_provider: str
    llm_model: str
    top_k: int
    similarity_threshold: float


class ComparativeResponse(BaseModel):
    """Canonical comparative response DTO."""

    request_context: ComparativeRequestContext
    konvergensi: list[AnalisisPoin]
    divergensi: list[AnalisisPoin]
    kritik_akademis: list[PoinKritik]
    sintesis_objektif: str
    keterbatasan_analisis: str
    diagnostics: ComparativeDiagnostics


@router.post(
    "/deep",
    summary="Comparative Deep Analysis",
    response_model=ComparativeResponse,
)
async def comparative_deep(
    payload: ComparativeRequest,
    user_id: str = Depends(verify_supabase_jwt),
) -> ComparativeResponse:
    """Run a structured comparative analysis using HyDE retrieval and LLM synthesis.

    Args:
        payload: Canonical comparative request DTO.
        user_id: Tenant user identifier derived from JWT.

    Returns:
        ComparativeResponse: Structured comparative analysis response.
    """
    service = ComparativeService()
    logger.info(
        "Comparative skeleton request accepted",
        extra={
            "user_id": user_id,
            "project_id": payload.project_id,
            "file_hash_count": len(payload.file_hashes),
        },
    )
    try:
        result = await service.run_comparative(
            user_id=user_id,
            project_id=payload.project_id.strip(),
            file_hashes=payload.file_hashes,
            aspects=payload.aspects,
            llm_model=payload.llm_model,
            top_k=payload.top_k,
            similarity_threshold=payload.similarity_threshold,
        )
    except ComparativeValidationError as exc:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail={
                "error_code": "COMPARATIVE_VALIDATION_ERROR",
                "error_message": str(exc),
                "error_category": "validation",
            },
        ) from exc
    except AIGatewayError as exc:
        raise HTTPException(
            status_code=status.HTTP_502_BAD_GATEWAY,
            detail={
                "error_code": "AI_GATEWAY_ERROR",
                "error_message": str(exc),
                "error_category": "provider_runtime",
            },
        ) from exc
    except (ProviderRequestError, LLMPathExhaustedError) as exc:
        raise HTTPException(
            status_code=status.HTTP_502_BAD_GATEWAY,
            detail={
                "error_code": "LLM_PROVIDER_ERROR",
                "error_message": str(exc),
                "error_category": "provider_exhausted",
            },
        ) from exc
    except ComparativeServiceError as exc:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail={
                "error_code": "COMPARATIVE_SERVICE_ERROR",
                "error_message": str(exc),
                "error_category": "service_runtime",
            },
        ) from exc

    return ComparativeResponse.model_validate(result)
