"""
用户记忆管理 — 单机版重构
- 用户记忆：直接显示文档内容（基础信息 + AI偏好），不显示列表
- 案件记忆：按案件显示记忆内容
"""

import os
import json
import logging
from pathlib import Path
from fastapi import APIRouter, Depends, Query, Request, HTTPException
from pydantic import BaseModel
from typing import Optional
from ...core.database import get_db
from ...core.permission import require_login
from ...utils.request_utils import safe_json

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

# ── 数据模型 ──

class UserBasicInfo(BaseModel):
    """用户基础信息"""
    name: str = ""
    badge_no: str = ""          # 执法证号
    phone: str = ""              # 手机号
    area: str = ""               # 区域
    org_name: str = ""           # 单位名称
    org_phone: str = ""          # 单位联系电话
    org_address: str = ""        # 单位联系地址


class UserMemoryData(BaseModel):
    """完整的用户记忆数据"""
    basic_info: UserBasicInfo = UserBasicInfo()
    ai_preferences: str = ""     # AI聊天中提取的用户偏好/要求（Markdown 格式）


class UserMemoryUpdate(BaseModel):
    """用户记忆更新请求"""
    basic_info: Optional[UserBasicInfo] = None
    ai_preferences: Optional[str] = None


# ── 用户记忆：直接返回结构化内容（无列表）──

