import { Global, Module } from "@nestjs/common";
import { LoggerModule, type Params } from "nestjs-pino";
import type { IncomingMessage, ServerResponse } from "http";

const prettyLogsEnabled =
  process.env["PRETTY_LOGS"] === "true" || process.env["NODE_ENV"] !== "production";

// Build pinoHttp config - extracted to avoid type issues with exactOptionalPropertyTypes
// Using NonNullable to extract the pinoHttp type from Params
const pinoHttpConfig: NonNullable<Params["pinoHttp"]> = {
  level: process.env["LOG_LEVEL"] || "info",
  name: process.env["APP_NAME"] || "customer-portal-bff",
  /**
   * Reduce noise from pino-http auto logging:
   * - successful requests => debug (hidden when LOG_LEVEL=info)
   * - 4xx => warn
   * - 5xx / errors => error
   *
   * This keeps production logs focused on actionable events while still
   * allowing full request logging by setting LOG_LEVEL=debug.
   */
  customLogLevel: (_req: IncomingMessage, res: ServerResponse, err: Error | undefined) => {
    if (err || (res?.statusCode && res.statusCode >= 500)) return "error";
    if (res?.statusCode && res.statusCode >= 400) return "warn";
    return "debug";
  },
  autoLogging: {
    ignore: (req: IncomingMessage) => {
      const url = req.url || "";
      return (
        url.includes("/health") ||
        url.includes("/favicon") ||
        url.includes("/_next/") ||
        url.includes("/api/auth/session")
      );
    },
  },
  serializers: {
    req: (req: { method?: string; url?: string; headers?: Record<string, unknown> }) => ({
      method: req.method,
      url: req.url,
      ...(process.env["NODE_ENV"] === "development" && {
        headers: req.headers,
      }),
    }),
    res: (res: { statusCode?: number }) => ({
      statusCode: res.statusCode,
    }),
  },
  redact: {
    paths: [
      "req.headers.authorization",
      "req.headers.cookie",
      "req.body",
      "res.body",
      "password",
      "token",
      "secret",
      "jwt",
      "apiKey",
    ],
    remove: true,
  },
  formatters: {
    level: (label: string) => ({ level: label }),
    bindings: () => ({}),
  },
};

// Add transport only in development to avoid type issues
if (prettyLogsEnabled) {
  pinoHttpConfig.transport = {
    target: "pino-pretty",
    options: {
      colorize: true,
      translateTime: false,
      singleLine: true,
      // keep level for coloring but drop other noisy metadata
      ignore: "pid,req,res,context,name,time",
    },
  };
}

@Global()
@Module({
  imports: [LoggerModule.forRoot({ pinoHttp: pinoHttpConfig })],
  exports: [LoggerModule],
})
export class LoggingModule {}
