from fastapi import APIRouter, HTTPException
from app.models import findgoal_module
from app.models.general_module import get_username
from app.models.sales_sheet_module import get_sales_sheet_by_session
from app.schemas.findgoal_schema import StartFindGoalRequest, AnswerFindGoalRequest
from app.core.config import get_gemini_model
from google.genai import types
import json
from typing import Optional, Dict, Any

router = APIRouter(
    prefix="/goalskill-sales/api/findgoal",
    tags=["FindGoal"]
)

# =============================================================================
# 1. SYSTEM PROMPT（感情のブリッジ + 要因分析・状態目標 統合版）
# =============================================================================
SYSTEM_PROMPT_FINDGOAL = """
あなたは、ユーザーが自ら課題を認識し、自分自身をマネジメント（Self-Management）できるよう導くパートナー（熟練したセールスコーチ）です。
単にデータを突きつけるのではなく、**「感情のブリッジ（共感）」**を用いて、ユーザーの本音を引き出してください。

【対話のステップ】

**Step 1: 現実の直視と要因の深掘り（Reality & Factor Analysis）**
- **挨拶不要。「今期の累計データ（四半期）を見ると」から開始。**
- データ（目標・実績・達成率）を提示した後、クッション言葉を入れてから、要因分析を促す質問をします。
- **必須:** 決めつけず、代表的な要因（量・質・心）を例示し、ユーザー自身に「真因」を探らせてください。
- セリフはサーバーで生成済み。Step 1 の内容に沿ってユーザー回答を受け止めてください。

**Step 2: 「追われる現状」を断ち切り、ルーチン（仕組み）を目標に（Transformation）**
- ユーザーが要因（業務に追われている、ルーチンがない等）を答えたら、**共感した上で**「主導権を失う」に触れ、**「追われる現状を断ち切るために、どんな仕組み（ルーチン）を確立したいか」**を問います。
- **必ず以下の流れで応答してください：**
  1) 共感：「日々の業務に追われていると、どうしても主導権を失ってしまいますよね。よく分かります。」
  2) 問い：「では、その「追われる現状」を断ち切るために、今期は具体的にどんな「仕組み（ルーチン）」を確立したいですか？」
  3) 指示：「『〇〇な営業ルーチンを作る』といった形で、あなたの目標を言語化してみてください。」
- **NG対応:** 「340件やります」と数字だけで答えた場合 → **「その数字を安定して達成している人は、日々どんな習慣を持っていると思いますか？」**と問い返し、視座を引き上げてください。

**Step 3: 目標の確定（Lock-on）**
- ユーザーが目標を書いたら、それを強調して確定します。
- **以下の内容までで出力を終えてください。MBTI案内やボタンの文は出力しないでください（別のメッセージで表示します）。**
  「承知しました。その目標で確定します。

  🎯 **今期の確定ゴール**
  **『 {user_message} 』**

  素晴らしい定義です。一時的な達成ではなく、未来に続く『資産』を作る目標ですね。」

【注意事項】
- AIが「～を目標にしましょうか？」と誘導しないでください。ユーザーに「～を目標にする」と言わせてください。
- **ユーザーが「わからない」「よくわからない」「意味がわからない」と言った場合**は、責めずに「目標＝やりたい数」「実績＝実際にできた数」「ギャップ＝その差」を平易に言い換え、「この要因について、どこが一番のボトルネックだったと感じますか？」のように優しく聞き直してください。必ず status "continue" で返すこと。
"""

CATEGORY_NAMES = {
    1: "新規リストアップ行動",
    2: "架電数",
    3: "繋がるための行動",
    4: "アポ",
    5: "訪問",
    6: "見積",
    7: "見積額",
    8: "受注",
    9: "受注額",
}

PERIOD_LABELS = {
    "day": "日間",
    "week": "週間",
    "month": "月間",
    "quarter": "四半期",
}


def _format_value(val):
    """소수점 포맷팅 (예: 340.0 -> 340, 340.20 -> 340.2)"""
    try:
        f = float(val)
        if f == int(f):
            return int(f)
        return round(f, 1)
    except (TypeError, ValueError):
        return val


def _get_worst_performing(session_id: str) -> Optional[Dict[str, Any]]:
    """
    個人シート(1s)から **四半期(quarter)** データのみを対象に、
    達成率が最も低いカテゴリを1件返す。
    """
    rows = get_sales_sheet_by_session(session_id, "1s")
    if not rows:
        return None

    target_rows = [r for r in rows if r.get("period_type") == "quarter"]
    if not target_rows:
        target_rows = rows

    worst_record = None
    min_rate = 999.0

    for cat_idx in range(1, 10):
        t_row = next((r for r in target_rows if r.get("category") == cat_idx and r.get("record_type") == "target"), None)
        v_row = next((r for r in target_rows if r.get("category") == cat_idx and r.get("record_type") == "result"), None)

        if not t_row or not v_row:
            continue
        try:
            t_val = float(t_row.get("value") or 0)
            v_val = float(v_row.get("value") or 0)
        except (TypeError, ValueError):
            continue
        if t_val <= 0:
            continue

        rate = (v_val / t_val) * 100
        if rate < min_rate:
            min_rate = rate
            period_label = PERIOD_LABELS.get(t_row.get("period_type", ""), "期間")
            cat_name = CATEGORY_NAMES.get(cat_idx, f"項目{cat_idx}")
            worst_record = {
                "category_name": cat_name,
                "period": period_label,
                "target": _format_value(t_row["value"]),
                "value": _format_value(v_row["value"]),
                "rate": round(rate, 1),
            }

    return worst_record


