const { DateTime } = require("luxon");

module.exports = function (eleventyConfig, { TIME_ZONE, defaultLanguage }) {
    // {{ post.date | date("dd/MM/yyyy") }} -> 18/10/2025
    eleventyConfig.addFilter("date", function (dateObj, format = "dd/MM/yyyy") {
        let dt = dateObj;
        // handle string dates
        if (typeof dateObj === "string") {
            dt = DateTime.fromISO(dateObj, { zone: TIME_ZONE }).toJSDate();
        }
        // handle DateTime objects (from addDateParsing)
        if (dateObj instanceof DateTime) {
            dt = dateObj.toJSDate();
        }
        // check dt as valid Date object
        if (!(dt instanceof Date) || isNaN(dt)) {
            console.log("Invalid date input:", dateObj);
            return "";
        }
        // format in TIME_ZONE
        const formatted = DateTime.fromJSDate(dt, { zone: TIME_ZONE })
            .toFormat(format);
        console.log("Date input:", dt, "Formatted:", formatted, "Timezone:", TIME_ZONE);
        return formatted;
    });

    // filters collections by current language
    eleventyConfig.addFilter("i18n_filter", function (collection, limit = null) {
        const lang = this.page.lang; // access page.lang from context
        let filtered = collection.filter(item => item.data.lang === lang);
        if (limit !== null) {
            filtered = filtered.slice(0, limit);
        }
        return filtered;
    });

    const LOCALE_URL_DEBUG = process.env.LOCALE_URL_DEBUG === "1" || process.env.LOCALE_URL_DEBUG === "true";

    // locale_url replacement that uses pre-compile filesystem
    eleventyConfig.addNunjucksFilter("locale_url_resolve", function (targetUrl, desiredLocale) {
        const ctx = (this && this.ctx) ? this.ctx : {};
        const collections = (ctx.collections) ? ctx.collections : {};
        const all = collections.all || [];

        if (!targetUrl || typeof targetUrl !== "string") return targetUrl;
        if (!targetUrl.startsWith("/")) return targetUrl; // external or relative link -> leave as is

        // determine locale to resolve to
        const pageLang = desiredLocale || (ctx.page && ctx.page.lang) || ctx.locale || defaultLanguage;

        const LOCALE_URL_DEBUG = process.env.LOCALE_URL_DEBUG === "1" || process.env.LOCALE_URL_DEBUG === "true";
        if (LOCALE_URL_DEBUG) {
            console.warn(`[locale_url_resolve] resolving targetUrl="${targetUrl}" desiredLocale="${desiredLocale}" pageLang="${pageLang}"`);
        }

        // special case for homepage
        if (targetUrl === "/" || targetUrl === "/index/") {
            if (pageLang === defaultLanguage) {
                if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] homepage, default language (${defaultLanguage}) -> "/"`);
                return "/";
            }
            const homepageUrl = `/${pageLang}/`;
            if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] homepage, language (${pageLang}) -> "${homepageUrl}"`);
            return homepageUrl;
        }

        // normalize targetUrl to include trailing slash for comparison
        const normUrl = targetUrl.endsWith("/") ? targetUrl : `${targetUrl}/`;

        // try to find the canonical (default language) page corresponding to targetUrl
        let canonical = all.find(p => {
            return (p.url === normUrl || p.url === targetUrl) && p.data && p.data.lang === defaultLanguage;
        });

        // if not found, try to find any page with that url (maybe targetUrl already localized)
        if (!canonical) {
            canonical = all.find(p => (p.url === normUrl || p.url === targetUrl));
        }

        if (LOCALE_URL_DEBUG) {
            if (canonical) {
                const cs = (canonical.page && canonical.page.filePathStem) ? canonical.page.filePathStem : "(no stem)";
                const clang = (canonical.data && canonical.data.lang) ? canonical.data.lang : "(no lang)";
                console.warn(`[locale_url_resolve] canonical found: url="${canonical.url}" filePathStem="${cs}" lang="${clang}"`);
            } else {
                console.warn(`[locale_url_resolve] canonical NOT found for targetUrl="${targetUrl}". Will fallback to prefixed URL.`);
            }
        }

        // if cannot find canonical page, fall back to a prefixed URL (best effort)
        if (!canonical) {
            const fallback = `/${pageLang}${targetUrl}`.replace(/\/{2,}/g, "/");
            if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] fallback -> "${fallback}"`);
            return fallback;
        }

        // determine canonical filePathStem (the source input path without extension)
        const canonicalLang = canonical.data && canonical.data.lang ? canonical.data.lang : defaultLanguage;
        const canonicalStem = (canonical.page && canonical.page.filePathStem) ? canonical.page.filePathStem : "";

        // remove the canonical lang prefix from the stem to create a "key" to match across locales.
        // ie "/en/about" -> "/about", "/es/about" -> "/about"
        const key = canonicalStem.replace(new RegExp(`^/${canonicalLang}`), "").replace(/^\/+/, "");

        if (LOCALE_URL_DEBUG) {
            console.warn(`[locale_url_resolve] canonicalLang="${canonicalLang}" canonicalStem="${canonicalStem}" key="${key}"`);
        }

        // find the localized page whose filePathStem ends with that key and whose lang matches pageLang.
        const localized = all.find(p => {
            const pLang = p.data && p.data.lang;
            const pStem = (p.page && p.page.filePathStem) ? p.page.filePathStem : "";
            // be defensive: ensure pLang exists
            if (!pLang) return false;
            return pLang === pageLang && pStem.endsWith(key);
        });

        if (localized && localized.url) {
            if (LOCALE_URL_DEBUG) {
                const ls = (localized.page && localized.page.filePathStem) ? localized.page.filePathStem : "(no stem)";
                console.warn(`[locale_url_resolve] localized found: url="${localized.url}" filePathStem="${ls}" lang="${localized.data.lang}"`);
            }
            return localized.url;
        }

        // fallback to prefixed URL
        const fallback2 = `/${pageLang}${targetUrl}`.replace(/\/{2,}/g, "/");
        if (LOCALE_URL_DEBUG) console.warn(`[locale_url_resolve] localized NOT found for key="${key}" — fallback -> "${fallback2}"`);
        return fallback2;
    });

    // turn on disabled nunjucks filter
    eleventyConfig.addNunjucksFilter("values", obj => Object.values(obj));
};
