"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const i18next_express_middleware_1 = __importDefault(require("i18next-express-middleware"));
const path_match_1 = __importDefault(require("path-match"));
const utils_1 = require("../utils");
const route = path_match_1.default();
function default_1(nexti18next) {
    const { config, i18n } = nexti18next;
    const { allLanguages, ignoreRoutes, localeSubpaths } = config;
    const isI18nRoute = (req) => ignoreRoutes === null || ignoreRoutes === void 0 ? void 0 : ignoreRoutes.every(x => !req.url.startsWith(x));
    const localeSubpathRoute = route(`/:subpath(${Object.values(localeSubpaths || {}).join('|')})(.*)`);
    const middleware = [];
    /*
        If not using server side language detection,
        we need to manually set the language for
        each request
    */
    if (!config.serverLanguageDetection) {
        middleware.push((req, _res, next) => {
            if (isI18nRoute(req)) {
                req.lng = config.defaultLanguage;
            }
            next();
        });
    }
    /*
        This does the bulk of the i18next work
    */
    middleware.push(i18next_express_middleware_1.default.handle(i18n));
    /*
        This does the locale subpath work
    */
    middleware.push((req, res, next) => {
        if (isI18nRoute(req) && req.i18n) {
            let currentLng = utils_1.lngFromReq(req);
            const currentLngSubpath = utils_1.subpathFromLng(config, currentLng);
            const currentLngRequiresSubpath = utils_1.subpathIsRequired(config, currentLng || '');
            const currentLngSubpathIsPresent = utils_1.subpathIsPresent(req.url, currentLngSubpath);
            const lngFromCurrentSubpath = allLanguages.find((l) => utils_1.subpathIsPresent(req.url, utils_1.subpathFromLng(config, l)));
            if (lngFromCurrentSubpath !== undefined && lngFromCurrentSubpath !== currentLng) {
                /*
                    If a user has hit a subpath which does not
                    match their language, give preference to
                    the path, and change user language.
                */
                req.i18n.changeLanguage(lngFromCurrentSubpath);
                currentLng = lngFromCurrentSubpath;
            }
            else if (currentLngRequiresSubpath && !currentLngSubpathIsPresent) {
                /*
                    If a language subpath is required and
                    not present, prepend correct subpath
                */
                return utils_1.redirectWithoutCache(res, utils_1.addSubpath(req.url, currentLngSubpath));
            }
            /*
                If a locale subpath is present in the URL,
                modify req.url in place so that NextJs will
                render the correct route
            */
            if (typeof lngFromCurrentSubpath === 'string') {
                const params = localeSubpathRoute(req.url);
                if (params !== false) {
                    const { subpath } = params;
                    req.query = { ...req.query, subpath, lng: currentLng };
                    req.url = utils_1.removeSubpath(req.url, subpath);
                }
            }
        }
        next();
    });
    return middleware;
}
exports.default = default_1;
