"""API 路由 — Mail Tab（v2.7）

Mail 是一个特殊的 Project (_mail)，每封 Mail 是一个两点 Task（from → to）。
显示为独立 Tab，list 形式展示：时间 | From | To | Title | 状态（已读/已执行）。
"""

from __future__ import annotations

import json
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, List, Optional

from fastapi import APIRouter, HTTPException, Query

from src.blackboard.db import init_db
from src.blackboard.models import Task
from src.blackboard.operations import Blackboard
from src.blackboard.queries import Queries
from src.utils import get_data_root

router = APIRouter(prefix="/api/mail", tags=["mail"])

MAIL_PROJECT_ID = "_mail"


def _db_path() -> Path:
    root = get_data_root()
    db = root / MAIL_PROJECT_ID / "blackboard.db"
    db.parent.mkdir(parents=True, exist_ok=True)
    init_db(db)
    return db


def _bb() -> Blackboard:
    return Blackboard(_db_path())


def _q() -> Queries:
    return Queries(_db_path())


def _mail_meta(task: Task) -> Dict[str, Any]:
    """从 Task 的 must_haves 字段解析 Mail 元数据"""
    if task.must_haves:
        try:
            return json.loads(task.must_haves)
        except (json.JSONDecodeError, TypeError):
            pass
    return {}


def _task_to_mail(task: Task) -> Dict[str, Any]:
    """Task → Mail JSON"""
    meta = _mail_meta(task)
    return {
        "id": task.id,
        "title": task.title,
        "from": meta.get("from", task.assigned_by),
        "to": task.assignee,
        "status": task.status,
        "type": meta.get("type", "inform"),
        "performative": meta.get("performative", "inform"),
        "is_read": meta.get("is_read", False),
        "created_at": task.created_at,
        "updated_at": task.updated_at,
        "description": task.description,
        "conversation_id": meta.get("conversation_id"),
        "in_reply_to": meta.get("in_reply_to"),
    }


@router.get("")
async def list_mail(
    status: Optional[str] = None,
    from_agent: Optional[str] = None,
    to_agent: Optional[str] = None,
    unread: Optional[bool] = None,
    limit: int = Query(50, le=200),
):
    """Mail 列表（按时间倒序）"""
    bb = _bb()
    tasks = bb.list_tasks(status=status, assignee=to_agent)

    mails = []
    for t in tasks:
        meta = _mail_meta(t)
        # from 过滤
        if from_agent and meta.get("from", t.assigned_by) != from_agent:
            continue
        # unread 过滤
        if unread is True and meta.get("is_read", False):
            continue
        mails.append(_task_to_mail(t))

    # 按时间倒序
    mails.sort(key=lambda m: m.get("created_at", ""), reverse=True)
    mails = mails[:limit]

    return {"mails": mails, "total": len(mails)}


@router.get("/agents/list")
async def list_mail_agents():
    """列出参与过 Mail 的所有 Agent（用于筛选）"""
    q = _q()
    conn = q._conn()
    try:
        senders = conn.execute(
            "SELECT DISTINCT assigned_by FROM tasks WHERE assigned_by IS NOT NULL"
        ).fetchall()
        receivers = conn.execute(
            "SELECT DISTINCT assignee FROM tasks WHERE assignee IS NOT NULL"
        ).fetchall()
        agents = list(set(
            [r["assigned_by"] for r in senders] +
            [r["assignee"] for r in receivers]
        ))
        agents.sort()
        return {"agents": agents}
    finally:
        conn.close()


@router.get("/summary")
async def mail_summary():
    """Mail 摘要（未读数、总数）"""
    bb = _bb()
    all_tasks = bb.list_tasks()

    total = len(all_tasks)
    unread = 0
    by_type: Dict[str, int] = {}

    for t in all_tasks:
        meta = _mail_meta(t)
        if not meta.get("is_read", False):
            unread += 1
        mtype = meta.get("type", "inform")
        by_type[mtype] = by_type.get(mtype, 0) + 1

    return {"total": total, "unread": unread, "by_type": by_type}


@router.get("/{mail_id}")
async def get_mail(mail_id: str):
    """Mail 详情"""
    bb = _bb()
    task = bb.get_task(mail_id)
    if not task:
        raise HTTPException(404, f"Mail not found: {mail_id}")

    result = _task_to_mail(task)
    # 附加 comments（用于对话线程）
    comments = bb.get_comments(mail_id)
    result["comments"] = [
        {
            "id": c.id,
            "author": c.author,
            "type": c.comment_type,
            "body": c.body,
            "created_at": c.created_at,
        }
        for c in comments
    ]
    return result


@router.post("")
async def send_mail(body: Dict[str, Any]):
    """发送 Mail（创建 Task）"""
    bb = _bb()

    mail_id = body.get("id", f"mail-{int(datetime.now().timestamp() * 1000)}")
    meta = {
        "from": body.get("from", "user"),
        "type": body.get("type", "text"),
        "performative": body.get("performative", "inform"),
        "is_read": False,
        "conversation_id": body.get("conversation_id"),
        "in_reply_to": body.get("in_reply_to"),
    }

    task = Task(
        id=mail_id,
        title=body.get("title", ""),
        description=body.get("text", body.get("description", "")),
        assignee=body.get("to"),
        assigned_by=body.get("from", "user"),
        must_haves=json.dumps(meta),
        task_type="mail",
        status="done" if body.get("type") == "inform" else "pending",
    )
    bb.create_task(task)
    return {"ok": True, "mail_id": task.id}


@router.patch("/{mail_id}")
async def update_mail(mail_id: str, body: Dict[str, Any]):
    """更新 Mail（标记已读/已执行）"""
    bb = _bb()
    task = bb.get_task(mail_id)
    if not task:
        raise HTTPException(404, f"Mail not found: {mail_id}")

    meta = _mail_meta(task)

    if "is_read" in body:
        meta["is_read"] = body["is_read"]

    if body.get("mark_executed"):
        meta["is_read"] = True
        if task.status not in ("done", "cancelled"):
            bb.update_task_status(mail_id, "done", agent="mail-api")

    bb.update_must_haves(mail_id, json.dumps(meta))

    return {"ok": True}
