# app/routers/spi_router.py

from fastapi import APIRouter, HTTPException
import json
import random
from app.schemas import spi_schema
from app.models import spi_module
from app.services import spi_questions, spi_scoring
from app.core.config import logger

MAX_OPTIONS = 6  # 프론트에 표시할 최대 선택지 수


def trim_options(options: list, correct_answer: str, max_count: int = MAX_OPTIONS) -> list:
    """
    선택지가 max_count개 초과이면, 정답을 반드시 포함한 채 max_count개로 축소.
    정답이 없는 문제(성격검사 등)는 그대로 반환.
    """
    if not options or len(options) <= max_count:
        return options

    if not correct_answer:
        return options[:max_count]

    # 정답 옵션 찾기 (첫 글자로 매칭)
    correct_first = correct_answer[0] if correct_answer else None
    correct_opt = None
    wrong_opts = []

    for opt in options:
        opt_first = opt[0] if opt else None
        if correct_first and opt_first == correct_first and correct_opt is None:
            correct_opt = opt
        else:
            wrong_opts.append(opt)

    # 오답에서 랜덤으로 (max_count - 1)개 선택
    keep_wrong = random.sample(wrong_opts, min(max_count - 1, len(wrong_opts)))

    # 정답 + 선택된 오답을 원래 순서대로 정렬
    result_set = set()
    if correct_opt:
        result_set.add(correct_opt)
    result_set.update(keep_wrong)

    # 원래 options 순서 유지
    trimmed = [opt for opt in options if opt in result_set]
    return trimmed
from app.services.goalskill_classifier import classify_and_save
router = APIRouter(
    prefix="",
    tags=["SPI"]
)


@router.post("/start")
async def start_spi(request: spi_schema.StartSPIRequest):
    """
    SPI 시작 - 첫 번째 문제 반환
    
    Returns:
        - question_id: 문제 ID
        - question_type: 문제 유형
        - question_text: 문제 내용
        - options: 선택지
        - current: 현재 문제 번호
        - total: 전체 문제 수
    """
    try:
        # 이전 기록 초기화 (재시작용)
        spi_module.clear_session_logs(request.session_id)
        
        # 전체 문제 가져오기
        all_questions = spi_questions.get_all_questions()
        
        if not all_questions:
            raise HTTPException(status_code=500, detail="No questions available")
        
        # 첫 번째 문제
        first_question = all_questions[0]
        
        logger.info(f"SPI Started for session: {request.session_id}")
        
        return {
            "question_id": first_question["id"],
            "question_type": first_question["type"],
            "question_text": first_question["text"],
            "options": trim_options(first_question["options"], first_question.get("correct_answer")),
            "current": 1,
            "total": len(all_questions)
        }
        
    except Exception as e:
        logger.error(f"SPI Start Error: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/answer")
async def answer_spi(request: spi_schema.AnswerSPIRequest):
    """
    SPI 답변 제출
    
    Returns:
        - status: "continue" (계속) or "completed" (완료)
        - next_question: 다음 문제 (continue인 경우)
        - result: 최종 결과 (completed인 경우)
    """
    try:
        # 현재 문제 정보 가져오기
        current_question = spi_questions.get_question_by_id(request.question_id)
        
        if not current_question:
            raise HTTPException(status_code=404, detail="Question not found")
        
        # 정답 체크 (능력검사만)
        is_correct = None
        if current_question["type"] in ["language", "nonverbal"]:
            correct_answer = current_question.get("correct_answer")
            # 선택지 형식 통일: "A (ア)" 또는 "A 赤" → "A"만 추출해서 비교
            # correct_answer에서 첫 글자 추출
            correct_option = correct_answer[0] if correct_answer else None
            # 사용자 선택도 첫 글자만 비교 (이미 "A", "B" 형식으로 오지만 안전하게)
            user_option = request.selected_option[0] if request.selected_option else None
            is_correct = (user_option == correct_option)
        
        # 답변 저장 (spi_log)
        spi_module.save_answer(
            session_id=request.session_id,
            question_id=request.question_id,
            selected_option=request.selected_option,
            is_correct=is_correct
        )
        
        # 현재까지 답변한 문제 수 확인
        answered_count = spi_module.get_answer_count(request.session_id)
        total_questions = len(spi_questions.get_all_questions())
        
        logger.info(f"SPI Progress: {answered_count}/{total_questions} for session {request.session_id}")
        
        # 모든 문제 완료 시
        if answered_count >= total_questions:
            result = await calculate_final_result(request.session_id)
            return {
                "status": "completed",
                "result": result
            }
        
        # 다음 문제 반환
        all_questions = spi_questions.get_all_questions()
        next_question = all_questions[answered_count]  # 다음 문제 (0-based index)
        
        return {
            "status": "continue",
            "next_question": {
                "question_id": next_question["id"],
                "question_type": next_question["type"],
                "question_text": next_question["text"],
                "options": trim_options(next_question["options"], next_question.get("correct_answer")),
                "current": answered_count + 1,
                "total": total_questions
            }
        }
        
    except Exception as e:
        logger.error(f"SPI Answer Error: {e}")
        raise HTTPException(status_code=500, detail=str(e))


