from datetime import datetime from fastapi import APIRouter,Depends,Query from fastapi.responses import JSONResponse from fastapi import HTTPException from openai import APIError from pydantic import BaseModel from db_setup import get_session from sqlalchemy.ext.asyncio import AsyncSession from analytics.ask import ask_analytics from analytics.views import Analytics from users.permissions import PermissionTag,require_permission from dotenv import load_dotenv load_dotenv() router = APIRouter() class AskRequest(BaseModel): question: str @router.get("/analytics/kpis/fetch") async def fetch_kpis( current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)), from_date: datetime | None = Query(None), to_date: datetime | None = Query(None), department: str | None = Query(None), recruiter_id: str | None = Query(None), session: AsyncSession = Depends(get_session), ): try: service=Analytics(session=session) data=await service.get_kpis(from_date,to_date,department,recruiter_id) return JSONResponse(content={"data":data,"total":1,"status_code":200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500,detail=str(e)) @router.get("/analytics/funnel/fetch") async def fetch_funnel( current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)), from_date: datetime | None = Query(None), to_date: datetime | None = Query(None), department: str | None = Query(None), recruiter_id: str | None = Query(None), session: AsyncSession = Depends(get_session), ): try: service=Analytics(session=session) data=await service.get_funnel(from_date,to_date,department,recruiter_id) return JSONResponse(content={"data":data,"total":len(data),"status_code":200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500,detail=str(e)) @router.get("/analytics/hiring-trend/fetch") async def fetch_hiring_trend( current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)), months: int = Query(7,ge=1), from_date: datetime | None = Query(None), to_date: datetime | None = Query(None), department: str | None = Query(None), recruiter_id: str | None = Query(None), session: AsyncSession = Depends(get_session), ): try: service=Analytics(session=session) data=await service.get_hiring_trend(months,from_date,to_date,department,recruiter_id) return JSONResponse(content={"data":data,"total":1,"status_code":200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500,detail=str(e)) @router.get("/analytics/source-performance/fetch") async def fetch_source_performance( current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)), from_date: datetime | None = Query(None), to_date: datetime | None = Query(None), department: str | None = Query(None), recruiter_id: str | None = Query(None), session: AsyncSession = Depends(get_session), ): try: service=Analytics(session=session) data=await service.get_source_performance(from_date,to_date,department,recruiter_id) return JSONResponse(content={"data":data,"total":len(data),"status_code":200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500,detail=str(e)) @router.post("/analytics/ask") async def ask( payload: AskRequest, current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)), session: AsyncSession = Depends(get_session), ): try: data=await ask_analytics(session,payload.question) return JSONResponse(content={"data":data,"total":1,"status_code":200}) except HTTPException: raise except ValueError as e: raise HTTPException(status_code=422,detail=str(e)) except (APIError,RuntimeError) as e: # The governed queries are fine — it is the language model that is # unreachable or misconfigured, so say that instead of a bare 500. raise HTTPException(status_code=503,detail=f"AI assistant unavailable: {e}") except Exception as e: raise HTTPException(status_code=500,detail=str(e)) @router.get("/analytics/recruiter-performance/fetch") async def fetch_recruiter_performance( current_user: dict = Depends(require_permission(PermissionTag.ANALYTICS_VIEW)), top: int = Query(5,ge=1), from_date: datetime | None = Query(None), to_date: datetime | None = Query(None), department: str | None = Query(None), recruiter_id: str | None = Query(None), session: AsyncSession = Depends(get_session), ): try: service=Analytics(session=session) data=await service.get_recruiter_performance(top,from_date,to_date,department,recruiter_id) return JSONResponse(content={"data":data,"total":len(data),"status_code":200}) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500,detail=str(e))