from fastapi import FastAPI, HTTPException, BackgroundTasks
from pydantic import BaseModel
from typing import Dict, List, Any, Optional
import subprocess
import json
import tempfile
import os
from fastapi.middleware.cors import CORSMiddleware
import asyncio

# Define models for request validation
class Skill(BaseModel):
    skill_id: str
    skill_type: str
    skill_name: str

class UserInfo(BaseModel):
    user_name: str
    managerId: str
    assignedCourses: List[str] = []
    completedCourses: List[str] = []
    skills: List[Skill] = []

class Course(BaseModel):
    courseId: str
    name: str
    short_description: str
    description: str
    skills: List[Skill] = []

class CareerGuidanceRequest(BaseModel):
    client_id: int
    user_query: str
    user_data: Dict[str, UserInfo]
    client_all_courses_data: Dict[int, List[Course]]  # Add this line

class RecommendedCourse(BaseModel):
    courseId: str
    courseName: str
    matchScore: str
    reason: str
    score: str

class OnlineCourse(BaseModel):
    courseId: str
    courseName: str
    platform: str
    instructor: str
    duration: str
    matchScore: str
    reason: str
    score: str
    isOnlineCourse: bool = True
    url: str  # Add this line to include the URL field


class CareerGuidanceResponse(BaseModel):
    answer: str
    recommended_courses: List[RecommendedCourse]
    online_course_recommendations: Optional[List[OnlineCourse]] = []
    

# Path to Python script
PYTHON_SCRIPT_PATH = "test.py"  # Update this to the actual path if needed

# Initialize FastAPI app
app = FastAPI(
    title="Career Guidance API",
    description="API for career guidance recommendations using Ollama with Gemma 12B",
    version="1.0.0"
)

# Add CORS middleware to allow cross-origin requests
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Allows all origins
    allow_credentials=True,
    allow_methods=["*"],  # Allows all methods
    allow_headers=["*"],  # Allows all headers
)

@app.get("/")
async def root():
    """Health check endpoint"""
    return {"status": "API is running", "message": "Welcome to Career Guidance API"}

@app.post("/career-guidance", response_model=CareerGuidanceResponse)
async def get_career_guidance(request: CareerGuidanceRequest, background_tasks: BackgroundTasks):
    """
    Process career guidance request by invoking the Python script
    """
    try:
        # Convert Pydantic model to dict
        payload = request.dict()

        # Create a temporary file to store the JSON payload
        with tempfile.NamedTemporaryFile(mode='w+', suffix='.json', delete=False) as tmp_file:
            temp_file_path = tmp_file.name
            json.dump(payload, tmp_file)

        # Execute the Python script with the temporary file path asynchronously
        loop = asyncio.get_event_loop()
        result = await loop.run_in_executor(None, execute_subprocess, PYTHON_SCRIPT_PATH, temp_file_path)

        # Process the output
        output = result.stdout.strip()

        # Parse JSON output
        response_data = json.loads(output)

        # Schedule cleanup in the background
        background_tasks.add_task(cleanup_temp_file, temp_file_path)

        return response_data

    except subprocess.CalledProcessError as e:
        raise HTTPException(status_code=500, detail=f"Error executing Python script: {e.stderr}")
    except json.JSONDecodeError as e:
        raise HTTPException(status_code=500, detail=f"Error parsing JSON output: {str(e)}")
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Unexpected error: {str(e)}")

def execute_subprocess(script_path, temp_file_path):
    """Execute the subprocess and capture output"""
    result = subprocess.run(
        ["python3", script_path, temp_file_path],
        capture_output=True,
        text=True,
        check=True
    )
    return result

def cleanup_temp_file(file_path: str):
    """Remove temporary file after processing"""
    try:
        if os.path.exists(file_path):
            os.unlink(file_path)
    except Exception as e:
        pass