async def calculate_final_result(session_id: str):
    """SPI 최종 결과 계산"""
    try:
        # 1. 언어능력 채점
        language_answers = spi_module.get_answers_by_type(session_id, "language")
        language_correct = sum(1 for a in language_answers if a.get("is_correct") == 1)
        language_score, language_grade = spi_scoring.calculate_ability_grade(language_correct, len(language_answers))
        
        # 2. 비언어능력 채점
        nonverbal_answers = spi_module.get_answers_by_type(session_id, "nonverbal")
        nonverbal_correct = sum(1 for a in nonverbal_answers if a.get("is_correct") == 1)
        nonverbal_score, nonverbal_grade = spi_scoring.calculate_ability_grade(nonverbal_correct, len(nonverbal_answers))
        
        # 3. 성격검사 채점
        personality_answers = spi_module.get_answers_by_type(session_id, "personality")
        
        personality_answers_with_trait = []
        for answer in personality_answers:
            question = spi_questions.get_question_by_id(answer["question_id"])
            if question:
                personality_answers_with_trait.append({
                    "question_id": answer["question_id"],
                    "selected_option": answer["selected_option"],
                    "trait": question.get("trait")
                })
        
        # 결과 딕셔너리 생성
        personality_result = spi_scoring.calculate_personality_scores(personality_answers_with_trait)
        # 日本語キーに変換してJSON文字列に整形
        personality_for_db = spi_scoring.format_personality_for_db(personality_result)
        personality_score_json = json.dumps(personality_for_db, ensure_ascii=False)
        
        # 4. AI 코멘트 생성 (personality_type 컬럼에 저장하기 위해)
        try:
            ai_comment = spi_scoring.generate_ai_comment(
                personality_result, 
                language_grade, 
                nonverbal_grade
            )
        except Exception as e:
            logger.error(f"SPI AI Comment Generation Error: {e}")
            ai_comment = "データを分析中です..."
        
        # 5. DB 저장 (personality_type에 AI 코멘트 저장)
        spi_module.save_or_update_output(
            session_id=session_id,
            language_score=language_score,
            language_grade=language_grade,
            nonverbal_score=nonverbal_score,
            nonverbal_grade=nonverbal_grade,
            personality_score=personality_score_json,  # 個別特性JSONを保存
            personality_type=ai_comment  # AI コメント保存
        )
        
        await classify_and_save(
            session_id = session_id,
            part = "A",
            sender = "I",
            text = ai_comment
        )

        # 6. ★ 중요: 여기서 우리가 만든 리포트 생성 함수 호출 ★
        summary = spi_scoring.generate_professional_report(
            session_id=session_id,
            language_score=language_score,
            language_grade=language_grade,
            nonverbal_score=nonverbal_score,
            nonverbal_grade=nonverbal_grade,
            personality_scores=personality_result
        )
        logger.info(f"SPI Completed for session: {session_id}")
        
        return {
            "session_id": session_id,
            "language_score": language_score,
            "language_grade": language_grade,
            "nonverbal_score": nonverbal_score,
            "nonverbal_grade": nonverbal_grade,
            "personality_scores": personality_result,
            "personality_type": ai_comment, # API 응답에 AI 분석 코멘트 (frontend 용)
            "summary": summary # 옛날 레거시 텍스트용
        }
        
    except Exception as e:
        logger.error(f"SPI Result Calculation Error: {e}")
        raise e


@router.get("/result/{session_id}")
async def get_spi_result(session_id: str):
    """
    SPI 결과 조회
    
    Returns:
        SPI 최종 결과
    """
    try:
        output = spi_module.get_output(session_id)
        
        if not output:
            raise HTTPException(status_code=404, detail="No result found for this session")
        
        import json
        try:
            p_scores = json.loads(output.get("personality_score", "{}"))
        except:
            p_scores = {}
            
        result = {
            "session_id": session_id,
            "language_score": output.get("language_score", 0),
            "language_grade": output.get("language_grade", "E"),
            "nonverbal_score": output.get("nonverbal_score", 0),
            "nonverbal_grade": output.get("nonverbal_grade", "E"),
            "personality_scores": p_scores,
            "personality_type": output.get("personality_type", ""),
            "summary": "分析完了"
        }
        
        return {
            "status": "success",
            "result": result
        }
        
    except Exception as e:
        logger.error(f"SPI Result Get Error: {e}")
        raise HTTPException(status_code=500, detail=str(e))
