"""
庫柏每日簡報(階段 4e)。

對單一使用者:把「今天該關注的事」整理成 200-300 字的簡報。

資料來源:
  - 我負責的任務:今天到期 / 已逾期 / 進行中
  - 最近 3 天 重要訊息(tag = 📢 公告 / 📌 決策)
  - 最近 7 天 會議的待辦,還沒轉成 task 的
  - 最近一場會議摘要(若有)

由 Claude(Sonnet)整理成自然語氣的早安簡報。
"""

import json
import logging
from datetime import date, datetime, timedelta, timezone
from uuid import UUID

import anthropic
from sqlalchemy import or_, select

from app.config import settings
from app.database import AsyncSessionLocal
from app.models.channel import Message
from app.models.meeting import Meeting, MeetingActionItem, MeetingSummary
from app.models.task import Task
from app.models.user import User


logger = logging.getLogger("coba.brief")


BRIEF_SYSTEM_PROMPT = """你是庫柏(Cooper),團隊的 AI 同事。
請依使用者本人的待辦、最近的重要訊息與會議摘要,整理一份「個人化的今日簡報」給他。

【風格】
- 繁體中文,親切但不肉麻
- 直接稱呼使用者顯示名稱
- 200-300 字之間
- 條列+短段落混用
- 開頭一句問候,中間整理重點,結尾給「今天該優先做的事」

【結構建議】
1. 一句溫暖問候 + 整體狀況(多忙 / 卡點)
2. ⚡ 今天到期 / 逾期任務(最多 3 個)
3. 📌 最近重要決策或公告
4. 🎙️ 最近會議結論(若有)
5. 🚀 庫柏建議今天優先處理什麼

【規則】
- 沒有資料的區塊就跳過,不要硬寫
- 不要列「我會幫你做 X」這種空話
- 講事實 + 一句你的觀察 / 建議
"""


async def _gather_context(user: User) -> dict:
    """蒐集 Claude 要看的所有資料(純 SQL 撈)。"""
    today = date.today()
    seven_days_ago = datetime.now(timezone.utc) - timedelta(days=7)
    three_days_ago = datetime.now(timezone.utc) - timedelta(days=3)

    async with AsyncSessionLocal() as db:
        # ① 我負責的任務:assignee=我 OR creator=我
        my_tasks_stmt = (
            select(Task)
            .where(
                Task.deleted_at.is_(None),
                Task.status.in_(["todo", "in_progress", "review"]),
                or_(Task.assignee_id == user.id, Task.created_by == user.id),
            )
            .order_by(Task.due_date.asc().nulls_last(), Task.priority.desc())
            .limit(20)
        )
        my_tasks = list((await db.execute(my_tasks_stmt)).scalars().all())
        due_today = [t for t in my_tasks if t.due_date == today]
        overdue = [t for t in my_tasks if t.due_date and t.due_date < today]
        in_progress = [t for t in my_tasks if t.status == "in_progress" and t not in due_today and t not in overdue]

        # ② 最近 3 天 公告 / 決策訊息
        important_msgs_stmt = (
            select(Message)
            .where(
                Message.deleted_at.is_(None),
                Message.created_at >= three_days_ago,
            )
            .order_by(Message.created_at.desc())
            .limit(50)
        )
        all_recent = list((await db.execute(important_msgs_stmt)).scalars().all())
        important = [
            m for m in all_recent
            if m.tags and any(("公告" in t or "決策" in t) for t in m.tags)
        ][:5]

        # ③ 最近 7 天我的 action items 還沒轉 task 的
        action_items_stmt = (
            select(MeetingActionItem)
            .where(
                MeetingActionItem.suggested_assignee_id == user.id,
                MeetingActionItem.converted_task_id.is_(None),
                MeetingActionItem.created_at >= seven_days_ago,
            )
        )
        my_action_items = list((await db.execute(action_items_stmt)).scalars().all())

        # ④ 最近一場會議的摘要
        latest_meeting_stmt = (
            select(Meeting, MeetingSummary)
            .join(MeetingSummary, MeetingSummary.meeting_id == Meeting.id)
            .where(Meeting.deleted_at.is_(None), Meeting.status == "completed")
            .order_by(Meeting.created_at.desc())
            .limit(1)
        )
        latest = (await db.execute(latest_meeting_stmt)).first()
        latest_meeting_summary = None
        if latest:
            mt, sm = latest
            latest_meeting_summary = {
                "title": mt.title,
                "summary": sm.executive_summary,
                "topics": sm.key_topics or [],
                "when": mt.created_at.isoformat() if mt.created_at else "",
            }

        return {
            "user_name": user.display_name,
            "today": today.isoformat(),
            "due_today": [{"title": t.title, "priority": t.priority} for t in due_today],
            "overdue": [{"title": t.title, "due": t.due_date.isoformat() if t.due_date else None, "priority": t.priority} for t in overdue],
            "in_progress": [{"title": t.title, "priority": t.priority} for t in in_progress[:5]],
            "important_messages": [
                {"content": m.content[:200], "tags": m.tags or [], "when": m.created_at.isoformat() if m.created_at else ""}
                for m in important
            ],
            "my_action_items_pending": [
                {"description": ai.description, "due": ai.suggested_due_date} for ai in my_action_items
            ],
            "latest_meeting": latest_meeting_summary,
        }


async def generate_daily_brief(user: User) -> dict:
    """產生簡報。回傳 {brief: 文字, context: 蒐集到的原始資料}。"""
    context = await _gather_context(user)

    # 沒設 API key 就用簡單版本(避免測試環境壞掉)
    if not settings.ANTHROPIC_API_KEY:
        return {
            "brief": (
                f"{user.display_name},早安!\n"
                f"(API key 未設,只能列原始資料)\n"
                f"今天到期任務:{len(context['due_today'])} 個,"
                f"逾期:{len(context['overdue'])} 個。"
            ),
            "context": context,
        }

    user_prompt = (
        f"以下是 {user.display_name}({user.role})今天 ({context['today']}) 的個人狀況資料,"
        f"請寫一份個人化的今日簡報給他:\n\n"
        f"{json.dumps(context, ensure_ascii=False, indent=2)}"
    )

    try:
        client = anthropic.AsyncAnthropic(api_key=settings.ANTHROPIC_API_KEY)
        response = await client.messages.create(
            model=settings.CLAUDE_MODEL_SONNET,
            max_tokens=800,
            system=BRIEF_SYSTEM_PROMPT,
            messages=[{"role": "user", "content": user_prompt}],
        )
        text = "".join(b.text for b in response.content if b.type == "text").strip()
        cost = (response.usage.input_tokens / 1_000_000) * 3.0 + (response.usage.output_tokens / 1_000_000) * 15.0
        logger.info(
            "簡報產出 user=%s tokens=%d/%d cost=US$%.4f",
            user.display_name, response.usage.input_tokens, response.usage.output_tokens, cost,
        )
        return {"brief": text, "context": context}
    except Exception as e:
        logger.exception("簡報產生失敗")
        return {
            "brief": f"(庫柏抽風了:{type(e).__name__})\n手動列出今天到期任務 {len(context['due_today'])} 個。",
            "context": context,
        }
