"""管理会计OS — 知识摘要模块

仿 OpenCode 的持久记忆机制（summarizer + SummaryMessageID），但做了三处改进：
1. 分层压缩（日→周→月→全部），不是一次性全量压缩
2. 结构化存储（MySQL 关系表），不是 SQLite JSON 消息
3. 保留版本链，不是覆盖式压缩

参考：OpenCode SummarizeProvider 的 prompt 框架 + CMA OperationLog 的审计日志
"""

from sqlalchemy import Column, Integer, String, Text, DateTime, JSON, ForeignKey, Float, func
from app.database import Base


class KnowledgeEvent(Base):
    """关键事件记录

    自动从 OperationLog 和其他数据源抽取的"值得记住"的事件。
    每个事件是一个结构化记录，包含类型、级别、关联对象、摘要描述。
    这是增量压缩的输入——摘要 agent 只处理"未摘要过"的新事件。
    """
    __tablename__ = "knowledge_events"

    id = Column(Integer, primary_key=True, index=True)
    event_type = Column(String(30), nullable=False, comment="事件类型: kpi_change/alert/decision/plan/map/import/user_action")
    event_level = Column(String(20), default="info", comment="info/warning/important/critical")
    source = Column(String(50), nullable=True, comment="来源: operation_log/api/erp_sync/manual")
    source_id = Column(Integer, nullable=True, comment="源记录ID（如 operation_log.id）")
    target_type = Column(String(50), nullable=True, comment="关联对象类型: kpi/map/budget/alert/plan")
    target_id = Column(Integer, nullable=True, comment="关联对象ID")
    title = Column(String(300), nullable=False, comment="事件标题（一句话概括）")
    description = Column(Text, nullable=True, comment="事件详细描述")
    delta = Column(JSON, nullable=True, comment="变更字段和前后值: {field: {old: X, new: Y}}")
    occurred_at = Column(DateTime, nullable=False, comment="事件发生时间")
    created_at = Column(DateTime, server_default=func.now())

    # 摘要追踪——记录该事件被哪些摘要（id列表）包含
    summarized_in = Column(JSON, nullable=True, comment="包含此事件的摘要ID列表")


class KnowledgeSummary(Base):
    """知识摘要

    分层存储：daily/weekly/monthly/cumulative
    参考 OpenCode 的 summary_message_id 机制，但用结构化字段代替 message 指针。
    """
    __tablename__ = "knowledge_summaries"

    id = Column(Integer, primary_key=True, index=True)
    level = Column(String(20), nullable=False, comment="摘要层级: daily/weekly/monthly/cumulative")
    period_key = Column(String(20), nullable=False, comment="期间标识: 2026-06-12 / 2026-W24 / 2026-06 / cumulative")
    title = Column(String(300), nullable=False, comment="摘要标题")
    content = Column(Text, nullable=False, comment="摘要正文（纯文本/Markdown）")
    event_ids = Column(JSON, nullable=True, comment="包含的事件ID列表")

    # 核心指标变化（精简提取，用于快速问答）
    kpi_changes = Column(JSON, nullable=True, comment="摘要期内的KPI变化统计: [{kpi_code, kpi_name, old_value, new_value, direction, alert_level}]")
    decision_points = Column(JSON, nullable=True, comment="决策点: [{time, action, actor, result}]")
    key_metrics = Column(JSON, nullable=True, comment="摘要期内的关键指标快照: {kpi_code: value}")

    # 元信息
    prev_summary_id = Column(Integer, nullable=True, comment="上一级摘要ID（如 daily→weekly 的链路）")
    next_compressed_by = Column(Integer, nullable=True, comment="被哪个更高层摘要包含")
    token_estimate = Column(Integer, default=0, comment="估算token数（用于触发压缩阈值判断）")

    model = Column(String(50), nullable=True, comment="生成摘要使用的模型名")
    generated_by = Column(String(100), nullable=True, comment="生成方式: auto_scheduler/manual_trigger")
    is_stale = Column(Integer, default=0, comment="0=最新 1=已被上层摘要覆盖")
    created_at = Column(DateTime, server_default=func.now())
