import { SafeDictionary } from "@insite/client-framework/Common/Types";
import getDateTimeFormatPattern from "@insite/mobius/utilities/getDateTimeFormatPattern";

let storedLabelsByKey: SafeDictionary<string> = {};
let storedIsDebugModeEnabled = false;
let storedLanguageCode = "en-US";
let storedDateFormat = "MM/dd/y";
let storedDateTimeFormat = "MM/dd/y hh:mm a";
let labelsLoaded = false;

interface BCP47language {
    tag: string;
    language?: string;
    region?: string;
    description?: string;
}

const IETFBCP47languagetags: Record<string, BCP47language> = {
    arSA: { tag: "ar-SA", language: "Arabic", region: "Saudi Arabia", description: "Arabic (Saudi Arabia)" },
    beBY: { tag: "be-BY", language: "Belarusian", region: "Belarus", description: "Belarusian (Belarus)" },
    bgBG: { tag: "bg-BG", language: "Bulgarian", region: "Bulgaria", description: "Bulgarian (Bulgaria)" },
    bnBD: { tag: "bn-BD", language: "Bangla", region: "Bangladesh", description: "Bangla (Bangladesh)" },
    bnIN: { tag: "bn-IN", language: "Bangla", region: "India", description: "Bangla (India)" },
    caES: { tag: "ca-ES", language: "Catalan", region: "Spain", description: "Catalan (Spain)" },
    csCZ: { tag: "cs-CZ", language: "Czech", region: "Czech Republic", description: "Czech (Czech Republic)" },
    daDK: { tag: "da-DK", language: "Danish", region: "Denmark", description: "Danish (Denmark)" },
    deAT: { tag: "de-AT", language: "German", region: "Austria", description: "Austrian German" },
    deCH: { tag: "de-CH", language: "German", region: "Switzerland", description: "Swiss German" },
    deDE: {
        tag: "de-DE",
        language: "German",
        region: "Germany",
        description: "Standard German (as spoken in Germany)",
    },
    elGR: { tag: "el-GR", language: "Greek", region: "Greece", description: "Modern Greek" },
    enAU: { tag: "en-AU", language: "English", region: "Australia", description: "Australian English" },
    enCA: { tag: "en-CA", language: "English", region: "Canada", description: "Canadian English" },
    enGB: { tag: "en-GB", language: "English", region: "United Kingdom", description: "British English" },
    enIE: { tag: "en-IE", language: "English", region: "Ireland", description: "Irish English" },
    enIN: { tag: "en-IN", language: "English", region: "India", description: "Indian English" },
    enNZ: { tag: "en-NZ", language: "English", region: "New Zealand", description: "New Zealand English" },
    enUS: { tag: "en-US", language: "English", region: "United States", description: "US English" },
    enZA: { tag: "en-ZA", language: "English", region: "South Africa", description: "English (South Africa)" },
    es419: { tag: "es-419", language: "Spanish", region: "Latin American", description: "Latin American Spanish" },
    esAR: { tag: "es-AR", language: "Spanish", region: "Argentina", description: "Argentine Spanish" },
    esCL: { tag: "es-CL", language: "Spanish", region: "Chile", description: "Chilean Spanish" },
    esCO: { tag: "es-CO", language: "Spanish", region: "Columbia", description: "Colombian Spanish" },
    esES: {
        tag: "es-ES",
        language: "Spanish",
        region: "Spain",
        description: "Castilian Spanish (as spoken in Central-Northern Spain)",
    },
    esMX: { tag: "es-MX", language: "Spanish", region: "Mexico", description: "Mexican Spanish" },
    esUS: { tag: "es-US", language: "Spanish", region: "United States", description: "American Spanish" },
    fiFI: { tag: "fi-FI", language: "Finnish", region: "Finland", description: "Finnish (Finland)" },
    frBE: { tag: "fr-BE", language: "French", region: "Belgium", description: "Belgian French" },
    frCA: { tag: "fr-CA", language: "French", region: "Canada", description: "Canadian French" },
    frCH: { tag: "fr-CH", language: "French", region: "Switzerland", description: "Swiss French" },
    frFR: { tag: "fr-FR", language: "French", region: "France", description: "Standard French (especially in France)" },
    heIL: { tag: "he-IL", language: "Hebrew", region: "Israel", description: "Hebrew (Israel)" },
    hiIN: { tag: "hi-IN", language: "Hindi", region: "India", description: "Hindi (India)" },
    huHU: { tag: "hu-HU", language: "Hungarian", region: "Hungary", description: "Hungarian (Hungary)" },
    hyAM: { tag: "hy-AM", language: "Armenian", region: "Armenia", description: "Armenian (Armenian)" },
    idID: { tag: "id-ID", language: "Indonesian", region: "Indonesia", description: "Indonesian (Indonesia)" },
    itCH: { tag: "it-CH", language: "Italian", region: "Switzerland", description: "Swiss Italian" },
    itIT: { tag: "it-IT", language: "Italian", region: "Italy", description: "Standard Italian (as spoken in Italy)" },
    jaJP: { tag: "ja-JP", language: "Japanese", region: "Japan", description: "Japanese (Japan)" },
    koKR: { tag: "ko-KR", language: "Korean", region: "Republic of Korea", description: "Korean (Republic of Korea)" },
    nlBE: { tag: "nl-BE", language: "Dutch", region: "Belgium", description: "Belgian Dutch" },
    nlNL: {
        tag: "nl-NL",
        language: "Dutch",
        region: "The Netherlands",
        description: "Standard Dutch (as spoken in The Netherlands)",
    },
    mi: { tag: "mi", language: "Maori", region: "", description: "Maori" },
    mkMK: { tag: "mk-MK", language: "Macedonian", region: "Macedonia", description: "Macedonian (Macedonia)" },
    msMY: { tag: "mk-MK", language: "Malay", region: "Malaysia", description: "Malay (Malaysia)" },
    noNO: { tag: "no-NO", language: "Norwegian", region: "Norway", description: "Norwegian (Norway)" },
    plPL: { tag: "pl-PL", language: "Polish", region: "Poland", description: "Polish (Poland)" },
    ptBR: { tag: "pt-BR", language: "Portugese", region: "Brazil", description: "Brazilian Portuguese" },
    ptPT: {
        tag: "pt-PT",
        language: "Portugese",
        region: "Portugal",
        description: "European Portuguese (as written and spoken in Portugal)",
    },
    roRO: { tag: "ro-RO", language: "Romanian", region: "Romania", description: "Romanian (Romania)" },
    ruRU: {
        tag: "ru-RU",
        language: "Russian",
        region: "Russian Federation",
        description: "Russian (Russian Federation)",
    },
    slSL: { tag: "sl-SL", language: "Slovenian", region: "Slovenia", description: "Slovenian (Slovenia)" },
    sqAL: { tag: "sq-AL", language: "Albanian", region: "Albania", description: "Albanian (Albania)" },
    skSK: { tag: "sk-SK", language: "Slovak", region: "Slovakia", description: "Slovak (Slovakia)" },
    srCyrl: {
        tag: "sr-Cyrl",
        language: "Serbian",
        region: "Serbia",
        description: " Serbian written in Cyrillic script",
    },
    svSE: { tag: "sv-SE", language: "Swedish", region: "Sweden", description: "Swedish (Sweden)" },
    taIN: { tag: "ta-IN", language: "Tamil", region: "India", description: "Indian Tamil" },
    taLK: { tag: "ta-LK", language: "Tamil", region: "Sri Lanka", description: "Sri Lankan Tamil" },
    thTH: { tag: "th-TH", language: "Thai", region: "Thailand", description: "Thai (Thailand)" },
    trTR: { tag: "tr-TR", language: "Turkish", region: "Turkey", description: "Turkish (Turkey)" },
    viVN: { tag: "vi-VN", language: "Vietnamese", region: "Vietnam", description: "Vietnamese (Vietnam)" },
    zhCN: { tag: "zh-CN", language: "Chinese", region: "China", description: "Mainland China, simplified characters" },
    zhHK: { tag: "zh-HK", language: "Chinese", region: "Hond Kong", description: "Hong Kong, traditional characters" },
    zhTW: { tag: "zh-TW", language: "Chinese", region: "Taiwan", description: "Taiwan, traditional characters" },
};

