"""
Gemini CLI Lead Flow Test — 100 câu hỏi đa dạng.

Chạy khi server đang up: uvicorn server:app --host 0.0.0.0 --port 5000

Usage:
    cd backend
    python tests/gemini_lead_flow_test.py
    python tests/gemini_lead_flow_test.py 20   # chỉ chạy 20 câu
"""

import asyncio
import json
import logging
import os
import sys
import time

import httpx

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from common.gemini_cli_wrapper import GeminiCLI

logging.basicConfig(level=logging.INFO, format="%(message)s")
logger = logging.getLogger(__name__)

# ═══════════════════════════════════════════════
# Config
# ═══════════════════════════════════════════════
API_URL = "http://localhost:5000/api/agent/chat-lead-flow"
DEVICE_ID = "gemini-loop-tester"

gemini = GeminiCLI()

# ═══════════════════════════════════════════════
# 100 câu hỏi test đa dạng
# ═══════════════════════════════════════════════
TEST_QUESTIONS = [
    # ── MÙA HÈ ──
    "có áo mặc mùa hè thoáng mát không",
    "tìm áo phông nam mùa hè dưới 300k",
    "váy đi biển cho nữ có không bạn",
    "quần short nam đi chơi hè",
    "áo ba lỗ tập gym mùa hè",
    "đồ bơi trẻ em có không",
    "áo thun cotton thoáng mát cho bé trai",
    "váy liền đi dạo phố mùa hè",
    "quần linen nữ mặc hè thoải mái",
    "áo sơ mi ngắn tay nam mùa hè",

    # ── MÙA ĐÔNG ──
    "áo khoác mùa đông cho nữ",
    "áo giữ ấm cho bé gái 5 tuổi",
    "áo len nam dưới 500k",
    "áo phao trẻ em mùa đông",
    "quần jean dày mặc đông cho nam",
    "áo nỉ hoodie nữ giữ ấm",
    "set đồ mùa đông cho bé sơ sinh",
    "áo khoác gió nam đi làm mùa đông",
    "váy len dài mặc đông thanh lịch",
    "đồ ngủ mùa đông ấm áp",

    # ── ĐI LÀM / CÔNG SỞ ──
    "áo sơ mi nữ mặc đi làm",
    "quần tây nam công sở",
    "váy công sở thanh lịch dưới 600k",
    "áo polo nam đi làm smart casual",
    "set đồ công sở nữ mùa hè",
    "áo blazer nữ mặc văn phòng",
    "quần âu nữ ống đứng đi làm",
    "sơ mi trắng nam công sở size L",
    "đồ đi làm kín đáo mà vẫn đẹp",
    "trang phục họp quan trọng cho nữ",

    # ── ĐI CHƠI / DẠO PHỐ ──
    "đồ đi chơi cuối tuần cho nữ",
    "áo oversize nam đi dạo phố",
    "váy hoa đi picnic",
    "quần jogger nam đi chơi",
    "set đồ đi cafe cho nữ",
    "áo croptop nữ năng động",
    "quần short jean nữ đi chơi hè",
    "đồ đi chơi tết cho bé trai 3 tuổi",
    "áo khoác bomber nam cá tính",
    "đầm maxi đi du lịch",

    # ── ĐI TIỆC ──
    "váy đi tiệc cuối năm cho nữ",
    "áo sơ mi nam đi tiệc",
    "đầm dạ hội thanh lịch dưới 1 triệu",
    "trang phục đi đám cưới cho nam",
    "váy liền đi sinh nhật bạn",
    "áo vest nữ đi tiệc sang trọng",
    "đồ đi tiệc cho bé gái",
    "sơ mi cổ đức nam đi tiệc",
    "váy đen đi event",
    "set đồ đi gala cho nữ",

    # ── THỂ THAO ──
    "áo thể thao nam chạy bộ",
    "quần legging nữ tập yoga",
    "set đồ tập gym cho nam",
    "áo thun thể thao bé trai",
    "quần short thể thao nữ",
    "áo khoác gió thể thao chạy bộ",
    "đồ bơi nam tập bơi",
    "áo polo thể thao nam",
    "quần jogger nữ tập gym",
    "set thể thao trẻ em đi học",

    # ── MẶC NHÀ ──
    "đồ mặc nhà thoải mái cho nữ",
    "pyjama nam cotton mát",
    "đồ bộ mặc nhà cho bé gái",
    "áo ngủ nữ dễ thương",
    "quần short mặc nhà nam",
    "set đồ ngủ đôi couple",
    "đồ bộ mặc nhà nữ giá rẻ",
    "pyjama trẻ em dễ thương",
    "áo 2 dây mặc nhà nữ",
    "đồ ngủ cotton cho bé sơ sinh",

    # ── THEO MÀU SẮC ──
    "áo phông trắng basic nam",
    "váy đỏ đi tiệc nữ",
    "quần jean xanh đậm nam",
    "áo len hồng pastel nữ",
    "đồ đen full set cho nam",
    "áo khoác be nữ mùa thu",
    "váy vàng đi chơi",
    "áo xám basic oversize",
    "quần trắng nữ ống rộng",
    "sơ mi xanh nhạt nam",

    # ── THEO SIZE ──
    "áo phông nam size XXL",
    "váy nữ size XS nhỏ nhắn",
    "quần jean bé trai cao 140cm",
    "áo khoác nữ size 3XL",
    "đồ sơ sinh 0-3 tháng",

    # ── THEO GIÁ ──
    "áo dưới 200k cho nam",
    "váy đẹp dưới 400k",
    "đồ sale giảm giá 50%",
    "quần jean nam giá rẻ nhất",
    "set đồ dưới 500k cho nữ",

    # ── PHỐI ĐỒ / TƯ VẤN ──
    "mặc gì đi phỏng vấn xin việc",
    "gợi ý phối đồ đi hẹn hò",
    "mặc gì ngày 30/4 đẹp",
    "trang phục đi du lịch Đà Lạt mùa đông",
    "phối đồ đi biển Nha Trang",
]

