"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RoomstayTheme = void 0;
const ROP = __importStar(require("@juggle/resize-observer"));
const Sentry = __importStar(require("@sentry/browser"));
const dayjs_1 = __importDefault(require("dayjs"));
const isSameOrAfter_1 = __importDefault(require("dayjs/plugin/isSameOrAfter"));
const isSameOrBefore_1 = __importDefault(require("dayjs/plugin/isSameOrBefore"));
const i18next_1 = __importDefault(require("i18next"));
const react_i18next_1 = require("react-i18next");
const LanguageProvider_1 = require("./LanguageProvider");
const Color_1 = require("../util/Color");
if (typeof ResizeObserver === 'undefined') {
    window.ResizeObserver = ROP.ResizeObserver;
}
var RoomstayTheme;
(function (RoomstayTheme) {
    RoomstayTheme["Medium"] = "medium";
    RoomstayTheme["Light"] = "light";
})(RoomstayTheme || (exports.RoomstayTheme = RoomstayTheme = {}));
class RoomstayThemeEngine {
    constructor() {
        this.currentCompany = null;
        this.ScriptContainer = null;
        this.StyleContainer = null;
        this.selectedLang = LanguageProvider_1.Language.en_us;
        // TODO This needs to be changed, not ideal to just check for localhost
        this.isLocalhost = location.hostname === 'localhost';
        // TODO: This needs to be refactored to not be a fixed string.
        this.ThemeType = RoomstayTheme.Light;
        this.ExternalStyles = [];
        this.ExternalScripts = ['https://js.verygoodvault.com/vgs-collect/1/AC7dReJwJ6EWF1L9FHdcCw7n.js'];
        this.translation = null;
        this.changeCompany = (newCompany) => {
            this.currentCompany = newCompany;
            this.registerStyles(newCompany.colors);
        };
        this.changeTheme = (profile) => __awaiter(this, void 0, void 0, function* () {
            const styleOverrides = this.createElementOrReuseExisting('style', 'engine-styles');
            styleOverrides.setAttribute('rel', 'preload');
            styleOverrides.innerHTML = `
        :root {
            ${(0, Color_1.getAccentOverrideStyleContent)(profile)}
        }`;
        });
        this.registerStyles = (profile) => __awaiter(this, void 0, void 0, function* () {
            console.log('Loading custom Theme Styles');
            if (profile) {
                this.changeTheme(profile);
            }
            this.ExternalStyles.forEach((url, index) => {
                const style = this.createElementOrReuseExisting('link', `engine-external-style-${index}`);
                style.setAttribute('rel', 'stylesheet');
                style.setAttribute('href', this.getAssetUrl() + url);
            });
        });
        this.getAssetUrl = () => {
            return ASSET_URL;
        };
        this.getImageAssetUrl = (url = '') => {
            return this.getAssetUrl() + 'assets/img/' + url;
        };
        /**
         * Detects if URL is absolute, and needs to be
         * @param url string
         */
        this.wrapAssetUrl = (url) => {
            if (url.match(/^(?:[a-z]+:)?\/\//)) {
                return url;
            }
            return this.getAssetUrl() + url;
        };
        this.registerScripts = () => __awaiter(this, void 0, void 0, function* () {
            this.ExternalScripts.forEach((url, index) => {
                this.loadScript(url, `legacy-${index}`);
            });
        });
        this.loadScript = (src, name, alwaysExecute = false, timeout = 5000) => new Promise((resolve, reject) => {
            var _a;
            const container = this.EngineContainer;
            const existingScript = container.querySelector(`script[name="roomstay-script-${name}"]`);
            if (existingScript) {
                if (alwaysExecute) {
                    existingScript.remove();
                }
                else {
                    resolve();
                    return;
                }
            }
            const cleanup = () => {
                clearTimeout(timer);
                script.removeEventListener('load', onLoad);
                script.removeEventListener('error', onError);
            };
            const onLoad = () => {
                cleanup();
                resolve();
            };
            const onError = () => {
                cleanup();
                reject(new Error(`Failed to load script "${src}"`));
            };
            const script = document.createElement('script');
            script.setAttribute('name', `roomstay-script-${name}`);
            script.setAttribute('src', src);
            script.addEventListener('load', onLoad);
            script.addEventListener('error', onError);
            // Guarantee that we won't get stuck here forever
            const timer = setTimeout(onError, timeout);
            // Append the script twice for some reason
            container.appendChild(script);
            (_a = this.ScriptContainer) === null || _a === void 0 ? void 0 : _a.appendChild(script);
        });
        this.createElementOrReuseExisting = (type, name) => {
            const container = this.EngineContainer;
            const findingElement = container.querySelector(`${type}[name="roomstay-${name}"]`);
            if (findingElement) {
                return findingElement;
            }
            else {
                const target = document.createElement(type);
                target.setAttribute('name', `roomstay-${name}`);
                container.appendChild(target);
                return target;
            }
        };
        this.init = () => __awaiter(this, void 0, void 0, function* () {
            dayjs_1.default.extend(isSameOrBefore_1.default);
            dayjs_1.default.extend(isSameOrAfter_1.default);
            if (i18next_1.default) {
                this.translation = yield i18next_1.default.use(react_i18next_1.initReactI18next).init({
                    interpolation: { escapeValue: false },
                    lng: LanguageProvider_1.Language.en_us,
                    resources: LanguageProvider_1.LanguageProvider.getI18nMappedLanguages(),
                });
            }
            if (!this.isLocalhost) {
                Sentry.init({
                    dsn: 'https://3bfba949561e48f1862c843ce8254a2d@o398412.ingest.sentry.io/5254086',
                    beforeSend: (event, hint) => {
                        var _a, _b;
                        event.tags = (_a = event.tags) !== null && _a !== void 0 ? _a : { logger: '_default_' };
                        try {
                            if ((hint === null || hint === void 0 ? void 0 : hint.originalException) instanceof Error) {
                                if (((_b = hint.originalException.stack) === null || _b === void 0 ? void 0 : _b.indexOf('www.googletagmanager.com/gtm.js?id=')) > -1) {
                                    event.tags.logger = 'gtm';
                                    event.level = Sentry.Severity.Warning;
                                }
                            }
                        }
                        catch (ex) {
                            console.log(ex);
                        }
                        return event;
                    },
                });
            }
            this.reloadScriptAndStyleContainers();
        });
        this.reloadScriptAndStyleContainers = () => {
            this.StyleContainer = this.createElementOrReuseExisting('div', 'style-container');
            this.ScriptContainer = this.createElementOrReuseExisting('div', 'script-container');
            this.ScriptContainer.innerHTML = '';
            this.StyleContainer.innerHTML = '';
            this.registerStyles();
        };
        console.log(`Initializing Roomstay Booking Engine v${exports.RS_VERSION}`);
    }
}
exports.default = new RoomstayThemeEngine();
//# sourceMappingURL=RoomstayThemeEngine.js.map