"""admin_audit_log 写入 + 查询。

审计日志只增不改不删——任何写操作经 app.admin.audit.write_audit 落一条。
"""
from __future__ import annotations

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

from app.models.admin import AdminAuditLog


def add_audit_log(
    db: Session,
    *,
    admin_id: int,
    admin_username: str,
    action: str,
    target_type: str,
    target_id: str | None = None,
    detail: dict | None = None,
    ip: str | None = None,
    commit: bool = True,
) -> AdminAuditLog:
    """插一条审计。commit=False 时只 flush,让调用方把审计和业务写操作放同一事务。"""
    log = AdminAuditLog(
        admin_id=admin_id,
        admin_username=admin_username,
        action=action,
        target_type=target_type,
        target_id=target_id,
        detail=detail,
        ip=ip,
    )
    db.add(log)
    if commit:
        db.commit()
        db.refresh(log)
    else:
        db.flush()
    return log


def list_audit_logs(
    db: Session,
    *,
    action: str | None = None,
    target_type: str | None = None,
    admin_id: int | None = None,
    limit: int = 50,
    cursor: int | None = None,
) -> tuple[list[AdminAuditLog], int | None, int]:
    """offset 分页(id 倒序)+ total。cursor 即 offset((page-1)*pageSize),支持页码跳页。
    返回 (rows, next_cursor, total)。"""
    stmt = select(AdminAuditLog)
    if action:
        stmt = stmt.where(AdminAuditLog.action == action)
    if target_type:
        stmt = stmt.where(AdminAuditLog.target_type == target_type)
    if admin_id is not None:
        stmt = stmt.where(AdminAuditLog.admin_id == admin_id)

    total = int(db.execute(select(func.count()).select_from(stmt.subquery())).scalar_one())
    offset = max(cursor or 0, 0)
    rows = list(
        db.execute(
            stmt.order_by(AdminAuditLog.id.desc()).offset(offset).limit(limit + 1)
        ).scalars().all()
    )
    has_more = len(rows) > limit
    items = rows[:limit]
    next_cursor = offset + limit if has_more else None
    return items, next_cursor, total
