(function (window) {
    'use strict';

    var DIGIT_SETS = {
        persian: '۰۱۲۳۴۵۶۷۸۹',
        arabic: '٠١٢٣٤٥٦٧٨٩',
        devanagari: '०१२३४५६७८९',
        thai: '๐๑๒๓๔๕๖๗๘๙',
        western: '0123456789',
    };

    var KNOWN_SCRIPTS = ['western', 'arabic', 'persian', 'devanagari', 'thai'];

    function isKnownDigitScript(script) {
        return KNOWN_SCRIPTS.indexOf(script) >= 0;
    }

    function readDigitScript() {
        var admin = document.getElementById('zertiAdmin');
        if (admin) {
            var formatAttr = admin.getAttribute('data-zerti-digits-format');
            if (formatAttr && formatAttr !== 'auto') {
                if (isKnownDigitScript(formatAttr)) {
                    return formatAttr;
                }
            }
            var scriptAttr = admin.getAttribute('data-zerti-digit-script');
            if (isKnownDigitScript(scriptAttr)) {
                return scriptAttr;
            }
        }

        var cfg = window.zertiDigitLocale;
        if (cfg && typeof cfg.format === 'string' && cfg.format !== '' && cfg.format !== 'auto') {
            return cfg.format;
        }
        if (cfg && typeof cfg.script === 'string' && cfg.script !== '') {
            return cfg.script;
        }

        return 'persian';
    }

    function shouldLocalizeDigits() {
        return readDigitScript() !== 'western';
    }

    function localizeDigits(str) {
        var script = readDigitScript();
        if (script === 'western') {
            return String(str);
        }

        var digits = DIGIT_SETS[script] || DIGIT_SETS.persian;
        return String(str).replace(/[0-9]/g, function (d) {
            return digits.charAt(parseInt(d, 10));
        });
    }

    /** Localize digits in HTML without breaking tags or entities (e.g. &#36;). */
    function localizeDigitsInHtml(str) {
        var script = readDigitScript();
        if (script === 'western') {
            return String(str);
        }

        var html = String(str);
        var tokens = [];
        var protectedHtml = html.replace(/&(?:#x?[0-9a-fA-F]+|[a-zA-Z][a-zA-Z0-9]+);|<[^>]+>/g, function (match) {
            // Private-use char — no ASCII digits so localizeDigits cannot corrupt the placeholder.
            var key = '\uFFFF' + String.fromCharCode(0xe000 + tokens.length) + '\uFFFF';
            tokens.push({ key: key, value: match });
            return key;
        });
        var localized = localizeDigits(protectedHtml);
        tokens.forEach(function (token) {
            localized = localized.split(token.key).join(token.value);
        });

        return localized;
    }

    function toLatinDigits(str) {
        return String(str).replace(/[۰-۹٠-٩०-९๐-๙]/g, function (ch) {
            var name;
            for (name in DIGIT_SETS) {
                if (name === 'western') {
                    continue;
                }
                var idx = DIGIT_SETS[name].indexOf(ch);
                if (idx >= 0) {
                    return String(idx);
                }
            }

            return ch;
        });
    }

    window.zertiDigitLocale = window.zertiDigitLocale || {};
    window.zertiLocalizeDigits = localizeDigits;
    window.zertiLocalizeDigitsInHtml = localizeDigitsInHtml;
    window.zertiToLatinDigits = toLatinDigits;
    window.zertiShouldLocalizeDigits = shouldLocalizeDigits;
    window.zertiLatinToPersianDigits = localizeDigits;
    window.zertiPersianToLatinDigits = toLatinDigits;
})(window);