# ═══════════════════════════════════════════════
# Evaluator prompt cho Gemini CLI
# ═══════════════════════════════════════════════
EVALUATOR_PROMPT = """\
Bạn là chuyên gia thời trang đánh giá chatbot tư vấn CANIFA.

CÂU HỎI KHÁCH: "{question}"

TRẢ LỜI CHATBOT:
{response}

SẢN PHẨM TÌM ĐƯỢC: {product_count} sản phẩm
{product_list}

ĐÁNH GIÁ theo 4 tiêu chí (mỗi cái YES/NO):
1. RELEVANT: Sản phẩm có phù hợp câu hỏi? (hỏi váy mà ra áo = NO)
2. NATURAL: Câu trả lời tự nhiên, thân thiện?
3. HELPFUL: Có tư vấn phối đồ hoặc gợi ý hữu ích?
4. ACCURATE: Thông tin giá, size, màu có chính xác?

TRẢ LỜI CHÍNH XÁC FORMAT:
VERDICT: PASS hoặc FAIL
SCORE: X/4
REASON: <1 dòng ngắn gọn>
"""


async def call_lead_flow_api(question: str, conversation_id: str) -> dict:
    """Gọi API lead flow trên server đang chạy."""
    async with httpx.AsyncClient(timeout=30) as client:
        resp = await client.post(
            API_URL,
            json={
                "user_query": question,
                "device_id": DEVICE_ID,
                "conversation_id": conversation_id,
            },
        )
        resp.raise_for_status()
        return resp.json()


