import { auth } from '@/auth';
import { Session } from 'next-auth';

import { pino, Logger as LokiLogger } from 'pino';
import pinoLoki from 'pino-loki';

let loggerInstance: Logger;

class Logger {
  private lokiLogger!: LokiLogger;

  constructor() {
    if (loggerInstance) {
      return loggerInstance;
    }
    this.lokiLogger = pino(
      { level: 'info' },
      pinoLoki({
        batching: false,

        // These labels will be added to every log
        labels: {
          app: 'grafanacloud-landingai-logs',
          namespace: 'vision-agent',
        },

        // Credentials for our Loki instance
        host: 'https://logs-prod3.grafana.net',
        basicAuth: {
          username: process.env.LOKI_AUTH_USER_ID!,
          password: process.env.LOKI_AUTH_USER_PASSWORD!,
        },
      }),
    );
    this.lokiLogger.debug('test');
    loggerInstance = this;
    return loggerInstance;
  }

  private createLogMessage(
    message: Object | string,
    session: Session | null,
    request?: Request,
    logDescription?: string,
  ) {
    const body = {
      type: logDescription || '__DEFAULT',
      context: {
        ...(request
          ? {
              method: request?.method,
              url: request.url,
            }
          : {}),
        sessionUserId: session?.user.id,
        sessionUserName: session?.user.name,
        sessionUserEmail: session?.user.email,
      },
      message: message,
    };
    return body;
  }

  info(
    session: Session | null,
    message: string | Object,
    request?: Request,
    logDescription?: string,
  ) {
    this.lokiLogger.info(
      this.createLogMessage(message, session, request, logDescription),
    );
  }
  warn(
    session: Session | null,
    message: string | Object,
    request?: Request,
    logDescription?: string,
  ) {
    this.lokiLogger.warn(
      this.createLogMessage(message, session, request, logDescription),
    );
  }
  debug(
    session: Session | null,
    message: string | Object,
    request?: Request,
    logDescription?: string,
  ) {
    this.lokiLogger.debug(
      this.createLogMessage(message, session, request, logDescription),
    );
  }
  error(
    session: Session | null,
    message: string | Object,
    request?: Request,
    logDescription?: string,
  ) {
    this.lokiLogger.error(
      this.createLogMessage(
        message,
        session,
        request,
        logDescription ?? '__ERROR',
      ),
    );
  }
}

export const withLogging = (
  handler: (
    session: Session | null,
    json: any,
    request: Request,
  ) => Promise<Response>,
) => {
  return async (req: Request) => {
    const session = await auth();
    const json = await req.json();
    // logger.info(
    //   session,
    //   {
    //     params: json,
    //   },
    //   req,
    //   '_API_REQUEST',
    // );
    return handler(session, json, req);
  };
};

export const logger = new Logger();