/**
 * Dynamic Locale Loader
 * Loads locale files on-demand for moment, FullCalendar, and Bootstrap DatePicker
 */

window.CRM = window.CRM || {};

/**
 * Dynamically load a script file
 * @param {string} url - The URL of the script to load
 * @returns {Promise<void>}
 */
function loadScript(url) {
  return new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.src = url;
    script.onload = () => resolve();
    script.onerror = () => reject(new Error(`Failed to load script: ${url}`));
    document.head.appendChild(script);
  });
}

/**
 * Check browser locale against current ChurchCRM locale and notify user if different
 */
function checkBrowserLocale() {
  // Skip if already dismissed for current version
  const dismissKey = "browser-locale-prompt-dismissed";
  const dismissedVersion = localStorage.getItem(dismissKey);
  if (dismissedVersion === window.CRM.version) {
    return;
  }

  // Get browser locale directly from navigator
  const browserLocale = navigator.language || navigator.userLanguage;
  if (!browserLocale) {
    return;
  }

  // Extract language code (e.g., "en-US" -> "en", "ja" -> "ja")
  const browserLangCode = browserLocale.split("-")[0].split("_")[0];
  const crmLangCode = window.CRM.shortLocale || "";

  // Compare language codes only (ignore region variants)
  if (browserLangCode === crmLangCode) {
    return;
  }

  const showPrompt = () => {
    const container =
      document.querySelector(".content-wrapper > section.content > .container-fluid") ||
      document.querySelector(".content-wrapper");
    if (!container) {
      return;
    }

    const alert = document.createElement("div");
    alert.className = "alert alert-info alert-dismissible";
    alert.style.marginBottom = "1rem";

    const userSettingsUrl = `${window.CRM.root}/v2/user/${window.CRM.userId}#tab-localization`;

    alert.innerHTML = `
      <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
      <strong>${i18next.t("Browser language preference detected")}</strong>
      <div>${i18next.t("Your browser language preference differs from your ChurchCRM locale")}.</div>
      <div class="mt-2">
        <a href="${userSettingsUrl}" class="btn btn-sm btn-primary">
          <i class="fa-solid fa-cog mr-1"></i>${i18next.t("Change Your Locale")}
        </a>
        <button id="dismissBrowserLocaleBtn" class="btn btn-sm btn-secondary ml-2">${i18next.t("Dismiss")}</button>
      </div>
    `;

    container.insertAdjacentElement("afterbegin", alert);

    // Handle dismiss and close buttons
    const markDismissed = () => localStorage.setItem(dismissKey, window.CRM.version);
    alert.querySelector("#dismissBrowserLocaleBtn").addEventListener("click", () => {
      markDismissed();
      alert.remove();
    });
    alert.querySelector(".btn-close").addEventListener("click", markDismissed);
  };

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", showPrompt);
  } else {
    setTimeout(showPrompt, 500); // Small delay to ensure content wrapper exists
  }
}

/**
 * Load all locale files for the specified locale
 * @param {object} localeConfig - Locale configuration from locales.json
 */