@router.get("/user")
async def get_user_memory(
    request: Request,
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """
    获取用户记忆（单机版：直接返回内容，非列表）
    返回结构：{ basic_info: {...}, ai_preferences: "..." }
    """
    conn, cur = db
    user_id = user.get("userId", "default-user")

    # 默认值
    result = UserMemoryData().dict()

    # 优先从数据库 user_memories 表读取
    try:
        await cur.execute(
            "SELECT content FROM user_memories WHERE user_id = ? AND memory_type = 'user_profile'",
            (user_id,),
        )
        row = await cur.fetchone()
        if row and row["content"]:
            saved = json.loads(row["content"])
            result.update(saved)
    except Exception as e:
        logger.warning(f"读取用户记忆失败: {e}")

    # 兼容旧格式：从文件读取
    if not result.get("basic_info", {}).get("name"):
        base = os.getenv("MEMORIES_DIR", "./data/memories")
        file_path = Path(base) / "users" / f"{user_id}.md"
        if file_path.exists():
            try:
                content = file_path.read_text(encoding="utf-8")
                result["ai_preferences"] = content
            except OSError:
                pass

    return {"success": True, "data": result}


@router.put("/user")
async def update_user_memory(
    request: Request,
    body: UserMemoryUpdate,
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """更新用户记忆（基础信息 或 AI偏好）"""
    conn, cur = db
    user_id = user.get("userId", "default-user")

    # 先读取现有数据
    existing = UserMemoryData().dict()
    try:
        await cur.execute(
            "SELECT content FROM user_memories WHERE user_id = ? AND memory_type = 'user_profile'",
            (user_id,),
        )
        row = await cur.fetchone()
        if row and row["content"]:
            saved = json.loads(row["content"])
            existing.update(saved)
    except Exception:
        pass

    # 合并更新
    if body.basic_info is not None:
        existing["basic_info"] = body.basic_info.dict()
    if body.ai_preferences is not None:
        existing["ai_preferences"] = body.ai_preferences

    # 保存到数据库
    content_json = json.dumps(existing, ensure_ascii=False)
    try:
        await cur.execute(
            "SELECT id FROM user_memories WHERE user_id = ? AND memory_type = 'user_profile'",
            (user_id,),
        )
        exists = await cur.fetchone()

        if exists:
            await cur.execute(
                "UPDATE user_memories SET content = ?, updated_at = datetime('now') WHERE user_id = ? AND memory_type = 'user_profile'",
                (content_json, user_id),
            )
        else:
            await cur.execute(
                "INSERT INTO user_memories (user_id, memory_type, content, created_at, updated_at) VALUES (?, 'user_profile', ?, datetime('now'), datetime('now'))",
                (user_id, content_json),
            )

        # 同时写入 memory_history
        await cur.execute(
            "INSERT INTO memory_history (memory_type, target_id, memory_content, changed_by, change_reason, created_at) "
            "VALUES ('user_profile', ?, ?, ?, '用户编辑', datetime('now'))",
            (user_id, json.dumps({"content": content_json[:500]}, ensure_ascii=False), user_id),
        )
        await conn.commit()
    except Exception as e:
        logger.error(f"保存用户记忆失败: {e}")
        raise HTTPException(status_code=500, detail=f"保存失败: {e}")

    return {"success": True, "data": existing}


# ── 案件记忆 ──

@router.get("/cases")
async def get_case_memories(
    request: Request,
    page: int = Query(1, ge=1),
    pageSize: int = Query(20, ge=1, le=100),
    keyword: str = Query(""),
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """
    获取案件记忆列表
    单机版：返回有记忆内容的案件列表，每个案件包含记忆内容摘要
    """
    conn, cur = db
    user_id = user.get("userId", "default-user")

    where = "WHERE cm.user_id = ? AND cm.is_archived = 0"
    params = [user_id]

    if keyword:
        where += " AND (cm.title LIKE ? OR cm.content LIKE ?)"
        params.extend([f"%{keyword}%", f"%{keyword}%"])

    offset = (page - 1) * pageSize

    try:
        await cur.execute(f"SELECT COUNT(*) as total FROM conversation_memories cm {where}", params)
        count_row = await cur.fetchone()
        total = dict(count_row)["total"]

        await cur.execute(
            f"""SELECT cm.id, cm.thread_id, cm.case_id, cm.agent_type, cm.title,
                       cm.content, cm.message_count, cm.token_count,
                       cm.is_compressed, cm.file_path, cm.created_at, cm.updated_at
                FROM conversation_memories cm {where}
                ORDER BY cm.updated_at DESC
                LIMIT ? OFFSET ?""",
            params + [pageSize, offset],
        )
        rows = await cur.fetchall()
        items = [dict(r) for r in rows]

        return {"success": True, "data": {"list": items, "total": total, "page": page, "pageSize": pageSize}}
    except Exception as e:
        logger.error(f"查询案件记忆失败: {e}")
        return {"success": False, "data": {"list": [], "total": 0}, "error": str(e)}


@router.get("/case/{case_id}")
async def get_case_memory_detail(
    request: Request,
    case_id: str,
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """获取单个案件的详细记忆内容"""
    from ...services.case_memory_service import case_memory_service
    content = await case_memory_service.get_case_memory(case_id, db)
    return {"success": True, "data": {"content": content or "", "case_id": case_id}}


@router.put("/case/{case_id}")
async def update_case_memory_content(
    request: Request,
    case_id: str,
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """更新案件记忆内容"""
    body = await safe_json(request)
    content = body.get("content", "")
    user_id = user.get("userId", "")
    from ...services.case_memory_service import case_memory_service
    result = await case_memory_service.create_or_update_case_memory(case_id, content, db)
    return {"success": True, "case_id": case_id, "result": result}


# ── 保留原有路由（兼容）──

@router.get("")
async def list_memories(
    request: Request,
    page: int = Query(1, ge=1),
    pageSize: int = Query(20, ge=1, le=100),
    keyword: str = Query(""),
    user: dict = Depends(require_login),
    db=Depends(get_db),
):
    """记忆列表（兼容旧接口，建议使用 /user 和 /cases）"""
    conn, cur = db
    user_id = user.get("userId", "1")

    try:
        user_id = int(user_id) if str(user_id).isdigit() else 1
    except (ValueError, TypeError):
        user_id = 1

    where = "WHERE cm.user_id = ? AND cm.is_archived = 0"
    params = [user_id]

    if keyword:
        where += " AND (cm.title LIKE ? OR cm.content LIKE ?)"
        params.extend([f"%{keyword}%", f"%{keyword}%"])

    offset = (page - 1) * pageSize

    try:
        await cur.execute(f"SELECT COUNT(*) as total FROM conversation_memories cm {where}", params)
        count_row = await cur.fetchone()
        total = dict(count_row)["total"]

        await cur.execute(
            f"""SELECT cm.id, cm.thread_id, cm.case_id, cm.agent_type, cm.title,
                       cm.content, cm.message_count, cm.token_count,
                       cm.is_compressed, cm.file_path, cm.created_at, cm.updated_at
                FROM conversation_memories cm {where}
                ORDER BY cm.updated_at DESC
                LIMIT ? OFFSET ?""",
            params + [pageSize, offset],
        )
        rows = await cur.fetchall()
        items = [dict(r) for r in rows]

        return {"list": items, "total": total, "page": page, "pageSize": pageSize}
    except Exception as e:
        return {"error": "查询记忆失败", "detail": str(e), "list": [], "total": 0}


@router.get("/me")
async def get_my_memory(request: Request, user: dict = Depends(require_login), db=Depends(get_db)):
    """获取我的原始记忆内容（兼容）"""
    conn, cur = db
    user_id = user.get("userId", "")

    content = ""
    base = os.getenv("MEMORIES_DIR", "./data/memories")
    file_path = Path(base) / "users" / f"{user_id}.md"
    if file_path.exists():
        try:
            content = file_path.read_text(encoding="utf-8")
        except OSError:
            pass

    if not content:
        try:
            await cur.execute(
                "SELECT content FROM user_memories WHERE user_id = ? AND memory_type = 'user'",
                (user_id,),
            )
            row = await cur.fetchone()
            if row and row["content"]:
                content = row["content"]
        except Exception:
            pass

    return {"content": content, "user_id": user_id}


@router.put("/me")
async def update_my_memory(request: Request, user: dict = Depends(require_login), db=Depends(get_db)):
    """更新我的原始记忆内容（兼容）"""
    conn, cur = db
    body = await safe_json(request)
    content = body.get("content", "")
    user_id = user.get("userId", "")

    base = os.getenv("MEMORIES_DIR", "./data/memories")
    file_path = Path(base) / "users" / f"{user_id}.md"
    try:
        file_path.parent.mkdir(parents=True, exist_ok=True)
        file_path.write_text(content, encoding="utf-8")
    except OSError:
        pass

    try:
        await cur.execute(
            "SELECT id FROM user_memories WHERE user_id = ? AND memory_type = 'user'",
            (user_id,),
        )
        exists = await cur.fetchone()

        if exists:
            await cur.execute(
                "UPDATE user_memories SET content = ?, updated_at = datetime('now') WHERE user_id = ? AND memory_type = 'user'",
                (content, user_id),
            )
        else:
            await cur.execute(
                "INSERT INTO user_memories (user_id, memory_type, content, created_at, updated_at) VALUES (?, 'user', ?, datetime('now'), datetime('now'))",
                (user_id, content),
            )

        await cur.execute(
            "INSERT INTO memory_history (memory_type, target_id, memory_content, changed_by, change_reason, created_at) "
            "VALUES ('user', ?, ?, ?, '用户编辑', datetime('now'))",
            (user_id, json.dumps({"content": content[:500]}), user_id),
        )
        await conn.commit()
    except Exception:
        pass

    return {"success": True}


@router.get("/complaint/{complaint_id}")
async def get_complaint_memory(request: Request, complaint_id: str, user: dict = Depends(require_login), db=Depends(get_db)):
    from ...services.complaint_memory_service import complaint_memory_service
    content = await complaint_memory_service.get_complaint_memory(complaint_id, db)
    return {"content": content or "", "complaint_id": complaint_id}


@router.put("/complaint/{complaint_id}")
async def update_complaint_memory(request: Request, complaint_id: str, user: dict = Depends(require_login), db=Depends(get_db)):
    body = await safe_json(request)
    content = body.get("content", "")
    user_id = user.get("userId", "")
    from ...services.complaint_memory_service import complaint_memory_service
    result = await complaint_memory_service.update_complaint_memory_content(complaint_id, user_id, content, db)
    return result


@router.get("/{memory_id}")
async def get_memory(request: Request, memory_id: int, user: dict = Depends(require_login), db=Depends(get_db)):
    conn, cur = db
    user_id = user.get("userId", "1")

    try:
        await cur.execute(
            "SELECT * FROM conversation_memories WHERE id = ? AND user_id = ?",
            (memory_id, user_id),
        )
        row = await cur.fetchone()
        if not row:
            return {"error": "记忆不存在", "detail": "memory not found"}
        return dict(row)
    except Exception as e:
        return {"error": "查询失败", "detail": str(e)}
