angular
    .module("app")
    .service(
        "SkinService",
        function(
            $rootScope,
            $timeout,
            $localStorage,
            $q,
            AppService,
            sqPlugin,
            SQEvents,
            SQConstants
        ) {
            this.loadSkins = function() {
                var deferred = $q.defer();
                var allSkins = sqPlugin.getPlugins("Skin");
                instance.skins.length = 0;

                for (var i = 0; i < allSkins.length; i++) {
                    instance.skins.push(allSkins[i]);
                }

                if (isMainApp() || isAlgoWizard()) {
                    getCurrentSkin();
                    deferred.resolve();
                } else {
                    if(window.top.getCurrentSkin) processSkinChange(window.top.getCurrentSkin());
                    deferred.resolve();
                }

                return deferred.promise;
            };

            function getCurrentSkin() {
                if (isMainApp() && jQuery.isEmptyObject(SQConstants.getSettings())) {
                    SQConstants.loadAll().then(function() {
                        getCurrentSkin();
                    });
                    return;
                }
                if (SQConstants.getSettings() && SQConstants.getSettings().skin) {
                    for (let i = 0; i < instance.skins.length; i++) {
                        let skin = instance.skins[i];
                        if (skin.name == SQConstants.getSettings().skin) {
                            $storage.skin = skin;
                            processSkinChange(skin, true);
                            break;
                        }
                    }
                } else if ($storage.skin) {
                    processSkinChange($storage.skin, true);
                } else {
                    var curSkin;
                    for (let i = 0; i < instance.skins.length; i++) {
                        let skin = instance.skins[i];
                        if (skin.name == "Light skin") {
                            curSkin = skin;
                        }
                    }

                    curSkin = curSkin || instance.skins[0];
                    processSkinChange(curSkin, true);
                }
            }

            this.changeSkin = function(skin, dontSave) {
                processSkinChange(skin, dontSave);
                SQEvents.notifyListeners(SQEvents.get("SKIN_CHANGED"), {
                    skin: skin,
                    dontSave: dontSave,
                });

                window.top.AWSkin = skin;
                if (window.top.AWSkinChanged) {
                    window.top.AWSkinChanged(skin);
                }
                if (window.top.SQ4BSkinChanged) {
                    window.top.SQ4BSkinChanged(skin);
                }
            };

            function processSkinChange(skin, dontSave) {
                var filePaths = skin.filePaths;
                if (filePaths == undefined) {
                    return;
                }

                var styleSheets = document.styleSheets;
                for (let i = 0; i < styleSheets.length; i++) {
                    if (styleSheets[i].title == "skinLink") {
                        styleSheets[i].disabled = true;
                        break;
                    }
                }

                if (isAlgoWizard()) {
                    applyStylesFromAWCloud();
                } else {
                    $(".skinLink").remove();
                    for (let i = 0; i < filePaths.length; i++) {
                        var filePath = filePaths[i];
                        $("head").append(
                            $("<link/>", {
                                rel: "stylesheet",
                                href: filePath,
                                type: "text/css",
                                title: "skinLink",
                                class: "skinLink",
                            })
                        );
                    }
                }

                if (!dontSave && (isMainApp() || isAlgoWizard())) {
                    $storage.skin = skin;
                    AppService.saveSetting("skin", skin.name);
                }

                setSkinData(instance.selectedSkin, skin);
            }

            function applyStylesFromAWCloud() {
                //remove all skin styles

                var iframeHead = $("head").get(0);
                for (let i = iframeHead.childNodes.length - 1; i >= 0; i--) {
                    let childElem = iframeHead.childNodes[i];
                    if (childElem.nodeName.toLowerCase() != "style") continue;
                    if (getAttrStringValue(childElem, "title") == "skinLink") {
                        iframeHead.removeChild(childElem);
                    }
                }

                //add parent skin styles
                var parentStyleSheets = parent.document.styleSheets;
                var cssString = "";
                for (let i = 0, count = parentStyleSheets.length; i < count; i++) {
                    let parentStyleSheet = parentStyleSheets[i];
                    if (parentStyleSheet.title != "skinLink" && parentStyleSheet.title != "extraSkin") continue;

                    try {
                        if (parentStyleSheet.cssRules) {
                            var cssRules = parentStyleSheet.cssRules;

                            for (var j = 0, countJ = cssRules.length; j < countJ; j++) {
                                cssString += cssRules[j].cssText;
                            }
                        } else {
                            cssString += parentStyleSheet.cssText; // IE8 and earlier
                        }
                    } catch (err) {
                        console.error(err, parentStyleSheet);
                    }
                }

                if (cssString === "") return;

                var style = document.createElement("style");
                style.type = "text/css";
                style.title = "skinLink";
                try {
                    style.innerHTML = cssString;
                } catch (ex) {
                    style.styleSheet.cssText = cssString; // IE8 and earlier
                }

                iframeHead.appendChild(style);
            }

            function setSkinData(target, source) {
                target.name = source.name;
                target.filePaths = angular.copy(source.filePaths);
                target.extensionPoint = source.extensionPoint;
                target.position = source.position;
            }

            var instance = this;
            var $storage = $localStorage.$default();

            this.skins = [];
            this.selectedSkin = {};

            if (!isMainApp() && !isAlgoWizard() && !isCodeEditor()) {
                window.top.addListener(
                    "SkinService-" + window.appConfig.product,
                    SQEvents.get("SKIN_CHANGED"),
                    function(event, data) {
                        processSkinChange(data.skin, data.dontSave);
                    }
                );
            } else {
                window.getCurrentSkin = function() {
                    return instance.selectedSkin;
                };

                return "Light skin"
            }

            window.changeSkin = instance.changeSkin;
        }
    );