import { Context, Next } from 'koa';
import { logService, LogLevel, RequestLog } from './log.service';

// 请求日志中间件
export async function requestLogger(ctx: Context, next: Next): Promise<void> {
  const startTime = Date.now();
  const requestId = `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

  // 请求开始前记录
  const requestLog: Partial<RequestLog> = {
    requestId,
    method: ctx.method,
    path: ctx.path,
    query: ctx.querystring,
    headers: ctx.headers as Record<string, string>,
    ip: ctx.ip,
    userAgent: ctx.get('user-agent') || '',
  };

  try {
    await next();

    // 请求完成后记录响应信息
    requestLog.status = ctx.status;
    requestLog.responseTime = Date.now() - startTime;
    requestLog.responseSize = parseInt(ctx.get('Content-Length') || '0', 10);

    // 根据状态码确定日志级别
    if (ctx.status >= 500) {
      requestLog.level = LogLevel.ERROR;
      requestLog.error = `Server error: ${ctx.status}`;
    } else if (ctx.status >= 400) {
      requestLog.level = LogLevel.WARN;
      requestLog.error = `Client error: ${ctx.status}`;
    } else {
      requestLog.level = LogLevel.INFO;
    }

    logService.logRequest(requestLog as RequestLog);
  } catch (err: unknown) {
    const error = err as Error & { status?: number; code?: number };

    // 记录错误请求
    requestLog.status = error.status || 500;
    requestLog.responseTime = Date.now() - startTime;
    requestLog.level = LogLevel.ERROR;
    requestLog.error = error.message;

    logService.logRequest(requestLog as RequestLog);

    // 重新抛出错误，让 errorHandler 中间件处理
    throw err;
  }
}

// 导出日志服务实例，供其他地方使用
export { logService, LogLevel };