import type { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from './request-utils';

export interface AuditRequestUser {
  id?: number;
  username?: string;
}

export interface AuditRequest {
  user?: AuditRequestUser;
  headers?: Record<string, string | string[] | undefined>;
  connection?: { remoteAddress?: string };
}

export interface AuditLogEntry {
  module: string;
  action: string;
  targetId?: number;
  targetType?: string;
  detail?: string;
  status?: string;
}

/**
 * 执行业务操作并写入一条审计日志。
 * 统一从请求中提取 IP / UA，避免每个 controller 重复这段样板。
 */
export async function withAuditLog<T>(
  logService: OperationLogsService,
  req: AuditRequest,
  buildEntry: (result: T) => AuditLogEntry,
  operation: () => Promise<T>,
): Promise<T> {
  const { ipAddress, userAgent } = extractRequestInfo(req);
  const result = await operation();
  await logService.log({
    userId: req.user?.id,
    username: req.user?.username,
    ipAddress,
    userAgent,
    ...buildEntry(result),
  });
  return result;
}

/**
 * 仅写入一条审计日志（不包装业务操作）。
 * 适用于日志发生在操作中间、后面还有其他逻辑的 handler。
 */
export async function logAudit(
  logService: OperationLogsService,
  req: AuditRequest,
  entry: AuditLogEntry,
): Promise<void> {
  const { ipAddress, userAgent } = extractRequestInfo(req);
  await logService.log({
    userId: req.user?.id,
    username: req.user?.username,
    ipAddress,
    userAgent,
    ...entry,
  });
}
