"""
Search routes for the sim-search API.

This module defines the routes for search execution and history.
"""

from typing import Any, List

from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session

from app.api.dependencies import get_current_active_user
from app.db.models import User, Search
from app.db.session import get_db
from app.schemas.search import SearchExecute, SearchResults, SearchHistory, SearchHistoryList
from app.services.search_service import SearchService

router = APIRouter()
search_service = SearchService()


@router.post("/execute", response_model=SearchResults)
async def execute_search(
    search_in: SearchExecute,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db),
) -> Any:
    """
    Execute a search with the given parameters.
    
    Args:
        search_in: Search parameters
        current_user: Current authenticated user
        db: Database session
        
    Returns:
        Search results
    """
    try:
        # Get the structured query from the input
        structured_query = search_in.structured_query.model_dump() if search_in.structured_query else {}
        
        # Print for debugging
        print(f"Executing search with structured_query: {structured_query}")
        
        # Call the search service
        search_results = await search_service.execute_search(
            structured_query=structured_query,  # Explicitly use keyword argument
            search_engines=search_in.search_engines,
            num_results=search_in.num_results,
            timeout=search_in.timeout,
            user_id=current_user.id,
            db=db,
        )
        return search_results
    except Exception as e:
        import traceback
        traceback.print_exc()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Error executing search: {str(e)}",
        )


@router.get("/engines", response_model=List[str])
async def get_available_search_engines(
    current_user: User = Depends(get_current_active_user),
) -> Any:
    """
    Get a list of available search engines.
    
    Args:
        current_user: Current authenticated user
        
    Returns:
        List of available search engine names
    """
    try:
        engines = await search_service.get_available_search_engines()
        return engines
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Error getting available search engines: {str(e)}",
        )


@router.get("/history", response_model=SearchHistoryList)
async def get_search_history(
    skip: int = 0,
    limit: int = 100,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db),
) -> Any:
    """
    Get the user's search history.
    
    Args:
        skip: Number of records to skip
        limit: Maximum number of records to return
        current_user: Current authenticated user
        db: Database session
        
    Returns:
        List of search history records
    """
    searches = db.query(Search).filter(Search.user_id == current_user.id).order_by(
        Search.created_at.desc()
    ).offset(skip).limit(limit).all()
    
    total = db.query(Search).filter(Search.user_id == current_user.id).count()
    
    return {"searches": searches, "total": total}


@router.get("/{search_id}", response_model=SearchResults)
async def get_search_results(
    search_id: str,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db),
) -> Any:
    """
    Get results for a specific search.
    
    Args:
        search_id: ID of the search
        current_user: Current authenticated user
        db: Database session
        
    Returns:
        Search results
        
    Raises:
        HTTPException: If the search is not found or doesn't belong to the user
    """
    search = db.query(Search).filter(
        Search.id == search_id, Search.user_id == current_user.id
    ).first()
    
    if not search:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Search not found",
        )
    
    return await search_service.get_search_results(search)


@router.delete("/{search_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_search(
    search_id: str,
    current_user: User = Depends(get_current_active_user),
    db: Session = Depends(get_db),
) -> None:
    """
    Delete a search from history.
    
    Args:
        search_id: ID of the search to delete
        current_user: Current authenticated user
        db: Database session
        
    Raises:
        HTTPException: If the search is not found or doesn't belong to the user
    """
    search = db.query(Search).filter(
        Search.id == search_id, Search.user_id == current_user.id
    ).first()
    
    if not search:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Search not found",
        )
    
    db.delete(search)
    db.commit()