async function loadLocaleFiles(localeConfig) {
  // Validate localeConfig exists
  if (!localeConfig) {
    console.warn("localeConfig is null or undefined, skipping locale loading");
    window.CRM.i18keys = {};
    window.CRM.localesLoaded = true;
    window.dispatchEvent(new Event("CRM.localesReady"));
    return;
  }

  const rootPath = window.CRM.root || "";
  const promises = [];

  try {
    // Load i18n translation keys from JSON
    // Skip loading for en_US as it's the base language (no translation file needed)
    if (localeConfig.locale && localeConfig.locale !== "en_US") {
      const i18nPath = `${rootPath}/locale/i18n/${localeConfig.locale}.json`;
      try {
        const response = await fetch(i18nPath);
        if (response.ok) {
          window.CRM.i18keys = await response.json();
        } else {
          console.warn(`i18n keys not found for locale: ${localeConfig.locale}, using empty object`);
          window.CRM.i18keys = {};
        }
      } catch (e) {
        console.warn(`Failed to load i18n keys for ${localeConfig.locale}:`, e);
        window.CRM.i18keys = {};
      }
    } else {
      // en_US uses empty object (base language, no translations needed)
      window.CRM.i18keys = {};
    }

    // Load Moment.js locale if configured
    // Skip for 'en' as it's the default locale built into moment.js
    if (localeConfig.momentLocale && localeConfig.momentLocale !== "en" && typeof moment !== "undefined") {
      const momentPath = `${rootPath}/locale/vendor/moment/${localeConfig.momentLocale}.js`;
      promises.push(
        loadScript(momentPath)
          .then(() => {
            if (typeof moment !== "undefined" && typeof moment.locale === "function") {
              moment.locale(localeConfig.momentLocale);
            }
          })
          .catch((e) => console.warn(`Failed to load moment locale ${localeConfig.momentLocale}:`, e)),
      );
    } else if (localeConfig.momentLocale === "en" && typeof moment !== "undefined") {
      // Set to 'en' without loading (built-in default)
      moment.locale("en");
    }

    // Load Bootstrap DatePicker locale if configured
    if (localeConfig.datePicker) {
      const dpPath = `${rootPath}/locale/vendor/bootstrap-datepicker/bootstrap-datepicker.${localeConfig.languageCode}.min.js`;
      promises.push(
        loadScript(dpPath).catch((e) =>
          console.warn(`Failed to load DatePicker locale ${localeConfig.languageCode}:`, e),
        ),
      );
    }

    // Load FullCalendar locale only when FullCalendar is available.
    // FooterNotLoggedIn.php (login page) runs this loader but never loads
    // index.global.min.js, so ar.js / other locale IIFEs would throw
    // "FullCalendar is not defined" if loaded there.
    if (localeConfig.fullCalendar && typeof FullCalendar !== "undefined") {
      let fcLocale = localeConfig.languageCode.toLowerCase();
      if (localeConfig.fullCalendarLocale) {
        fcLocale = localeConfig.fullCalendarLocale;
      }
      const fcPath = `${rootPath}/locale/vendor/fullcalendar/${fcLocale}.js`;
      promises.push(
        loadScript(fcPath).catch((e) => console.warn(`Failed to load FullCalendar locale ${fcLocale}:`, e)),
      );
    }

    // Wait for all locale files to load
    await Promise.all(promises);

    // Initialize i18next after locale keys are loaded
    if (typeof i18next !== "undefined" && window.CRM.i18keys) {
      const i18nextOpt = {
        lng: window.CRM.shortLocale,
        nsSeparator: false,
        keySeparator: false,
        pluralSeparator: false,
        contextSeparator: false,
        fallbackLng: false,
        resources: {},
      };
      i18nextOpt.resources[window.CRM.shortLocale] = {
        translation: window.CRM.i18keys,
      };
      i18next.init(i18nextOpt);

      // Detect browser locale and prompt user if different
      checkBrowserLocale();

      // Set flag BEFORE dispatching so synchronous event listeners see it as true
      window.CRM.localesLoaded = true;
      window.dispatchEvent(new Event("CRM.localesReady"));
    }
  } catch (error) {
    console.error("Error loading locale files:", error);
    // Even on error, mark as loaded to prevent infinite waiting
    window.CRM.localesLoaded = true;
    window.dispatchEvent(new Event("CRM.localesReady"));
  }
}

// Export for use in other scripts
window.CRM.loadLocaleFiles = loadLocaleFiles;

/**
 * Populate a <select> with locale options grouped by region.
 * Shared by church-info and user-settings pages.
 *
 * @param {HTMLSelectElement} selectEl       - Target element to populate.
 * @param {string}            selectedLocale - Locale code to pre-select.
 * @returns {Promise<void>}
 */
async function populateLocaleDropdown(selectEl, selectedLocale) {
  const root = window.CRM.root || "";
  const response = await fetch(`${root}/locale/locales.json`);
  if (!response.ok) {
    throw new Error(`Failed to load locales.json: ${response.status}`);
  }
  const locales = await response.json();

  const byRegion = {};
  for (const [englishName, data] of Object.entries(locales)) {
    const region = data.region || "Other";
    if (!byRegion[region]) byRegion[region] = [];
    byRegion[region].push({ englishName, data });
  }

  for (const region of Object.keys(byRegion).sort()) {
    const group = document.createElement("optgroup");
    group.label = region;
    for (const { englishName, data } of byRegion[region]) {
      const native = data.nativeName || "";
      const nativeFirstWord = native.split(/[\s(-]/)[0].toLowerCase();
      const englishFirstWord = englishName.split(/[\s(-]/)[0].toLowerCase();
      const sameLanguage = nativeFirstWord === englishFirstWord;
      const label =
        native && native !== englishName && !sameLanguage
          ? `${native} \u2014 ${englishName} [${data.locale}]`
          : `${englishName} [${data.locale}]`;
      const option = new Option(label, data.locale, false, data.locale === selectedLocale);
      group.appendChild(option);
    }
    selectEl.appendChild(group);
  }
}

window.CRM.populateLocaleDropdown = populateLocaleDropdown;
