from fastapi import APIRouter, Depends, Query, Request
from ...core.database import get_db
from ...core.permission import require_login
from ...core.config import settings
import httpx
import json

router = APIRouter()

QDRANT_HOST = getattr(settings, "QDRANT_HOST", "localhost")
QDRANT_PORT = getattr(settings, "QDRANT_PORT", "6334")
GRAPHITI_SERVER_URL = getattr(settings, "GRAPHITI_BASE_URL", "http://localhost:2082")


@router.get("/search/suggest")
async def search_suggest(
    request: Request,
    q: str = Query("", min_length=1),
    limit: int = Query(10, ge=1, le=20),
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """搜索联想/自动补全"""
    if not q:
        return {"suggestions": []}

    conn, cur = db
    try:
        await cur.execute(
            """SELECT p.id, p.title, d.name as category
               FROM wiki_pages p
               LEFT JOIN wiki_directories d ON p.directory_id = d.id
               WHERE p.is_published = 1
               AND (p.title LIKE %s OR p.slug LIKE %s)
               ORDER BY p.view_count DESC, p.updated_at DESC
               LIMIT %s""",
            (f"%{q}%", f"%{q}%", limit),
        )
        rows = await cur.fetchall()

        suggestions = []
        for row in rows:
            suggestions.append({
                "id": row["id"],
                "title": row["title"],
                "category": dict(row).get("category", ""),
                "type": "wiki_page",
            })

        return {"success": True, "suggestions": suggestions}
    except Exception as e:
        return {"error": f"获取搜索建议失败: {str(e)}"}


@router.get("/detail/{point_id}")
async def knowledge_detail(
    request: Request,
    point_id: str,
    collection: str = Query("market_regulation_laws"),
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """内容详情页（统一模板）"""
    try:
        async with httpx.AsyncClient(timeout=15) as client:
            res = await client.post(
                f"http://{QDRANT_HOST}:{QDRANT_PORT}/collections/{collection}/points",
                json={"ids": [point_id], "with_payload": True, "with_vector": False},
            )
            if res.status_code != 200:
                return {"error": f"获取详情失败: HTTP {res.status_code}"}

            points = res.json().get("result", [])
            if not points:
                return {"error": "内容不存在"}

            point = points[0]
            payload = point.get("payload", {})

            # 构建详情数据
            detail = {
                "id": point_id,
                "collection": collection,
                "title": payload.get("title", ""),
                "content": payload.get("content", ""),
                "category": payload.get("category", ""),
                "region": payload.get("region", ""),
                "status": payload.get("status", ""),
                "effective_date": payload.get("effective_date", ""),
                "issuer": payload.get("issuer", ""),
                "article_num": payload.get("article_num", ""),
                "law_name": payload.get("law_name", ""),
                "chunk_index": payload.get("chunk_index", 0),
                "related_law_ids": payload.get("related_law_ids", []),
                "related_discretion_ids": payload.get("related_discretion_ids", []),
                "related_case_ids": payload.get("related_case_ids", []),
                "related_exemption_ids": payload.get("related_exemption_ids", []),
            }

            return {"success": True, "data": detail}
    except Exception as e:
        return {"error": f"获取详情失败: {str(e)}"}


@router.get("/related/{point_id}")
async def knowledge_related(
    request: Request,
    point_id: str,
    collection: str = Query("market_regulation_laws"),
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """关联信息（裁量/案例/不罚）"""
    try:
        async with httpx.AsyncClient(timeout=15) as client:
            res = await client.post(
                f"http://{QDRANT_HOST}:{QDRANT_PORT}/collections/{collection}/points",
                json={"ids": [point_id], "with_payload": True, "with_vector": False},
            )
            if res.status_code != 200:
                return {"error": f"获取关联信息失败: HTTP {res.status_code}"}

            points = res.json().get("result", [])
            if not points:
                return {"error": "内容不存在"}

            payload = points[0].get("payload", {})
            result = {
                "discretion": [],
                "cases": [],
                "exemptions": [],
            }

            # 查询关联裁量基准
            related_discretion_ids = payload.get("related_discretion_ids", [])
            if related_discretion_ids:
                # 从 Qdrant 的 discretion_standards 集合查询
                try:
                    disc_res = await client.post(
                        f"http://{QDRANT_HOST}:{QDRANT_PORT}/collections/discretion_standards/points",
                        json={"ids": related_discretion_ids, "with_payload": True, "with_vector": False},
                    )
                    if disc_res.status_code == 200:
                        for p in disc_res.json().get("result", []):
                            dp = p.get("payload", {})
                            result["discretion"].append({
                                "id": p.get("id"),
                                "title": dp.get("title", ""),
                                "region": dp.get("region", ""),
                                "excerpt": dp.get("content", "")[:200],
                            })
                except Exception:
                    pass

            # 查询关联案例
            related_case_ids = payload.get("related_case_ids", [])
            if related_case_ids:
                try:
                    case_res = await client.post(
                        f"http://{QDRANT_HOST}:{QDRANT_PORT}/collections/case_precedents/points",
                        json={"ids": related_case_ids, "with_payload": True, "with_vector": False},
                    )
                    if case_res.status_code == 200:
                        for p in case_res.json().get("result", []):
                            cp = p.get("payload", {})
                            result["cases"].append({
                                "id": p.get("id"),
                                "title": cp.get("title", ""),
                                "region": cp.get("region", ""),
                                "excerpt": cp.get("content", "")[:200],
                            })
                except Exception:
                    pass

            # 查询关联不罚清单
            related_exemption_ids = payload.get("related_exemption_ids", [])
            if related_exemption_ids:
                try:
                    exemp_res = await client.post(
                        f"http://{QDRANT_HOST}:{QDRANT_PORT}/collections/exemption_lists/points",
                        json={"ids": related_exemption_ids, "with_payload": True, "with_vector": False},
                    )
                    if exemp_res.status_code == 200:
                        for p in exemp_res.json().get("result", []):
                            ep = p.get("payload", {})
                            result["exemptions"].append({
                                "id": p.get("id"),
                                "title": ep.get("title", ""),
                                "region": ep.get("region", ""),
                                "excerpt": ep.get("content", "")[:200],
                            })
                except Exception:
                    pass

            return {"success": True, "data": result}
    except Exception as e:
        return {"error": f"获取关联信息失败: {str(e)}"}


@router.get("/context/{point_id}")
async def knowledge_context(
    request: Request,
    point_id: str,
    collection: str = Query("market_regulation_laws"),
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """上下文法条导航（前后条）"""
    try:
        async with httpx.AsyncClient(timeout=15) as client:
            # 获取当前 point 的 chunk_index
            res = await client.post(
                f"http://{QDRANT_HOST}:{QDRANT_PORT}/collections/{collection}/points",
                json={"ids": [point_id], "with_payload": True, "with_vector": False},
            )
            if res.status_code != 200:
                return {"error": f"获取上下文失败: HTTP {res.status_code}"}

            points = res.json().get("result", [])
            if not points:
                return {"error": "内容不存在"}

            payload = points[0].get("payload", {})
            current_index = payload.get("chunk_index", 0)
            law_name = payload.get("law_name", "")

            result = {"current": {"id": point_id, "title": payload.get("title", ""), "article_num": payload.get("article_num", "")}}

            # 查询前一条
            if current_index > 0:
                try:
                    prev_res = await client.post(
                        f"http://{QDRANT_HOST}:{QDRANT_PORT}/collections/{collection}/points/scroll",
                        json={
                            "filter": {
                                "must": [
                                    {"key": "chunk_index", "match": {"value": current_index - 1}},
                                    {"key": "law_name", "match": {"value": law_name}} if law_name else {},
                                ]
                            },
                            "limit": 1,
                            "with_payload": True,
                        },
                    )
                    if prev_res.status_code == 200:
                        prev_points = prev_res.json().get("result", [])
                        if prev_points:
                            pp = prev_points[0]
                            result["previous"] = {
                                "id": pp.get("id"),
                                "title": pp.get("payload", {}).get("title", ""),
                                "article_num": pp.get("payload", {}).get("article_num", ""),
                            }
                except Exception:
                    pass

            # 查询后一条
            try:
                next_res = await client.post(
                    f"http://{QDRANT_HOST}:{QDRANT_PORT}/collections/{collection}/points/scroll",
                    json={
                        "filter": {
                            "must": [
                                {"key": "chunk_index", "match": {"value": current_index + 1}},
                                {"key": "law_name", "match": {"value": law_name}} if law_name else {},
                            ]
                        },
                        "limit": 1,
                        "with_payload": True,
                    },
                )
                if next_res.status_code == 200:
                    next_points = next_res.json().get("result", [])
                    if next_points:
                        np = next_points[0]
                        result["next"] = {
                            "id": np.get("id"),
                            "title": np.get("payload", {}).get("title", ""),
                            "article_num": np.get("payload", {}).get("article_num", ""),
                        }
            except Exception:
                pass

            return {"success": True, "data": result}
    except Exception as e:
        return {"error": f"获取上下文失败: {str(e)}"}


@router.get("/relation-chain/{point_id}")
async def knowledge_relation_chain(
    request: Request,
    point_id: str,
    collection: str = Query("market_regulation_laws"),
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """关联关系文本链"""
    try:
        # 先获取当前法条信息
        async with httpx.AsyncClient(timeout=15) as client:
            res = await client.post(
                f"http://{QDRANT_HOST}:{QDRANT_PORT}/collections/{collection}/points",
                json={"ids": [point_id], "with_payload": True, "with_vector": False},
            )
            if res.status_code != 200:
                return {"error": f"获取关系链失败: HTTP {res.status_code}"}

            points = res.json().get("result", [])
            if not points:
                return {"error": "内容不存在"}

            payload = points[0].get("payload", {})
            article_title = payload.get("title", "")
            law_name = payload.get("law_name", "")

            # 通过 Graphiti 查询关系链
            chain = []
            try:
                cypher = """
                    MATCH (a:Article {name: $article_name})<-[:VIOLATES]-(v:Violation)
                    OPTIONAL MATCH (a)-[:PENALIZES]->(p:Penalty)
                    RETURN v.name as violation, a.name as article, p.name as penalty
                    LIMIT 5
                """
                graph_res = await client.post(
                    f"{GRAPHITI_SERVER_URL}/api/knowledge-graph/query",
                    json={"query": cypher, "params": {"article_name": article_title}},
                )
                if graph_res.status_code == 200:
                    records = graph_res.json().get("result", [])
                    for r in records:
                        chain.append({
                            "violation": r.get("violation", ""),
                            "article": r.get("article", ""),
                            "penalty": r.get("penalty", ""),
                        })
            except Exception:
                pass

            return {
                "success": True,
                "data": {
                    "current_article": article_title,
                    "law_name": law_name,
                    "chain": chain,
                }
            }
    except Exception as e:
        return {"error": f"获取关系链失败: {str(e)}"}


@router.get("/hot")
async def hot_searches(
    request: Request,
    limit: int = Query(10, ge=1, le=20),
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """热门搜索推荐"""
    conn, cur = db
    try:
        # 查询搜索日志统计（如果存在 search_logs 表）
        try:
            await cur.execute(
                """SELECT query, COUNT(*) as cnt
                   FROM search_logs
                   WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
                   GROUP BY query
                   ORDER BY cnt DESC
                   LIMIT %s""",
                (limit,),
            )
            rows = await cur.fetchall()
            if rows:
                return {
                    "success": True,
                    "hot_searches": [{"query": r["query"], "count": r["cnt"]} for r in rows],
                }
        except Exception:
            pass

        # 如果没有搜索日志表，返回默认热门搜索
        default_hot = [
            {"query": "食品安全法", "count": 0},
            {"query": "轻微违法行为免罚", "count": 0},
            {"query": "行政处罚裁量基准", "count": 0},
            {"query": "消费者权益保护法", "count": 0},
            {"query": "无证经营处罚", "count": 0},
        ]
        return {"success": True, "hot_searches": default_hot[:limit]}
    except Exception as e:
        return {"error": f"获取热门搜索失败: {str(e)}"}


@router.get("/history")
async def get_view_history(
    request: Request,
    limit: int = Query(20, ge=1, le=50),
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """用户最近查看历史"""
    user_id = str(user.get("userId", "1"))
    conn, cur = db
    try:
        await cur.execute(
            """SELECT id, point_id, collection, title, doc_path, view_count, viewed_at
               FROM knowledge_view_history
               WHERE user_id = ?
               ORDER BY view_count DESC, viewed_at DESC
               LIMIT ?""",
            (user_id, limit),
        )
        rows = await cur.fetchall()

        history = []
        for row in rows:
            r = dict(row)
            history.append({
                "id": r["point_id"],
                "collection": r["collection"],
                "title": r["title"],
                "docPath": r.get("doc_path") or f"/knowledge/lib",
                "viewCount": r.get("view_count", 1),
                "viewed_at": str(r["viewed_at"]) if r["viewed_at"] else None,
            })

        return {"success": True, "history": history}
    except Exception as e:
        # 表可能不存在
        return {"success": True, "history": [], "note": "查看历史功能未启用"}


@router.post("/history")
async def record_view_history(
    request: Request,
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """记录查看历史（SQLite 原生语法，避免 ON DUPLICATE KEY UPDATE 兼容问题）"""
    user_id = str(user.get("userId", "1"))
    conn, cur = db
    try:
        body = await request.json()
        point_id = body.get("point_id")
        collection = body.get("collection", "markdown_docs")
        title = body.get("title", "")
        doc_path = body.get("doc_path", "")

        if not point_id:
            return {"error": "缺少 point_id"}

        # 先尝试更新已有记录
        await cur.execute(
            """UPDATE knowledge_view_history
               SET viewed_at = datetime('now', 'localtime'),
                   title = ?,
                   doc_path = COALESCE(?, doc_path),
                   view_count = view_count + 1
               WHERE user_id = ? AND point_id = ?""",
            (title, doc_path or None, user_id, point_id),
        )
        if cur.rowcount == 0:
            # 不存在则插入新记录
            await cur.execute(
                """INSERT INTO knowledge_view_history
                   (user_id, point_id, collection, title, doc_path, view_count, viewed_at)
                   VALUES (?, ?, ?, ?, ?, 1, datetime('now', 'localtime'))""",
                (user_id, point_id, collection, title, doc_path or None),
            )
        await conn.commit()

        return {"success": True, "message": "已记录查看历史"}
    except Exception as e:
        return {"success": False, "message": "记录失败", "error": str(e)}
