"""
Evaluator — Conversion Measurement + Insight Accuracy
=======================================================
Đánh giá chatbot từ góc nhìn persona:
  A. Quality scores (1-5)
  B. Conversion status (converted/interested/dropped)
  C. Insight accuracy (bot nhận ra persona đúng bao nhiêu %)
  D. Product relevance (SP gợi ý phù hợp bao nhiêu %)

Model: gpt-5.4-nano
"""

import json
import logging
from typing import Any

from common.llm_factory import create_llm
from config import DEFAULT_MODEL

logger = logging.getLogger(__name__)

SIM_MODEL = DEFAULT_MODEL

# ═══════════════════════════════════════════════════════════════
# EVALUATE PROMPT
# ═══════════════════════════════════════════════════════════════
EVAL_SYSTEM = """Bạn là UX evaluator đánh giá chatbot bán hàng thời trang CANIFA.
Bạn quan sát cuộc chat giữa 1 khách giả lập (persona) và chatbot.

Đánh giá từ GÓC NHÌN PERSONA:

A. SCORES (1.0-5.0):
- clarity: Bot dễ hiểu?
- helpfulness: Giải quyết được vấn đề?
- naturalness: Tự nhiên?
- task_completion: Khách đạt mục đích?
- satisfaction: Hài lòng?

B. CONVERSION:
- conversion_status: "converted" | "interested" | "dropped"
  + converted = persona nói "mua", "đặt", "lấy cái này"
  + interested = hứng thú nhưng chưa quyết
  + dropped = mất hứng, từ chối, bot không phù hợp
- conversion_reason: Lý do 1 câu tiếng Việt

C. INSIGHT ACCURACY (nếu có):
- insight_accuracy: 0-100 (bot nhận đúng persona %)
- insight_details: Bot hiểu đúng/sai gì

D. PRODUCT:
- product_match: 0-100 (SP phù hợp persona %)
- product_details: SP hợp/không hợp

E. ANALYSIS:
- key_wins: 1-2 điểm mạnh (array, tiếng Việt)
- key_fails: 1-2 điểm yếu (array, tiếng Việt)
- prompt_fix: 1 instruction fix vấn đề lớn nhất (tiếng Việt)

Trả ONLY valid JSON."""


async def evaluate_conversation(
    persona_name: str,
    persona_age: int,
    persona_archetype: str,
    chat_style: str,
    budget: str,
    shopping_for: str,
    style_preference: str,
    conversion_trigger: str,
    drop_trigger: str,
    conversation: list[dict[str, str]],
    model_name: str | None = None,
) -> dict[str, Any]:
    """
    Evaluate 1 conversation → scores + conversion + insight accuracy.

    Returns dict with: scores, conversion_status, conversion_reason,
    insight_accuracy, product_match, key_wins, key_fails, prompt_fix
    """
    model = model_name or SIM_MODEL

    conv_text = "\n".join(
        f"{'Persona' if m['role'] == 'user' else 'Chatbot'}: {m['content']}"
        for m in conversation
    )

    eval_input = f"""Persona: {persona_name} ({persona_age} tuổi, {persona_archetype})
Chat style: {chat_style}
Budget: {budget}
Mua cho: {shopping_for}
Style: {style_preference}

CONVERSION CRITERIA:
- MUA khi: {conversion_trigger}
- BỎ khi: {drop_trigger}

Conversation ({len(conversation)} messages):
{conv_text}

Evaluate and determine CONVERSION STATUS."""

    llm = create_llm(model, streaming=False, json_mode=True)

    # Retry
    for attempt in range(3):
        try:
            response = await llm.ainvoke([
                {"role": "system", "content": EVAL_SYSTEM},
                {"role": "user", "content": eval_input},
            ])

            raw = response.content
            if isinstance(raw, list):
                raw = "".join(str(c.get("text", c) if isinstance(c, dict) else c) for c in raw)

            return json.loads(raw)

        except Exception as e:
            logger.warning(f"⚠️ Evaluate fail (attempt {attempt+1}/3): {e}")

    logger.error(f"❌ Evaluate failed for {persona_name}")
    return {
        "scores": {"clarity": 0, "helpfulness": 0, "naturalness": 0, "task_completion": 0, "satisfaction": 0},
        "conversion_status": "error",
        "conversion_reason": "Evaluation failed",
        "key_wins": [],
        "key_fails": ["Evaluation error"],
        "prompt_fix": "",
    }


# ═══════════════════════════════════════════════════════════════
# SYNTHESIZE PROMPT
# ═══════════════════════════════════════════════════════════════
SYNTHESIS_SYSTEM = """Bạn là senior UX researcher. Phân tích kết quả simulation nhiều personas.

Tạo BÁO CÁO CONVERSION:

1. conversion_summary:
   - total_personas, converted, interested, dropped, conversion_rate

2. segment_analysis: Array of {archetype, conversion_status, avg_score, issue}

3. worst_personas: Tên persona điểm thấp nhất

4. systemic_issues: 2-3 vấn đề hệ thống (tiếng Việt)

5. top_fixes: Array of {title, instruction, impacts}

6. insight_accuracy_avg: Trung bình %

7. overall_score: 1.0-5.0

8. summary: 2-3 câu tóm executive (tiếng Việt)

Trả ONLY valid JSON."""


async def synthesize_results(
    results: list[dict[str, Any]],
    chatbot_prompt: str = "",
    model_name: str | None = None,
) -> dict[str, Any]:
    """
    Tổng hợp kết quả từ tất cả personas → Conversion Report.
    """
    model = model_name or SIM_MODEL

    summaries = []
    for r in results:
        scores = r.get("scores", {})
        ov = sum(scores.values()) / max(len(scores), 1)
        summaries.append(
            f"{r.get('persona_name', '?')} ({r.get('archetype', '?')}): "
            f"overall {ov:.1f}/5 | "
            f"conversion: {r.get('conversion_status', '?')} | "
            f"reason: {r.get('conversion_reason', '?')}\n"
            f"  Scores: {json.dumps(scores)}\n"
            f"  Insight accuracy: {r.get('insight_accuracy', '?')}%\n"
            f"  Product match: {r.get('product_match', '?')}%\n"
            f"  Wins: {'; '.join(r.get('key_wins', []))}\n"
            f"  Fails: {'; '.join(r.get('key_fails', []))}"
        )

    synth_input = f"""Chatbot prompt (trích): "{chatbot_prompt[:1000]}"

Results across {len(results)} personas:
{chr(10).join(summaries)}

Provide CONVERSION REPORT and top fixes."""

    llm = create_llm(model, streaming=False, json_mode=True)

    for attempt in range(3):
        try:
            response = await llm.ainvoke([
                {"role": "system", "content": SYNTHESIS_SYSTEM},
                {"role": "user", "content": synth_input},
            ])

            raw = response.content
            if isinstance(raw, list):
                raw = "".join(str(c.get("text", c) if isinstance(c, dict) else c) for c in raw)

            return json.loads(raw)

        except Exception as e:
            logger.warning(f"⚠️ Synthesize fail (attempt {attempt+1}/3): {e}")

    logger.error("❌ Synthesize failed")
    return {"error": "Synthesis failed after 3 attempts"}
