import { TRPCError } from "@trpc/server";
import { logger } from "../lib/logger.js";

const SLOW_THRESHOLD_MS = 500;

/**
 * Core logging logic for tRPC procedure calls.
 *
 * Designed to be wrapped with `t.middleware()` in trpc.ts.
 * Generates a requestId (UUID) per call and attaches it to the context.
 *
 * Log levels:
 * - debug: normal requests
 * - warn:  slow requests (>500ms)
 * - error: failed requests
 */
export async function loggingMiddleware(opts: {
  ctx: { dbUser?: { id: string } | null; requestId?: string };
  type: "query" | "mutation" | "subscription";
  path: string;
  next: (opts: { ctx: Record<string, unknown> }) => Promise<{ ok: boolean }>;
}) {
  const { ctx, type, path, next } = opts;
  const requestId = crypto.randomUUID();
  const userId = ctx.dbUser?.id ?? "anonymous";
  const start = performance.now();

  const logBase = {
    requestId,
    type,
    path,
    userId,
  };

  try {
    const result = await next({
      ctx: { ...ctx, requestId },
    });

    const durationMs = Math.round(performance.now() - start);
    const logData = { ...logBase, durationMs, status: "ok" as const };

    if (durationMs > SLOW_THRESHOLD_MS) {
      logger.warn(logData, "Slow tRPC call");
    } else {
      logger.debug(logData, "tRPC call");
    }

    return result;
  } catch (error) {
    const durationMs = Math.round(performance.now() - start);
    const errorCode =
      error instanceof TRPCError ? error.code : "INTERNAL_SERVER_ERROR";
    const errorMessage =
      error instanceof Error ? error.message : "Unknown error";

    // Log input validation failures at warn level (not error)
    if (errorCode === "BAD_REQUEST") {
      logger.warn(
        { ...logBase, durationMs, status: "error" as const, errorCode, errorMessage },
        "Input validation failure",
      );
    } else {
      logger.error(
        { ...logBase, durationMs, status: "error" as const, errorCode, errorMessage },
        "tRPC call failed",
      );
    }

    throw error;
  }
}
