# app/services/spi_scoring.py
import json
import datetime
from app.core.config import get_gemini_model
from google import genai
from google.genai import types
from app.models.general_module import get_username


def calculate_ability_grade(correct_count, total_count):
    """
    능력검사(言語/非言語) 등급 계산
    
    Args:
        correct_count: 정답 수
        total_count: 전체 문제 수
    
    Returns:
        tuple: (score, grade)
        - score: 정답 수
        - grade: A/B/C/D
    """
    if total_count == 0:
        return 0, "D"
    
    percentage = (correct_count / total_count) * 100
    
    if percentage >= 80:  # 4-5개 정답
        grade = "A"
    elif percentage >= 60:  # 3개 정답
        grade = "B"
    elif percentage >= 40:  # 2개 정답
        grade = "C"
    else:  # 0-1개 정답
        grade = "D"
    
    return correct_count, grade


def calculate_personality_scores(answers):
    """
    성격검사 점수 계산 (입력값 유연화 적용)
    - "A"만 오거나 "A 当てはまる"가 와도 모두 처리 가능
    """
    # 1. 첫 글자만 보고 점수 매핑 (대소문자 무관)
    score_map = {
        "A": 5, "B": 4, "C": 3, "D": 2, "E": 1
    }
    
    trait_scores = {
        "positivity": [], "cooperation": [], "resilience": [],
        "responsibility": [], "planning": []
    }
    
    for answer in answers:
        trait = answer.get("trait")
        selected = answer.get("selected_option", "") # None 방지
        
        if not selected:
            continue
            
        # ★ 핵심 수정: 입력값의 첫 글자만 따서 대문자로 변환 후 채점
        # 예: "a" -> "A", "A (Yes)" -> "A"
        first_char = str(selected).strip()[0].upper()
        
        if trait and first_char in score_map:
            trait_scores[trait].append(score_map[first_char])
    
    result = {}
    total_score = 0
    
    for trait, scores in trait_scores.items():
        if scores:
            avg_score = sum(scores) / len(scores)
            total_score += sum(scores)
            
            if avg_score >= 4.0: level = "高"
            elif avg_score >= 3.0: level = "中"
            else: level = "低"
            
            result[trait] = {"score": round(avg_score, 1), "level": level}
        else:
            # 답이 없어도 기본값 채워줌 (에러 방지)
            result[trait] = {"score": 0, "level": "測定不能"}
    
    result["total_score"] = total_score
    return result


def generate_spi_summary(language_grade, nonverbal_grade, personality_type):
    """
    SPI 결과 요약 메시지 생성
    
    Args:
        language_grade: 言語 등급 (A/B/C/D)
        nonverbal_grade: 非言語 등급 (A/B/C/D)
        personality_type: 性格 유형
    
    Returns:
        str: 요약 메시지
    """
    summary = f"""【SPI検査結果】

▼ 能力検査
言語能力: {language_grade}
非言語能力: {nonverbal_grade}

▼ 性格検査
{personality_type}

お疲れ様でした！"""
    
    return summary


# app/services/spi_scoring.py

def generate_professional_report(session_id, language_score, language_grade, 
                                 nonverbal_score, nonverbal_grade,
                                 personality_scores):
    """
    SPI 리포트 생성 (성격 부분은 리스트 없이 코멘트로만 대체)
    """
    import datetime
    
    now_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
    # 선 길이를 30자로 확대 (줄바꿈 문제 해결)
    thick_line = "━" * 35
    thin_line = "─" * 35
    
    # 1. username 가져오기
    username = get_username(session_id)
    display_name = username if username else session_id
    
    # 2. AI 코멘트 먼저 생성 (성격 파트에 넣기 위해)
    try:
        # 등급과 점수 모두 넘겨서 종합적인 코멘트 생성
        ai_comment = generate_ai_comment(personality_scores, language_grade, nonverbal_grade)
    except Exception as e:
        print(f"[SPI AI Comment Error] {e}")
        ai_comment = "データを分析中です..."

    # 3. 리포트 텍스트 구성 (줄바꿈은 자연스럽게 처리)
    report_text = f"""
{thick_line}
 SPI3 総合診断レポート
{thick_line}
Name : {display_name}
Date : {now_str}

{thin_line}
【1】 言語 (Language)
{thin_line}
  ■ スコア : {language_score} / 5
  ■ ランク : {language_grade}

{thin_line}
【2】 非言語 (Non-verbal)
{thin_line}
  ■ スコア : {nonverbal_score} / 5
  ■ ランク : {nonverbal_grade}

{thin_line}
【3】 性格・総評
{thin_line}
{ai_comment}
{thick_line}
"""
    
    return report_text


