from __future__ import annotations

import json
from datetime import datetime, timedelta, timezone
from typing import Any

from sqlalchemy import func, select
from sqlalchemy.orm import Session

from app.core.logging import get_logger
from app.models.financial_record import ExpenseClaim
from app.services.runtime_chat import RuntimeChatService

logger = get_logger("app.services.hermes_expense_report")


class HermesExpenseReportService:
    def __init__(self, db: Session) -> None:
        self.db = db
        self.chat_service = RuntimeChatService(db)

    def generate_weekly_report(self, log_id: str | None = None) -> None:
        logger.info("Starting Hermes weekly expense report generation...")
        
        # 1. 聚合数据
        aggregated_data = self._aggregate_recent_expenses(days=7)
        if not aggregated_data.get("total_amount"):
            logger.info("No expense data in the last 7 days. Skipping report.")
            return

        # 2. 传入大模型分析
        report_markdown = self._generate_insights_with_llm(aggregated_data)
        
        if not report_markdown:
            logger.warning("Failed to generate expense report from LLM.")
            return

        # 3. 模拟发送报告
        self._deliver_report(report_markdown, log_id)
        logger.info("Hermes weekly expense report generation completed.")

    def _aggregate_recent_expenses(self, days: int = 7) -> dict[str, Any]:
        target_date = datetime.now(timezone.utc) - timedelta(days=days)
        
        # 基础过滤：最近N天且不是驳回状态的单据
        base_filter = [
            ExpenseClaim.occurred_at >= target_date,
            ExpenseClaim.status != "rejected"
        ]

        # 1. 按部门汇总
        dept_stmt = select(
            ExpenseClaim.department_name, 
            func.sum(ExpenseClaim.amount).label("total")
        ).where(*base_filter).group_by(ExpenseClaim.department_name)
        
        dept_results = self.db.execute(dept_stmt).all()
        by_department = {row.department_name or "Unknown": float(row.total or 0) for row in dept_results}

        # 2. 按类目汇总
        type_stmt = select(
            ExpenseClaim.expense_type, 
            func.sum(ExpenseClaim.amount).label("total")
        ).where(*base_filter).group_by(ExpenseClaim.expense_type)
        
        type_results = self.db.execute(type_stmt).all()
        by_expense_type = {row.expense_type or "Unknown": float(row.total or 0) for row in type_results}

        # 3. 总花费
        total_amount = sum(by_department.values())

        return {
            "period": f"Last {days} days",
            "total_amount": total_amount,
            "by_department": by_department,
            "by_expense_type": by_expense_type
        }

    def _generate_insights_with_llm(self, data: dict[str, Any]) -> str | None:
        system_prompt = (
            "你是公司的财务分析专家。请根据提供的最近期业务开销数据，撰写一份简洁有力的【高管费控洞察周报】。\n"
            "要求：\n"
            "1. 不要机械地罗列数字，要像人一样指出异常（例如：哪个部门花钱最多？打车费是不是异常高？）。\n"
            "2. 给出 1 条削减成本的实操建议。\n"
            "3. 纯 Markdown 格式输出，不超过 300 字。"
        )

        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": f"开销统计数据：\n{json.dumps(data, ensure_ascii=False, indent=2)}"}
        ]

        response = self.chat_service.complete(
            messages,
            max_tokens=800,
            temperature=0.4
        )
        return response

    def _deliver_report(self, report_markdown: str, log_id: str | None) -> None:
        # TODO: 未来在这里接入企微/钉钉机器人或邮件发送接口
        logger.info(f"\n================ Hermes Weekly Report [LogID: {log_id}] ================\n"
                    f"{report_markdown}\n"
                    f"==========================================================================")
