# =============================================================================
# 企微IT智能服务台 — 审计日志服务
# =============================================================================
# 说明: 提供 audit_log 写入/查询的统一入口
# 用法:
#   from app.services.audit_log_service import record_audit_log
#   await record_audit_log(
#       db, employee_id="sxn", action="role_change",
#       resource="agent", resource_id="agent-001",
#       details={"role": "agent"}, request=request,
#   )
# =============================================================================

import logging
from datetime import datetime
from typing import Any, Dict, Optional

from fastapi import Request
from sqlalchemy import select, func, and_
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.audit_log import AuditLog

logger = logging.getLogger(__name__)


async def record_audit_log(
    db: AsyncSession,
    employee_id: str,
    action: str,
    resource: str,
    resource_id: Optional[str] = None,
    details: Optional[Dict[str, Any]] = None,
    result: str = "success",
    request: Optional[Request] = None,
) -> AuditLog:
    """记录一条审计日志。

    Args:
        db: 数据库会话
        employee_id: 操作人企微 UserID,系统操作传 "system"
        action: 操作类型
        resource: 目标资源类型
        resource_id: 目标资源 ID(可选)
        details: 详细上下文 JSON(可选)
        result: success / failure / partial
        request: FastAPI Request(可选,自动取 IP + UA)

    Returns:
        AuditLog: 写入的日志对象
    """
    ip_address = None
    user_agent = None
    if request is not None:
        # 优先用 X-Forwarded-For / X-Real-IP(proxy 后面)
        ip_address = (
            request.headers.get("x-forwarded-for", "").split(",")[0].strip()
            or request.headers.get("x-real-ip")
            or (request.client.host if request.client else None)
        )
        user_agent = request.headers.get("user-agent")

    log = AuditLog(
        employee_id=employee_id,
        action=action,
        resource=resource,
        resource_id=resource_id,
        details=details or {},
        result=result,
        ip_address=ip_address,
        user_agent=user_agent,
        created_at=datetime.now(),
    )
    db.add(log)
    # 注:不 commit,让调用方跟主操作一起 commit(避免日志写一半就回滚)
    return log


async def list_audit_logs(
    db: AsyncSession,
    employee_id: Optional[str] = None,
    action: Optional[str] = None,
    resource: Optional[str] = None,
    from_time: Optional[datetime] = None,
    to_time: Optional[datetime] = None,
    page: int = 1,
    page_size: int = 50,
) -> Dict[str, Any]:
    """查询审计日志(分页 + 多维过滤)。

    Args:
        db: 数据库会话
        employee_id: 按操作人过滤(可选)
        action: 按操作类型过滤(可选)
        resource: 按资源类型过滤(可选)
        from_time: 起始时间(可选)
        to_time: 结束时间(可选)
        page: 页码,从 1 开始
        page_size: 每页条数,默认 50

    Returns:
        Dict: {items: [...], total: int, page, page_size}
    """
    stmt = select(AuditLog)
    conditions = []
    if employee_id:
        conditions.append(AuditLog.employee_id == employee_id)
    if action:
        conditions.append(AuditLog.action == action)
    if resource:
        conditions.append(AuditLog.resource == resource)
    if from_time:
        conditions.append(AuditLog.created_at >= from_time)
    if to_time:
        conditions.append(AuditLog.created_at <= to_time)
    if conditions:
        stmt = stmt.where(and_(*conditions))

    # 倒序 + 分页
    stmt = stmt.order_by(AuditLog.created_at.desc())
    stmt = stmt.offset((page - 1) * page_size).limit(page_size)

    result = await db.execute(stmt)
    items = result.scalars().all()

    # 总数
    count_stmt = select(func.count()).select_from(AuditLog)
    if conditions:
        count_stmt = count_stmt.where(and_(*conditions))
    total = (await db.execute(count_stmt)).scalar() or 0

    return {
        "items": items,
        "total": total,
        "page": page,
        "page_size": page_size,
    }
