from fastapi import APIRouter, HTTPException, status
from pydantic import BaseModel, Field
from typing import Optional, Dict, Any, List

from pif_compiler.services.srv_echa import orchestrator
from pif_compiler.functions.common_log import get_logger

logger = get_logger()

router = APIRouter()


class EchaRequest(BaseModel):
    cas: str = Field(..., description="CAS number of the substance to search for")

    class Config:
        json_schema_extra = {
            "example": {
                "cas": "50-00-0"
            }
        }


class EchaResponse(BaseModel):
    success: bool
    cas: str
    data: Optional[Dict[str, Any]] = None
    error: Optional[str] = None


class EchaBatchRequest(BaseModel):
    cas_list: List[str] = Field(..., description="List of CAS numbers to search for")

    class Config:
        json_schema_extra = {
            "example": {
                "cas_list": ["50-00-0", "64-17-5", "67-56-1"]
            }
        }


class EchaBatchResponse(BaseModel):
    success: bool
    total: int
    successful: int
    failed: int
    results: List[EchaResponse]


@router.post("/echa/search", response_model=EchaResponse, tags=["ECHA"])
async def search_echa_substance(request: EchaRequest):
    """
    Search for substance information in ECHA database.

    This endpoint orchestrates the full ECHA data extraction process:
    1. Validates the CAS number
    2. Checks local MongoDB cache
    3. If not found locally, fetches from ECHA:
       - Substance information
       - Dossier information
       - Toxicological information
       - Acute toxicity data
       - Repeated dose toxicity data
    4. Caches the result locally

    Args:
        request: EchaRequest containing the CAS number

    Returns:
        EchaResponse with the substance data or error information
    """
    logger.info(f"API request received for CAS: {request.cas}")

    try:
        result = orchestrator(request.cas)

        if result is None:
            logger.warning(f"No data found for CAS: {request.cas}")
            return EchaResponse(
                success=False,
                cas=request.cas,
                data=None,
                error="No data found for the provided CAS number. The CAS may be invalid or not registered in ECHA."
            )

        # Remove MongoDB _id field if present (it's not JSON serializable)
        if "_id" in result:
            del result["_id"]

        logger.info(f"Successfully retrieved data for CAS: {request.cas}")
        return EchaResponse(
            success=True,
            cas=request.cas,
            data=result,
            error=None
        )

    except Exception as e:
        logger.error(f"Error processing request for CAS {request.cas}: {str(e)}", exc_info=True)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Internal error while processing CAS {request.cas}: {str(e)}"
        )


@router.post("/echa/batch-search", response_model=EchaBatchResponse, tags=["ECHA"])
async def batch_search_echa_substances(request: EchaBatchRequest):
    """
    Search for multiple substances in ECHA database.

    This endpoint processes multiple CAS numbers in a single request.
    Each CAS number is processed independently using the same orchestration
    process as the single search endpoint.

    Args:
        request: EchaBatchRequest containing a list of CAS numbers

    Returns:
        EchaBatchResponse with results for all CAS numbers, including
        success/failure counts and individual results
    """
    logger.info(f"Batch API request received for {len(request.cas_list)} CAS numbers")

    results = []
    successful = 0
    failed = 0

    for cas in request.cas_list:
        try:
            logger.info(f"Processing CAS: {cas}")
            result = orchestrator(cas)

            if result is None:
                logger.warning(f"No data found for CAS: {cas}")
                results.append(EchaResponse(
                    success=False,
                    cas=cas,
                    data=None,
                    error="No data found for the provided CAS number. The CAS may be invalid or not registered in ECHA."
                ))
                failed += 1
            else:
                # Remove MongoDB _id field if present
                if "_id" in result:
                    del result["_id"]

                logger.info(f"Successfully retrieved data for CAS: {cas}")
                results.append(EchaResponse(
                    success=True,
                    cas=cas,
                    data=result,
                    error=None
                ))
                successful += 1

        except Exception as e:
            logger.error(f"Error processing CAS {cas}: {str(e)}", exc_info=True)
            results.append(EchaResponse(
                success=False,
                cas=cas,
                data=None,
                error=f"Internal error: {str(e)}"
            ))
            failed += 1

    logger.info(f"Batch request completed: {successful} successful, {failed} failed out of {len(request.cas_list)} total")

    return EchaBatchResponse(
        success=True,
        total=len(request.cas_list),
        successful=successful,
        failed=failed,
        results=results
    )


@router.get("/echa/health", tags=["ECHA"])
async def echa_health_check():
    """
    Health check endpoint for ECHA service.

    Returns the status of the ECHA service components.
    """
    return {
        "status": "healthy",
        "service": "echa-orchestrator",
        "components": {
            "api": "operational",
            "scraper": "operational",
            "parser": "operational"
        }
    }