@router.post("/start")
async def start_find_goal(request: StartFindGoalRequest):
    """FindGoal 시작: 분기(四半期) 기준 최저 달성률 데이터로 AI가 Step 1 멘트 생성"""
    session_id = request.session_id
    findgoal_module.clear_history(session_id)
    worst_data = _get_worst_performing(session_id)

    # worst_data가 있으면 AI 호출 없이 서버에서 완성 문장 생성 → 끊김 방지
    if worst_data:
        t_int = int(float(worst_data["target"]))
        v_int = int(float(worst_data["value"]))
        r_int = int(round(float(worst_data["rate"]), 0))
        cat = worst_data["category_name"]
        part1 = (
            f"今期の累計データ（四半期）を見ると、\n"
            f"チーム目標達成のために割り当てられた『{cat}』は\n"
            f"{t_int} 件に対して、現在 {v_int} 件（達成率 {r_int}%）ですね。"
        )
        part2 = (
            "この数字で良し悪しをつけるのではなく、『どこを伸ばすか』のヒントとして見ていただければと思います。\n\n"
            "このギャップの背景に、どんな要因があると感じますか？"
        )
        ai_message = part1 + "|||" + part2
        findgoal_module.save_question(session_id, 1, ai_message)
        return {"status": "continue", "question": ai_message, "step": 1}

    # シート 없음: AI로 안내 생성
    full_prompt = f"""
{SYSTEM_PROMPT_FINDGOAL}

(データが見つかりません。ユーザーにシートのアップロードを確認するよう、1文で案内してください。)
"""
    client = get_gemini_model()
    try:
        response = client.models.generate_content(
            model="gemini-2.5-flash",
            contents=[types.Content(role="user", parts=[types.Part(text=full_prompt)])],
            config=types.GenerateContentConfig(temperature=0.3, max_output_tokens=256),
        )
        ai_message = (response.text or "").strip() or "シートのデータが見つかりません。まずシートをアップロードしてください。"
        findgoal_module.save_question(session_id, 1, ai_message)
        return {"status": "continue", "question": ai_message, "step": 1}
    except Exception as e:
        print(f"Gemini Error: {e}")
        return {"status": "continue", "question": "分析エラーが発生しました。もう一度お試しください。", "step": 0}


@router.post("/answer")
async def answer_find_goal(request: AnswerFindGoalRequest):
    """사용자 답변 처리 → 목표 확정(completed) 또는 다음 질문(continue)"""
    session_id = request.session_id
    current_step = request.current_step or 1

    q = findgoal_module.get_question_by_step(session_id, current_step)
    if q:
        findgoal_module.save_answer(session_id, q["id"], request.user_message)

    history = findgoal_module.get_conversation_history(session_id)
    worst_data = _get_worst_performing(session_id)
    worst_str = f"分析対象: {worst_data['category_name']}" if worst_data else "（データなし）"
    history_text = "\n".join([
        f"AI: {h.get('question_text', '')}\nUser: {h.get('answer_text') or ''}"
        for h in history
    ])

    full_prompt = f"""
{SYSTEM_PROMPT_FINDGOAL}

【分析データ】
{worst_str}

【対話履歴】
{history_text}

ユーザー回答: {request.user_message}

(これに対する次の応答を生成してください。必ずJSONで status と message を返すこと。ユーザーが「わからない」と言った場合は status "continue" で、データを平易に説明し直してから優しく聞き直すこと。Step 3の条件を満たした場合のみ status "completed" を返すこと。)
"""

    response_schema = {
        "type": "OBJECT",
        "properties": {
            "status": {"type": "STRING", "enum": ["continue", "completed"]},
            "message": {"type": "STRING"},
            "final_goal": {"type": "STRING", "nullable": True},
        },
        "required": ["status", "message"],
    }

    client = get_gemini_model()
    try:
        response = client.models.generate_content(
            model="gemini-2.5-flash",
            contents=[types.Content(role="user", parts=[types.Part(text=full_prompt)])],
            config=types.GenerateContentConfig(
                temperature=0.3,
                max_output_tokens=512,
                response_mime_type="application/json",
                response_schema=response_schema,
            ),
        )
        result = json.loads(response.text or "{}")
        status = result.get("status") or "continue"
        msg = result.get("message") or ""

        if status == "completed":
            final_goal = result.get("final_goal") or request.user_message
            findgoal_module.save_or_update_output(session_id, final_goal)
            findgoal_module.sync_to_user_profile_summary(session_id, final_goal)
            username = get_username(session_id)
            return {"status": "completed", "message": msg or "目標を確定しました。", "final_goal": final_goal, "username": username}
        else:
            # continue または 不明な status のときは continue として扱い、메시지가 없으면 안내문 사용
            next_msg = msg or "もう少し具体的に教えていただけますか？データの意味が伝わりにくかったかもしれません。"
            next_step = current_step + 1
            findgoal_module.save_question(session_id, next_step, next_msg)
            return {"status": "continue", "question": next_msg, "step": next_step}
    except Exception as e:
        print(f"Error: {e}")
        # 500을 내리지 않고 안전한 continue 응답으로 대화 유지
        fallback = (
            "申し訳ありません。もう少しわかりやすくお伝えしますね。"
            "「目標」はやりたい数、「実績」は実際にできた数です。その差が『ギャップ』です。"
            "このギャップを埋めるために、日々の活動で何が足りないと感じますか？"
        )
        next_step = (request.current_step or 1) + 1
        findgoal_module.save_question(session_id, next_step, fallback)
        return {"status": "continue", "question": fallback, "step": next_step}
