import subprocess
import json
import tempfile
import os
from fastapi import FastAPI, HTTPException, BackgroundTasks, status
from pydantic import BaseModel
from typing import Dict, List, Any, Optional
from fastapi.middleware.cors import CORSMiddleware
import logging
from fastapi.responses import StreamingResponse

# Import the new manager models
from manager_career_guidance_models import (
    ManagerCareerGuidanceRequest, 
    ManagerCareerGuidanceResponse
)

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Define models for request validation
class Skill(BaseModel):
    skill_id: str
    skill_type: str
    skill_name: str

class JobProfile(BaseModel):
    job_profile_name: Optional[str] = None
    job_profile_skills: Optional[List[Skill]] = None

class UserInfo(BaseModel):
    user_name: str
    managerId: str
    designation: str
    jobProfile: Optional[JobProfile] = None
    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]]

class RecommendedCourse(BaseModel):
    courseId: str
    courseName: str
    matchScore: str
    reason: str
    scenario_relevance: str

class OnlineCourse(BaseModel):
    courseId: str
    courseName: str
    platform: str
    instructor: str
    duration: str
    matchScore: int
    reason: str
    score: float
    isOnlineCourse: bool = True
    url: str
    type: str
    lastUpdated: int
    thumbnail: Optional[str] = None

# In the CareerGuidanceResponse model, add token_count
class CareerGuidanceResponse(BaseModel):
    answer: str
    recommended_courses: List[RecommendedCourse]
    online_course_recommendations: Optional[List[OnlineCourse]] = []
    skill_gap_chart: Optional[Dict[str, Any]] = None
    job_profile_analysis: Optional[Dict[str, Any]] = None
    career_context: Optional[Dict[str, Any]] = None
    token_count: int 

class PlatformCourseRequest(BaseModel):
    client_id: int
    user_query: str
    user_data: Dict[str, UserInfo]
    platform_name: str

class PlatformCourseResponse(BaseModel):
    online_course_recommendations: List[OnlineCourse]


app = FastAPI(
    title="Career Guidance API",
    description="API for career guidance recommendations using Ollama with Gemma 12B",
    version="1.0.0"
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/")
async def root():
    return {"status": "API is running", "message": "Welcome to Career Guidance production API"}

@app.post("/career-guidance", response_model=CareerGuidanceResponse)
async def get_career_guidance(request: CareerGuidanceRequest, background_tasks: BackgroundTasks):
    try:
        payload = request.dict()
        with tempfile.NamedTemporaryFile(mode='w+', suffix='.json', delete=False) as tmp_file:
            temp_file_path = tmp_file.name
            json.dump(payload, tmp_file)
            tmp_file.flush()
            os.fsync(tmp_file.fileno())

        try:
            result = subprocess.run(
                ["python3", "my_career_production.py", temp_file_path],
                capture_output=True,
                text=True,
                check=True
            )

            output = result.stdout.strip()
            logger.info(f"Script output: {output}")

            try:
                json_start = output.find('{')
                json_end = output.rfind('}') + 1
                if json_start >= 0 and json_end > json_start:
                    json_str = output[json_start:json_end]
                    response_data = json.loads(json_str)
                    
                    # Ensure token_count exists in response
                    if 'token_count' not in response_data:
                        response_data['token_count'] = 0
                else:
                    raise HTTPException(
                        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                        detail="No valid JSON found in script output"
                    )

            except json.JSONDecodeError as e:
                raise HTTPException(
                    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                    detail="Failed to parse script output"
                )

            background_tasks.add_task(cleanup_temp_file, temp_file_path)

            # Build response with all required fields
            final_response_data = {
                "answer": response_data.get("answer", ""),
                "recommended_courses": response_data.get("recommended_courses", []),
                "online_course_recommendations": response_data.get("online_course_recommendations", []),
                "skill_gap_chart": response_data.get("skill_gap_chart", {}),
                "job_profile_analysis": response_data.get("job_profile_analysis", {}),
                "career_context": response_data.get("career_context", {}),
                "token_count": response_data.get("token_count", 0)
            }

            return final_response_data

        except subprocess.CalledProcessError as e:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"Error executing Python script: {e.stderr}"
            )

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Unexpected error: {str(e)}"
        )
    

@app.post("/career-guidance-manager", response_model=ManagerCareerGuidanceResponse)
async def get_manager_career_guidance(request: ManagerCareerGuidanceRequest, background_tasks: BackgroundTasks):
    """
    Advanced career guidance endpoint specifically designed for managers.
    Provides comprehensive team analysis, management insights, and strategic recommendations.
    Now includes total token count in the response.
    """
    try:
        payload = request.dict()
        with tempfile.NamedTemporaryFile(mode='w+', suffix='.json', delete=False) as tmp_file:
            temp_file_path = tmp_file.name
            json.dump(payload, tmp_file)
            tmp_file.flush()
            os.fsync(tmp_file.fileno())

        try:
            result = subprocess.run(
                ["python3", "manager_career_guidance_processor.py", temp_file_path],
                capture_output=True,
                text=True,
                check=True,
                timeout=120
            )

            output = result.stdout.strip()

            try:
                json_start = output.find('{')
                json_end = output.rfind('}') + 1
                if json_start >= 0 and json_end > json_start:
                    json_str = output[json_start:json_end]
                    response_data = json.loads(json_str)
                else:
                    raise HTTPException(
                        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                        detail="No valid JSON found in script output"
                    )

            except json.JSONDecodeError as e:
                raise HTTPException(
                    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                    detail="Failed to parse script output"
                )

            background_tasks.add_task(cleanup_temp_file, temp_file_path)
            
            # Ensure token count is included in the response
            if 'total_tokens' not in response_data:
                response_data['total_tokens'] = 0  # Default value if not provided
                
            return response_data

        except subprocess.CalledProcessError as e:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"Error executing manager guidance script: {e.stderr}"
            )
        except subprocess.TimeoutExpired:
            raise HTTPException(
                status_code=status.HTTP_408_REQUEST_TIMEOUT,
                detail="Request processing timed out. Please try again."
            )

    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Unexpected error: {str(e)}"
        )
import asyncio
    
@app.post("/fetch-platform-courses", response_model=PlatformCourseResponse)
async def fetch_platform_courses(request: PlatformCourseRequest, background_tasks: BackgroundTasks):
    try:
        payload = request.dict()
        with tempfile.NamedTemporaryFile(mode='w+', suffix='.json', delete=False) as tmp_file:
            temp_file_path = tmp_file.name
            json.dump(payload, tmp_file)

        loop = asyncio.get_event_loop()
        result = await loop.run_in_executor(None, execute_subprocess, "my_career_fetch_particular_platform_online_courses.py", temp_file_path)

        output = result.stdout.strip()
        try:
            json_start = output.find('{')
            json_end = output.rfind('}') + 1
            if json_start >= 0 and json_end > json_start:
                json_str = output[json_start:json_end]
                response_data = json.loads(json_str)
            else:
                raise json.JSONDecodeError("No valid JSON found", output, 0)
        except json.JSONDecodeError:
            raise HTTPException(status_code=500, detail="Error parsing JSON output")

        response_data = {
            "online_course_recommendations": response_data.get("online_course_recommendations", [])
        }

        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 if hasattr(e, 'stderr') else 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):
    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):
    try:
        if os.path.exists(file_path):
            os.unlink(file_path)
    except Exception:
        pass