import createMiddleware from "next-intl/middleware";
import { getRequestConfig } from "next-intl/server";
import type { NextRequest } from "next/server";

export interface MintelI18nConfig {
  locales: string[];
  defaultLocale: string;
  logRequests?: boolean;
}

export function createMintelMiddleware(config: MintelI18nConfig) {
  const intlMiddleware = createMiddleware({
    locales: config.locales,
    defaultLocale: config.defaultLocale,
  });

  return function middleware(request: NextRequest) {
    if (config.logRequests) {
      const { method, url } = request;
      console.log(`Incoming request: method=${method} url=${url}`);
    }

    try {
      return intlMiddleware(request);
    } catch (error) {
      if (config.logRequests) {
        console.error(
          `Request failed: ${request.method} ${request.url}`,
          error,
        );
      }
      throw error;
    }
  };
}

export function createMintelI18nRequestConfig(
  locales: string[],
  defaultLocale: string,
  importMessages: (locale: string) => Promise<any>,
) {
  return getRequestConfig(async ({ requestLocale }) => {
    let locale = await requestLocale;

    if (!locale || !locales.includes(locale)) {
      locale = defaultLocale;
    }

    return {
      locale,
      messages: (await importMessages(locale)).default,
      onError(error: any) {
        if (error.code === "MISSING_MESSAGE") {
          console.error(error.message);
        } else {
          console.error(error);
        }
      },
      getMessageFallback({ namespace, key, error }: any) {
        const path = [namespace, key].filter((part) => part != null).join(".");
        if (error.code === "MISSING_MESSAGE") {
          return path;
        }
        return "fallback";
      },
    };
  });
}
