import asyncio
import json
import logging
from typing import Optional

from fastapi import APIRouter, Query
from fastapi.responses import StreamingResponse, JSONResponse

from worker.stylist_engine import StylistEngine

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/fashion-matches/simulator", tags=["Fashion Matches Simulator"])

@router.get("/search")
async def search_product(q: str = Query(..., description="Mã SP hoặc Tên SP", min_length=2)):
    """API hỗ trợ tìm kiếm nhanh Product Code cho Simulator"""
    try:
        engine = StylistEngine()
        catalog = engine._get_catalog()
        
        q_lower = q.lower().strip()
        results = []
        
        for p in catalog:
            code = p.get("code", "").lower()
            ref = p.get("internal_ref_code", "").lower()
            name = p.get("name", "").lower()
            
            # Simple match logic
            if q_lower in code or q_lower in ref or q_lower in name:
                results.append({
                    "code": p.get("code"),
                    "name": p.get("name"),
                    "image": p.get("image", ""),
                    "color": p.get("color", "")
                })
                if len(results) >= 10:
                    break
        
        return {"ok": True, "data": results}
    except Exception as e:
        logger.error("[Simulator] Search error: %s", e)
        return JSONResponse({"ok": False, "error": str(e)}, status_code=500)


@router.get("/stream")
async def stream_flow(code: str = Query(..., description="Product code to simulate")):
    """SSE Endpoint cho Realtime Live Simulator"""
    
    async def event_generator():
        try:
            # --- BƯỚC 1: INIT ---
            msg = json.dumps({
                "step": 1,
                "node": "init",
                "status": f"🔧 Khởi chạy Cỗ máy StylistEngine. Mã SP đưa vào: {code}..."
            }, ensure_ascii=False)
            yield f"data: {msg}\n\n"
            await asyncio.sleep(0.8) # Dramatic delay

            engine = StylistEngine()
            catalog = engine._get_catalog()
            source = next((p for p in catalog if p["code"] == code), None)

            if not source:
                yield f"data: {json.dumps({'error': True, 'status': '❌ Không tìm thấy mã sản phẩm trong Catalog!'})}\n\n"
                return

            # --- BƯỚC 2: PHÂN TÍCH SP GỐC ---
            msg = json.dumps({
                "step": 2,
                "node": "fetch_product",
                "status": f"🔍 Bóc tách SP gốc: {source.get('name')} (Màu: {source.get('color')} / Giới tính: {source.get('gender')})",
                "payload": {
                    "code": source.get("code"),
                    "name": source.get("name"),
                    "image": source.get("image"),
                    "color": source.get("color"),
                    "category": source.get("product_line")
                }
            }, ensure_ascii=False)
            yield f"data: {msg}\n\n"
            await asyncio.sleep(1.0)

            # --- BƯỚC 3: KÉO LUẬT DB ---
            anchor_cat = source.get("product_line", "")
            gender = source.get("gender", "")
            db_rules = engine._fetch_rules_with_reason(anchor_cat, gender)
            rules_count = len(db_rules)
            
            if rules_count == 0:
                status_rules = f"⚠️ Không có luật DB từ [chatbot_fashion_rules] cho '{anchor_cat}'. Rơi vào Fallback Rules."
            else:
                status_rules = f"📂 Khớp thành công {rules_count} luật (Rules) phối đồ theo Dịp (Occasion) & Role từ Database."
                
            msg = json.dumps({
                "step": 3,
                "node": "fetch_rules",
                "status": status_rules,
                "payload": {"rules_count": rules_count}
            }, ensure_ascii=False)
            yield f"data: {msg}\n\n"
            await asyncio.sleep(1.2)

            # --- BƯỚC 4: CHẤM ĐIỂM ---
            msg = json.dumps({
                "step": 4,
                "node": "scoring",
                "status": "🧮 Khởi động Scoring Engine: Tính điểm Color Synergy (30đ), Material (10đ), Occasion (20đ) cho toàn bộ Catalog..."
            }, ensure_ascii=False)
            yield f"data: {msg}\n\n"
            
            # (Run the heavy lifting here)
            ai_matches = engine.compute_dynamic_rule_matches(code)
            await asyncio.sleep(1.5)

            # --- BƯỚC 5: HẬU KỲ VÀ PHẨN LOẠI MỞ RỘNG (DEDUPLICATE / SQL CLASSIFICATIONS) ---
            msg = json.dumps({
                "step": 5,
                "node": "dedup",
                "status": "📋 Sàng lọc (Deduplication): Loại bỏ kết quả trùng, lấy Top 3 cho mỗi Role (Top/Bottom/Khoác)... Đồng thời nạp Data Phân Loại mở rộng SQL."
            }, ensure_ascii=False)
            yield f"data: {msg}\n\n"
            
            classifications = engine.compute_super_classifications_sql(code)
            await asyncio.sleep(0.8)

            # --- BƯỚC 6: FINISH ---
            msg = json.dumps({
                "step": 6,
                "node": "complete",
                "status": "✅ HOÀN TẤT! Đẩy khung Outfit JSON ra giao diện.",
                "payload": {
                    "ai_matches": ai_matches,
                    "classifications": classifications
                }
            }, ensure_ascii=False)
            yield f"data: {msg}\n\n"

        except Exception as e:
            logger.error("[Simulator] Generator error: %s", e)
            msg = json.dumps({"error": True, "status": f"❌ Lỗi Engine: {str(e)}"}, ensure_ascii=False)
            yield f"data: {msg}\n\n"

    return StreamingResponse(event_generator(), media_type="text/event-stream")