async def run_one_test(idx: int, question: str) -> dict:
    """Chạy 1 test case."""
    t0 = time.time()
    conv_id = f"test-loop-{idx}"

    logger.info(f"\n{'─'*60}")
    logger.info(f"[{idx:03d}] 🧑 {question}")

    # 1. Gọi API lead flow
    try:
        result = await call_lead_flow_api(question, conv_id)
    except Exception as e:
        logger.error(f"  💥 API Error: {e}")
        return {"idx": idx, "question": question, "verdict": "ERROR", "reason": str(e)}

    ai_response = result.get("ai_response", "")[:300]
    products = result.get("products", [])
    product_count = len(products)

    product_names = [p.get("name", "?") for p in products[:5]]
    logger.info(f"  📦 {product_count} sản phẩm | response: {ai_response[:80]}...")
    for name in product_names[:3]:
        logger.info(f"     → {name}")

    # 2. Gemini CLI đánh giá
    product_list = "\n".join([
        f"  - {p.get('name','?')} | {p.get('price',0):,}đ | {p.get('color','?')} | {p.get('product_line','?')}"
        for p in products[:5]
    ]) or "  (không có sản phẩm)"

    eval_prompt = EVALUATOR_PROMPT.format(
        question=question,
        response=ai_response,
        product_count=product_count,
        product_list=product_list,
    )

    try:
        verdict_text = await gemini.ask(eval_prompt)
    except Exception as e:
        logger.warning(f"  ⚠️ Evaluator error: {e}")
        verdict_text = "VERDICT: UNKNOWN"

    # Parse verdict
    verdict = "PASS" if "PASS" in verdict_text.upper() else "FAIL"
    score = "?"
    reason = ""
    for line in verdict_text.splitlines():
        if "SCORE:" in line.upper():
            score = line.split(":")[-1].strip()
        if "REASON:" in line.upper():
            reason = line.split(":", 1)[-1].strip()

    elapsed = round(time.time() - t0, 1)
    icon = "✅" if verdict == "PASS" else "❌"
    logger.info(f"  {icon} {verdict} ({score}) | {reason} [{elapsed}s]")

    return {
        "idx": idx,
        "question": question,
        "product_count": product_count,
        "top_products": product_names,
        "ai_response": ai_response,
        "verdict": verdict,
        "score": score,
        "reason": reason,
        "elapsed_s": elapsed,
    }


async def main(max_rounds: int | None = None):
    """Chạy test loop."""
    questions = TEST_QUESTIONS[:max_rounds] if max_rounds else TEST_QUESTIONS
    total = len(questions)

    logger.info(f"🚀 Gemini CLI Lead Flow Test — {total} câu hỏi")
    logger.info(f"   API: {API_URL}")
    logger.info(f"   Evaluator: GeminiCLI (gemini-2.0-flash)")

    results = []
    for i, q in enumerate(questions, 1):
        try:
            r = await run_one_test(i, q)
            results.append(r)
        except Exception as e:
            logger.error(f"[{i:03d}] 💥 Fatal: {e}")
            results.append({"idx": i, "question": q, "verdict": "ERROR", "reason": str(e)})

        # Throttle: tránh rate limit Gemini CLI
        await asyncio.sleep(1)

    # ── Summary ──
    passed = sum(1 for r in results if r.get("verdict") == "PASS")
    failed = sum(1 for r in results if r.get("verdict") == "FAIL")
    errors = sum(1 for r in results if r.get("verdict") == "ERROR")
    avg_time = sum(r.get("elapsed_s", 0) for r in results) / max(len(results), 1)

    logger.info(f"\n{'═'*60}")
    logger.info(f"📊 KẾT QUẢ: {passed} PASS ✅ | {failed} FAIL ❌ | {errors} ERROR 💥")
    logger.info(f"   Tổng: {total} câu | Avg: {avg_time:.1f}s/câu")
    logger.info(f"   Pass rate: {passed/max(total,1)*100:.0f}%")
    logger.info(f"{'═'*60}")

    # Liệt kê FAIL cases
    fails = [r for r in results if r.get("verdict") == "FAIL"]
    if fails:
        logger.info(f"\n❌ FAIL CASES ({len(fails)}):")
        for f in fails:
            logger.info(f"  [{f['idx']:03d}] {f['question']}")
            logger.info(f"        → {f.get('reason', '?')}")

    # Save results
    out_path = os.path.join(os.path.dirname(__file__), "gemini_test_results.json")
    with open(out_path, "w", encoding="utf-8") as f:
        json.dump(results, f, ensure_ascii=False, indent=2)
    logger.info(f"\n💾 Full results: {out_path}")


if __name__ == "__main__":
    rounds = int(sys.argv[1]) if len(sys.argv) > 1 else None
    asyncio.run(main(rounds))
