"""
DailyDigestGenerator

Generates daily summary of user's day including conversations, tasks, key memories.
Generated at 22:00 daily via scheduler.
"""

import json
from dataclasses import dataclass, field
from datetime import date, datetime, timedelta, UTC
from typing import Any

from sqlalchemy import select, and_
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.memory import MemorySummary, UserMemory
from app.models.task import Task


@dataclass
class DailyDigestData:
    """Daily digest data structure."""

    date: date
    summary: str
    key_points: list[dict] = field(default_factory=list)
    pending_questions: list[dict] = field(default_factory=list)
    suggestions: list[dict] = field(default_factory=list)


class DailyDigestGenerator:
    """Generate daily summary for a user."""

    MAX_KEY_POINTS = 5
    MAX_SUGGESTIONS = 3

    async def generate(
        self,
        db: AsyncSession,
        user_id: str,
        target_date: date | None = None,
    ) -> DailyDigestData:
        """Generate daily digest for user.

        1. Get today's conversation summaries
        2. Get high importance memories from today
        3. Get today's tasks
        4. Generate summary using LLM
        """
        if target_date is None:
            target_date = datetime.now(UTC).date()

        start_of_day = datetime.combine(target_date, datetime.min.time()).replace(tzinfo=UTC)
        end_of_day = datetime.combine(target_date, datetime.max.time()).replace(tzinfo=UTC)

        # 1. Get conversation summaries from today
        summaries = await self._get_today_summaries(db, user_id, start_of_day, end_of_day)

        # 2. Get high importance memories from today
        high_importance_memories = await self._get_high_importance_memories(
            db, user_id, start_of_day, end_of_day
        )

        # 3. Get today's tasks
        tasks = await self._get_today_tasks(db, user_id, start_of_day, end_of_day)

        # 4. Generate summary using LLM
        summary = await self._generate_summary(
            summaries=summaries,
            memories=high_importance_memories,
            tasks=tasks,
        )

        # 5. Extract key points
        key_points = self._extract_key_points(high_importance_memories, summaries, tasks)

        # 6. Generate suggestions
        suggestions = self._generate_suggestions(high_importance_memories, tasks)

        return DailyDigestData(
            date=target_date,
            summary=summary,
            key_points=key_points,
            pending_questions=[],  # Filled by LLM analysis
            suggestions=suggestions,
        )

    async def _get_today_summaries(
        self,
        db: AsyncSession,
        user_id: str,
        start: datetime,
        end: datetime,
    ) -> list[MemorySummary]:
        """Get conversation summaries from today."""
        result = await db.execute(
            select(MemorySummary)
            .where(
                MemorySummary.user_id == user_id,
                MemorySummary.summary_at >= start,
                MemorySummary.summary_at <= end,
            )
            .order_by(MemorySummary.summary_at.desc())
        )
        return list(result.scalars().all())

    async def _get_high_importance_memories(
        self,
        db: AsyncSession,
        user_id: str,
        start: datetime,
        end: datetime,
    ) -> list[UserMemory]:
        """Get high importance memories accessed or created today."""
        result = await db.execute(
            select(UserMemory)
            .where(
                UserMemory.user_id == user_id,
                UserMemory.importance_level == "high",
                ((UserMemory.last_accessed_at >= start) | (UserMemory.last_accessed_at.is_(None))),
            )
            .order_by(UserMemory.importance_score.desc())
            .limit(5)
        )
        return list(result.scalars().all())

    async def _get_today_tasks(
        self,
        db: AsyncSession,
        user_id: str,
        start: datetime,
        end: datetime,
    ) -> list[Task]:
        """Get tasks updated today."""
        result = await db.execute(
            select(Task)
            .where(
                Task.user_id == user_id,
                Task.updated_at >= start,
                Task.updated_at <= end,
            )
            .order_by(Task.priority.desc())
        )
        return list(result.scalars().all())

    async def _generate_summary(
        self,
        summaries: list[MemorySummary],
        memories: list[UserMemory],
        tasks: list[Task],
    ) -> str:
        """Generate daily summary text using LLM."""
        from app.services.llm_service import get_llm
        from langchain_core.messages import HumanMessage, SystemMessage

        summary_texts = "\n".join(f"- {s.summary_text}" for s in summaries)
        memory_texts = "\n".join(f"- [{m.memory_type}] {m.content}" for m in memories[:3])
        task_texts = "\n".join(f"- [{t.status}] {t.title}" for t in tasks[:5])

        prompt = f"""今天的主要活动摘要：

对话摘要：
{summary_texts or "无"}

高重要性记忆：
{memory_texts or "无"}

任务：
{task_texts or "无"}

请用1-2句话简洁总结今天的核心活动。不要过度发挥。"""
        try:
            llm = get_llm()
            response = await llm.invoke(
                [
                    SystemMessage(
                        content="你是一个记忆助手。请简洁总结用户今天的核心活动，不超过50字。"
                    ),
                    HumanMessage(content=prompt),
                ]
            )
            return response.content.strip()
        except Exception:
            # Fallback: count activities
            total = len(summaries) + len(memories) + len(tasks)
            if total == 0:
                return "今天没有明显的活动记录。"
            return f"今天共处理了 {total} 项活动（{len(summaries)} 次对话、{len(memories)} 条重要记忆、{len(tasks)} 个任务）。"

    def _extract_key_points(
        self,
        memories: list[UserMemory],
        summaries: list[MemorySummary],
        tasks: list[Task],
    ) -> list[dict]:
        """Extract key points from today's activities."""
        key_points = []

        for m in memories[: self.MAX_KEY_POINTS]:
            key_points.append(
                {
                    "content": m.content[:100],
                    "importance": m.importance_score or 0.5,
                    "source": "memory",
                }
            )

        for t in tasks[:3]:
            if len(key_points) >= self.MAX_KEY_POINTS:
                break
            key_points.append(
                {
                    "content": t.title,
                    "importance": t.priority / 10.0 if t.priority else 0.5,
                    "source": "task",
                }
            )

        key_points.sort(key=lambda x: x["importance"], reverse=True)
        return key_points[: self.MAX_KEY_POINTS]

    def _generate_suggestions(
        self,
        memories: list[UserMemory],
        tasks: list[Task],
    ) -> list[dict]:
        """Generate suggestions based on today's activities."""
        suggestions = []

        # Suggest following up on high importance memories
        for m in memories[:2]:
            if len(suggestions) >= self.MAX_SUGGESTIONS:
                break
            suggestions.append(
                {
                    "text": f"可以继续聊聊「{m.content[:20]}」相关的话题",
                    "reason": "这是你关心的高优先级话题",
                }
            )

        # Suggest incomplete high-priority tasks
        incomplete = [t for t in tasks if t.status != "done"]
        for t in incomplete[:2]:
            if len(suggestions) >= self.MAX_SUGGESTIONS:
                break
            suggestions.append(
                {
                    "text": f"继续推进：{t.title}",
                    "reason": "这是未完成的高优先级任务",
                }
            )

        return suggestions[: self.MAX_SUGGESTIONS]

    async def get_recent_digests(
        self,
        db: AsyncSession,
        user_id: str,
        limit: int = 7,
    ) -> list[DailyDigestData]:
        """Get recent digests (stored as JSON in user metadata or separate table)."""
        # For simplicity, return empty list - digests are stored separately
        # In production, would query a daily_digests table
        return []
