"""
FAQ Knowledge Base API
CRUD + AI variant generation for FAQ entries stored in SQLite.
"""
import logging
import uuid
from datetime import datetime, timezone
from typing import Optional

import httpx
from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel

from common.pool_wrapper import get_pooled_connection_compat

logger = logging.getLogger(__name__)
router = APIRouter()

# ── AI Config ──
from config import FREE_LLM_API_KEY, LITELLM_BASE_URL

AI_BASE_URL = f"{LITELLM_BASE_URL}/v1/chat/completions"
AI_API_KEY = FREE_LLM_API_KEY

# ── DB Setup ──
def _ensure_faqs_table():
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("""
                CREATE TABLE IF NOT EXISTS faqs (
                    id TEXT PRIMARY KEY,
                    question TEXT NOT NULL,
                    answer TEXT NOT NULL,
                    category TEXT DEFAULT 'chung',
                    is_variant INTEGER DEFAULT 0,
                    parent_id TEXT,
                    created_at TEXT
                )
            """)
    except Exception as e:
        logger.error(f"Error creating faqs table: {e}")

_ensure_faqs_table()

# ── Pydantic Models ──
class FaqItem(BaseModel):
    question: str
    answer: str
    category: str = "chung"

class GenerateVariantsRequest(BaseModel):
    faq_id: str
    count: int = 20

class BatchGenerateRequest(BaseModel):
    category: Optional[str] = None
    count_per_faq: int = 10

# ── CRUD ──
@router.get("/api/faqs", summary="List FAQs")
async def list_faqs(
    category: Optional[str] = None,
    search: Optional[str] = None,
    variants: bool = True,
    page: int = Query(1, ge=1),
    limit: int = Query(50, ge=1, le=500),
):
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            where, params = [], []
            if category:
                where.append("category = ?"); params.append(category)
            if search:
                where.append("question LIKE ?"); params.append(f"%{search}%")
            if not variants:
                where.append("is_variant = 0")
            clause = ("WHERE " + " AND ".join(where)) if where else ""
            cur.execute(f"SELECT COUNT(*) as cnt FROM faqs {clause}", params)
            total = cur.fetchone()["cnt"]
            offset = (page - 1) * limit
            cur.execute(f"""
                SELECT id, question, answer, category, is_variant, parent_id, created_at
                FROM faqs {clause} ORDER BY created_at DESC LIMIT ? OFFSET ?
            """, params + [limit, offset])
            rows = [dict(r) for r in cur.fetchall()]
            return {"faqs": rows, "total": total, "page": page, "limit": limit}
    except Exception as e:
        logger.error(f"Error listing faqs: {e}")
        raise HTTPException(500, "Database error")

@router.post("/api/faqs", summary="Create FAQ")
async def create_faq(item: FaqItem):
    faq_id = str(uuid.uuid4())[:8]
    now = datetime.now(tz=timezone.utc).isoformat()
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("""
                INSERT INTO faqs (id, question, answer, category, is_variant, parent_id, created_at)
                VALUES (?, ?, ?, ?, 0, NULL, ?)
            """, (faq_id, item.question, item.answer, item.category, now))
        return {"status": "success", "id": faq_id}
    except Exception as e:
        logger.error(f"Error creating faq: {e}")
        raise HTTPException(500, "Database error")

@router.put("/api/faqs/{faq_id}", summary="Update FAQ")
async def update_faq(faq_id: str, item: FaqItem):
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("UPDATE faqs SET question=?, answer=?, category=? WHERE id=?",
                        (item.question, item.answer, item.category, faq_id))
            if cur.rowcount == 0:
                raise HTTPException(404, "FAQ not found")
        return {"status": "success"}
    except HTTPException: raise
    except Exception as e:
        logger.error(f"Error updating faq: {e}")
        raise HTTPException(500, "Database error")

@router.delete("/api/faqs/{faq_id}", summary="Delete FAQ")
async def delete_faq(faq_id: str):
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("DELETE FROM faqs WHERE parent_id = ?", (faq_id,))
            cur.execute("DELETE FROM faqs WHERE id = ?", (faq_id,))
            if cur.rowcount == 0:
                raise HTTPException(404, "FAQ not found")
        return {"status": "success"}
    except HTTPException: raise
    except Exception as e:
        logger.error(f"Error deleting faq: {e}")
        raise HTTPException(500, "Database error")

# ── Stats ──
@router.get("/api/faqs/stats", summary="FAQ statistics")
async def faq_stats():
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("SELECT COUNT(*) as total FROM faqs")
            total = cur.fetchone()["total"]
            cur.execute("SELECT COUNT(*) as cnt FROM faqs WHERE is_variant = 0")
            originals = cur.fetchone()["cnt"]
            cur.execute("SELECT category, COUNT(*) as cnt FROM faqs GROUP BY category ORDER BY cnt DESC")
            by_cat = [dict(r) for r in cur.fetchall()]
            return {"total": total, "originals": originals, "variants": total - originals, "by_category": by_cat}
    except Exception as e:
        logger.error(f"Error getting faq stats: {e}")
        raise HTTPException(500, "Database error")