export function setLabels(labelsByKey: SafeDictionary<string>, isDebugModeEnabled: boolean, languageCode: string) {
    storedLabelsByKey = labelsByKey;
    storedIsDebugModeEnabled = isDebugModeEnabled;
    storedLanguageCode = IETFBCP47languagetags[languageCode] ? IETFBCP47languagetags[languageCode].tag : "en-US";
    storedDateFormat = getDateTimeFormatPattern(storedLanguageCode);
    storedDateTimeFormat = getDateTimeFormatPattern(storedLanguageCode, true);
    labelsLoaded = true;
}

export function TS(key: string, ...replacementValues: readonly string[]) {
    if (!key) {
        return "";
    }

    let localizedFormat = storedLabelsByKey[key] ?? getFirstLetterCaseInsensitive(key);

    localizedFormat ??= key;

    localizedFormat = replacer(localizedFormat, replacementValues);

    if (localizedFormat && storedIsDebugModeEnabled && !localizedFormat.startsWith("TS:")) {
        localizedFormat = `TS:${localizedFormat}`;
    }

    return localizedFormat;
}

export function getLanguageCode() {
    return storedLanguageCode;
}

export function getDateTimeFormat(needTime?: boolean) {
    return needTime ? storedDateTimeFormat : storedDateFormat;
}

export function getStoredIsDebugModeEnabled() {
    return storedIsDebugModeEnabled;
}

export function areLabelsLoaded() {
    return labelsLoaded;
}

const replacer = (text: string, replacementValues: readonly string[]) => {
    return replacementValues.reduce((accumulator, replacementValue, replacementIndex) => {
        return accumulator.replace(`{${replacementIndex}}`, replacementValue);
    }, text);
};

function getFirstLetterCaseInsensitive<T>(key: string) {
    const firsLetterCaseKey = key.charAt(0).toLowerCase() + key.slice(1);

    let result = storedLabelsByKey[firsLetterCaseKey];

    if (result) {
        result = result.charAt(0).toUpperCase() + result.slice(1);
    }

    return result;
}