def generate_ai_comment(personality_scores, language_grade, nonverbal_grade):
    """
    SPI 결과 AI 코멘트 생성 (능력치 + 성격 통합 분석)
    """
    # Fallback용 변수를 함수 시작 부분에서 초기화 (스코프 문제 해결)
    high_traits = []
    trait_names = {
        "positivity": "積極性", "cooperation": "協調性", "responsibility": "責任感",
        "planning": "計画性", "resilience": "メンタル"
    }
    
    try:
        client = get_gemini_model()
        
        # 1. 데이터 전처리
        personality_lines = []
        
        for key, name in trait_names.items():
            if key in personality_scores:
                level = personality_scores[key].get("level", "-")
                personality_lines.append(f"- {name}: {level}")
                if level == "高":
                    high_traits.append(name)
        
        personality_text = "\n".join(personality_lines)
        is_all_high = (len(high_traits) == 5)
        
        # 2. 능력치 상태 파악 (낮은 등급이 있는지 확인)
        has_low_grade = (language_grade == "D" or nonverbal_grade == "D")
        
        # 3. 프롬프트 구성
        prompt = f"""
あなたは企業の人事担当者です。
以下のSPI検査結果に基づき、**この人はどんな人か**を分析してください。

【検査結果】
[能力検査]
- 言語能力ランク: {language_grade}
- 非言語能力ランク: {nonverbal_grade}

[性格検査]
{personality_text}

【作成の指針】
1. **分析の視点**: 「この人はどんな人か」を客観적으로分析してください。
   - 個人の「好み」ではなく、仕事における「実務遂行能力」「組織適応力」「ストレス耐性」に焦点を当ててください。
   - 「この人は〜な人です」「〜なタイプです」という形式で記述してください。

2. **能力と性格の統合**: 
   - 能力ランクが高い場合: その知能と性格面の組み合わせで、どんな特徴があるかを分析してください。
   - **能力ランクが低い(C, D)場合**: 能力の結果には直接触れず、性格面の特徴を中心に「この人はどんな人か」を分析してください。
   
3. **All High（全項目が高い）の場合の対応**:
   - 絶対に「非現実的」「矛盾している」などの表現は避けてください。
   - 「組織適応力が高く、攻守のバランスが優れた万能型の人」「プレッシャーに強い強靭なメンタルの持ち主」として**客観的に分析**してください。

【制約事項】
- 言語: 自然な日本語
- 長さ: 100文字以内（簡潔に）
- 形式: 「この人は〜な人です」「〜なタイプです」「〜持ち主です」など、**「この人はどんな人か」を説明する形式**
- トーン: **客観的でプロフェッショナルな分析**（応援や励ましの言葉は使わない）
- 終わり方: 「〜人です」「〜タイプです」「〜持ち主です」など、**客観的な分析で終わる**（「自信を持ってください」「頑張ってください」などの応援メッセージは絶対に使わない）
- **結果が低くても、絶対に否定的な言葉（向いていない、ダメだ等）は使わないこと**

この人はどんな人か、分析してください:
"""

        # 4. API 호출 (Temperature를 낮춰서 일관성 유지)
        response = client.models.generate_content(
            model="gemini-2.5-flash",
            contents=[types.Content(role="user", parts=[types.Part(text=prompt)])],
            config=types.GenerateContentConfig(temperature=0.4) 
        )
        
        ai_comment = response.text.strip()
        
        if not ai_comment:
            raise ValueError("Empty response from AI")
            
        return ai_comment

    except Exception as e:
        print(f"[SPI AI Comment Error] {e}")
        # Fallback 로직 (high_traits는 함수 시작 부분에서 초기화되어 있음)
        is_all_high = (len(high_traits) == 5)
        if is_all_high:
            return "組織適応力が高く、攻守のバランスが非常に優れた「万能型」の人です。"
        else:
            # 성격 강점을 객관적으로 분석
            if high_traits:
                trait_str = "と".join(high_traits[:2]) if len(high_traits) >= 2 else high_traits[0]
                return f"高い{trait_str}を持つ、バランスの取れた人材です。"
            else:
                return "検査結果を基に、この人の特徴を分析中です。"