# ── AI Variant Generation ──
async def _call_ai(prompt: str) -> str:
    async with httpx.AsyncClient(timeout=60) as client:
        resp = await client.post(AI_BASE_URL, json={
            "model": "gpt-4.1-mini",
            "messages": [{"role": "user", "content": prompt}],
            "temperature": 0.8,
        }, headers={"Authorization": f"Bearer {AI_API_KEY}"})
        resp.raise_for_status()
        return resp.json()["choices"][0]["message"]["content"]

@router.post("/api/faqs/generate-variants", summary="AI generate question variants")
async def generate_variants(req: GenerateVariantsRequest):
    conn = get_pooled_connection_compat()
    with conn.cursor() as cur:
        cur.execute("SELECT id, question, answer, category FROM faqs WHERE id = ?", (req.faq_id,))
        faq = cur.fetchone()
        if not faq:
            raise HTTPException(404, "FAQ not found")

    prompt = f"""Bạn là chuyên gia ngôn ngữ. Từ câu hỏi gốc dưới đây, hãy sinh ra {req.count} biến thể câu hỏi khác nhau mà khách hàng Canifa có thể hỏi. 
Mỗi biến thể trên 1 dòng, không đánh số, không giải thích thêm.
Yêu cầu: đa dạng phong cách (formal, casual, viết tắt, có typo nhẹ, dùng emoji), giữ nguyên ý nghĩa.

Câu hỏi gốc: {faq['question']}
Danh mục: {faq['category']}"""

    try:
        result = await _call_ai(prompt)
        variants = [line.strip() for line in result.strip().split("\n") if line.strip() and len(line.strip()) > 5]
        now = datetime.now(tz=timezone.utc).isoformat()
        inserted = 0
        conn2 = get_pooled_connection_compat()
        with conn2.cursor() as cur2:
            for v in variants:
                vid = str(uuid.uuid4())[:8]
                cur2.execute("""
                    INSERT INTO faqs (id, question, answer, category, is_variant, parent_id, created_at)
                    VALUES (?, ?, ?, ?, 1, ?, ?)
                """, (vid, v, faq["answer"], faq["category"], faq["id"], now))
                inserted += 1
        return {"status": "success", "inserted": inserted, "variants": variants}
    except Exception as e:
        logger.error(f"Error generating variants: {e}")
        raise HTTPException(500, f"AI generation error: {str(e)}")

@router.post("/api/faqs/batch-generate", summary="Batch generate variants for all originals")
async def batch_generate(req: BatchGenerateRequest):
    conn = get_pooled_connection_compat()
    with conn.cursor() as cur:
        where = "WHERE is_variant = 0"
        params = []
        if req.category:
            where += " AND category = ?"
            params.append(req.category)
        cur.execute(f"SELECT id, question, answer, category FROM faqs {where}", params)
        originals = [dict(r) for r in cur.fetchall()]

    total_inserted = 0
    errors = []
    for faq in originals:
        try:
            prompt = f"""Sinh ra {req.count_per_faq} biến thể câu hỏi từ: "{faq['question']}"
Mỗi biến thể 1 dòng, không đánh số. Đa dạng phong cách."""
            result = await _call_ai(prompt)
            variants = [l.strip() for l in result.strip().split("\n") if l.strip() and len(l.strip()) > 5]
            now = datetime.now(tz=timezone.utc).isoformat()
            conn2 = get_pooled_connection_compat()
            with conn2.cursor() as cur2:
                for v in variants:
                    vid = str(uuid.uuid4())[:8]
                    cur2.execute("""
                        INSERT INTO faqs (id, question, answer, category, is_variant, parent_id, created_at)
                        VALUES (?, ?, ?, ?, 1, ?, ?)
                    """, (vid, v, faq["answer"], faq["category"], faq["id"], now))
                    total_inserted += 1
        except Exception as e:
            errors.append({"faq_id": faq["id"], "error": str(e)})

    return {"status": "success", "originals_processed": len(originals), "total_variants_inserted": total_inserted, "errors": errors}

# ── Simulator Match ──
class SimulateMatchRequest(BaseModel):
    query: str

@router.post("/api/faqs/simulate-match", summary="Simulate User Search matching FAQs")
async def simulate_match_endpoint(req: SimulateMatchRequest):
    import time

    from common.match_algo import find_best_matches
    
    start_t = time.time()
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("SELECT id, question, answer, category, is_variant FROM faqs")
            rows = cur.fetchall()
            
        faq_list = []
        for r in rows:
            faq_list.append({
                "id": r["id"],
                "question": r["question"],
                "answer": r["answer"],
                "category": r["category"],
                "is_variant": r["is_variant"]
            })
            
        matches = find_best_matches(req.query, faq_list, top_k=3)
        elapsed_ms = int((time.time() - start_t) * 1000)
        
        return {
            "query": req.query,
            "matches": matches,
            "elapsed_ms": elapsed_ms
        }
    except Exception as e:
        logger.error(f"Error in simulate-match: {e}")
        raise HTTPException(500, str(e))
