var Apis = {

    blockImages: [],

    data: {},

    refresh(){

        Api.post('/v1/apis/refresh', {
            code: Apis.getApi()
        }).then(res => {

            console.log(res);

        });

    },

    // @todo Verificar uso fora da nuvemshop
    checkUrl(that){

        let url = $(that).val();

        if(!url) return;

        if(url.match(/http:\/\//g)) url = url.replace('http://', 'https://');

        if(!url.match(/https:\/\//g)) url = 'https://' + url;

        // Remove coisas do pathurl
        url = url.split('?')[0];
        
        $(that).val(url);

    },

    catalog: {

        sync(){

            Api.post('/v1/apis/catalog/sync', {
                api: Apis.getApi()
            }).catch(e => {

                Alerts.ok(e);

            });

        },

        clear(){

            Alerts.confirm('Deseja apagar todos os produtos dessa integração?', 'Não será apagado da plataforma, apenas de dentro da IndexaAI').then(() => {

                Api.delete('/v1/apis/' + Apis.getApi() + '/catalog').then(() => {

                    Catalog.reload();

                });

            });

        }

    },

    categoriesById: {},

    oninput: {

        tray(){

            let url = $('input[name=credential2]').val();

            let adjusted = new URL(url);

            url = adjusted.origin;

            $('input[name=credential2]').val(url);

        },

        vtex(){

            let url = $('input[name=credential3]').val();

            let accountName = '';

            // Se a url finalizar com um desses dois parametros: vtexcommercestable.com ou vtexcommercestable.com.br
            if(url.match(/vtexcommercestable.com/ || /vtexcommercestable.com.br/)){

                accountName = url.split('.')[0].split('//')[1];

            }

            // Se terminar com myvtex.com
            if(url.match(/myvtex.com/)){

                accountName = url.split('.')[0].split('//')[1].split('-')[0];

                // Se tiver production--, vamos usar o que está depois do --, sem o .myvtex.com
                if(url.match(/production--/)){

                    accountName = url.split('--')[1];

                    console.log('Account name', accountName);

                    accountName = accountName.replace('.myvtex.com', '');

                }

            }

            // Remove o webservice- do nome da conta
            accountName = accountName.replace('webservice-', '');

            $('input[name=credential4]').val(accountName);

        }

    },

    // Essa função é chamada quando o usuário altera o valor de um campo
    oninputForm(){

        let platform = $('input[name=platform]').val();

        if(Apis.oninput[platform]) Apis.oninput[platform]();

    },

    onCache: null,

    setApi(api){

        let oldApi = Apis.getApi();

        localStorage.setItem('api', api);

        Dashboard.setConfig({
            api: api
        });

        $('.apis .api').removeClass('active');

        if($('.apis [alt=' + api + ']').length){

            $('.apis').prepend($('.apis [alt=' + api + ']'));

            $('.apis [alt=' + api + ']').addClass('active');

            

        }

        if(Apis.onCache != api) {
            Apis.requestSync();
        }

        Apis.onCache = api;

        if(oldApi == api) return;

        // Recarrega a página, para que ajustes visuais sejam feitos
        Nav.trigger(location.pathname);

    },

    syncing: null,
    synced: null,

    requestingPromise: null,
    resolveRequesting: null,

    async requestSync(){

        Apis.requestingPromise = new Promise((resolve, reject) => {

            Apis.resolveRequesting = resolve;

        });

        await Dashboard.connected;

        Dashboard.socket.emit('api sync', Apis.getApi());

        $('.apis .api[alt=' + Apis.getApi() + ']').addClass('unloaded');
        $('.apis .api[alt=' + Apis.getApi() + ']').prop('title', 'Sincronizando categorias, atributos e outras informações');

    },

    selectColumn(kind, api, column, subcolumn){

        let config = Apis.getSelectedColumns();

        if(!config[kind]) config[kind] = {};

        if(!config[kind][api.code]) config[kind][api.code] = {};

        if(!config[kind][api.code][column]) config[kind][api.code][column] = [];

        config[kind][api.code][column].push(subcolumn);

        Dashboard.setConfig({
            columns: config
        });

    },

    unselectColumn(kind, api, column, subcolumn){

        let config = Apis.getSelectedColumns();

        if(!config[kind]) config[kind] = {};

        if(!config[kind][api.code]) config[kind][api.code] = {};

        if(!config[kind][api.code][column]) config[kind][api.code][column] = [];

        config[kind][api.code][column] = config[kind][api.code][column].filter(col => col != subcolumn);

        Dashboard.setConfig({
            columns: config
        });

    },

    getSelectedColumns(){

        let dashboardConfig = Dashboard.getConfig();
        let branch = Dashboard.getBranch();

        if(!dashboardConfig[branch.id]) return {};

        dashboardConfig = dashboardConfig[branch.id];

        if(dashboardConfig.columns) return dashboardConfig.columns;

        return {}

    },

    getColumns(kind){

        let selected = Apis.getSelectedColumns();
        let api = Apis.getApi();

        if(selected[kind] && selected[kind][api]){

            return selected[kind][api];

        }

        return {};

    },

    // Baixa o modelo de api, com base nas colunas selecionadas da atual api
    // @todo Baixar modelo quando não há integrações
    downloadModel(kind){

        if(kind == 'creation_skus') return Helpers.download('/modelo_variantes.xlsx', 'Modelo de Variantes');

        // switch(kind){

        //     case 'enhancing':

        //         // Helpers.download('/modelo_enriquecimento.xlsx', 'Modelo de Enriquecimento');

        //         Enhancement.mass.model();

        //     break;
        //     case 'creation':

        //         Helpers.download('/model.xlsx', 'Modelo de Cadastro');

        //     break;
        //     case 'creation_skus':

        //         Helpers.download('/modelo_variantes.xlsx', 'Modelo de Variantes');

        //     break;

        // }

        // return;

        // @todo Descomentar, está comentado no atual momento, pois um cliente reclamou de planilha corrompida

        let modelName = I18n.get('Modelo de cadastro');

        if(kind == 'enhancing') modelName = I18n.get('Modelo de enriquecimento');

        // Código de Referencia	Ean	Nome	Marca	Peso	Altura do produto	Largura do produto	Comprimento do produto	Altura da embalagem	Largura da embalagem	Comprimento da embalagem	Quantidade por pacote	Categoria	Cor	Material	Voltagem	Tamanho	Coleção
        let defaultColumns = [
            'Código de Referência',
            'Ean',
            'Nome',
            'Marca',
            'Peso',
            'Altura do produto',
            'Largura do produto',
            'Comprimento do produto',
            'Altura da embalagem',
            'Largura da embalagem',
            'Comprimento da embalagem',
            'Quantidade por pacote',
            'Categoria',
            'Cor',
            'Material',
            'Voltagem',
            'Tamanho',
            'Coleção'
        ];

        if (kind === 'enhancing') {
            defaultColumns = Core.idFields[Apis.getPlatform()];
        }

        let selectedColumns = Apis.getColumns(kind);

        let columns = [...defaultColumns];

        for (let block in selectedColumns) {
            for (let column in selectedColumns[block]) {
                columns.push(selectedColumns[block][column] + ' *');
            }

        }

        Helpers.makeExcel([columns], modelName + '.xlsx');
    },

    configColumns(kind){

        // Caso não tenha uma API configurada
        if(!Dashboard.info?.apis?.length){

            return Alerts.blank('', 'Para configurar as colunas do modelo de cadastro é necessário ter uma integração configurada<br><br><button onclick="Dashboard.configure()">Integrar minha loja</button>');

        }

        // Vamos pegar a api selecionada
        let selected = Dashboard.info.apis.filter(api => api.code == Apis.getApi())[0];

        let columnCount = 0;

        for(let column in selected.columns){

            columnCount += selected.columns[column].length;

        }

        let msg = 'As colunas abaixo são compatíveis com a plataforma ' + selected.name + '<br><div class="columns-holder"></div>';

        // Caso não tenha colunas
        if(!columnCount) msg = 'A plataforma ' + selected.name + ' atualmente não possui colunas compatíveis';

        let modal = Alerts.ok('Colunas compatíveis', msg);

        let columns = $(modal).find('.columns-holder');

        let selectedColumns = Apis.getColumns(kind);

        // Vamos passar por cada blcoo de coluna
        for(let column in selected.columns){

            // Uma versão com letra maiúscula, por motivos de i18n
            let columnCapitalize = column.charAt(0).toUpperCase() + column.slice(1);

            // Caso não tenha nada nessa coluna, não vamos exibi-la
            if(!selected.columns[column].length) continue;

            columns.append('<h3>' + I18n.get(columnCapitalize) + '</h3>');
            columns.append('<br>');

            let list = $('<div class="columns-list"></div>');

            let block = selectedColumns[column] || [];

            // Passa por cada coluna do bloco
            for(let subcolumn in selected.columns[column]){

                let columnName = selected.columns[column][subcolumn];
                let apiColumnElm = $('<span class="api-column">' + columnName + '</span>');

                if(block.includes(columnName)) apiColumnElm.addClass('selected');

                apiColumnElm.click(() => {

                    if(apiColumnElm.hasClass('selected')){

                        Apis.unselectColumn(kind, selected, column, columnName);

                        apiColumnElm.removeClass('selected');

                    } else{

                        Apis.selectColumn(kind, selected, column, columnName);

                        apiColumnElm.addClass('selected');

                    }

                });

                list.append(apiColumnElm);

            }

            columns.append(list);

        }

    },

    async sync(data){

        if(!data) return;

        for(let api in data){

            Apis.data[api] = data[api];

            // Remove o loading de sincronização
            $('.apis .api[alt=' + api + ']').removeClass('unloaded');
            $('.apis .api[alt=' + api + ']').prop('title', api.split('_')[1]);

        }

        Apis.categoriesById = {};

        let apiData = Apis.getData();

        let categories = [];

        if(apiData){

            categories = apiData.categories;

            for(let category in categories){

                Apis.categoriesById[categories[category].id] = categories[category];
                
            }

        }

        Apis.synced();
        Apis.resolveRequesting();

    },

    getData(){
            
        return Apis.data[Apis.getApi()];

    },

    async existApis(){
        
        await Dashboard.ready;

        return Dashboard.info?.apis && Dashboard.info.apis.length > 0
    },

    async getCategories(){

        if(!await Apis.existApis()) return [];

        await Apis.syncing;

        let data = await Apis.getData();

        if(!data) return false;
        
        return data.categories || [];

    },

    // @todo Verificar se não é melhor usar diretamente o setApi
    setByCode(code){

        let api = Dashboard.info.apis.filter(api => api.code == code)[0];

        if(!api) return;

        Apis.setApi(api.code);        

    },

    setByFirstPlatform(platform){

        let api = Dashboard.info.apis.filter(api => api.code.split('_')[0] == platform)[0];

        if(!api) return;

        Apis.setApi(api.code);

    },

    // @deprecated due Apis.getAll
    get(){

        let apis = [];

        if(!Dashboard.info.apis) return apis;

        Dashboard.info.apis.forEach(api => {

            apis.push(api.code);

        });

        return apis;

    },

    getAll(){

        return Dashboard.info.apis || [];

    },

    setApiInfoBasedOnBranch(){

        let config = Dashboard.getConfig();

        let branch = Dashboard.getBranch();

        if(!branch) return;

        if(!config) return;

        if(!config[branch.id]) return;

        try{

            let api = config[branch.id].api;

            localStorage.setItem('api', api);

        } catch(e){

            console.log(e);

        }

    },

    getApi(){

        let api = localStorage.getItem('api');

        // Se não tiver na interface, vamos invalidar o localStorage
        if(api && !Apis.get().includes(api)) localStorage.removeItem('api');

        // Quando não tem nenhuma selecionada
        if(!api) {

            api = localStorage.getItem('api');
            
        }

        if(!api) return false;

        return api;

    },

    getPlatform(){

        let api = Apis.getApi();

        if(!api) return false;

        return api.split('_')[0];

    },

    clearBranchLocalInfo(){

        localStorage.removeItem('api');
        localStorage.removeItem('enhancefield');

    },

    getInfo(api_id){

        return Api.get('/v1/apis/' + api_id + '/info');

    },

    async openSyncSettings(code){

        let apiInfo = Apis.getApiInfo(code);

        let info = await Apis.getInfo(apiInfo.api_id);

        let modal = Alerts.blank('Configurações da plataforma <span class="yellow">' + apiInfo.code.split('_')[1] + '</span>');

        Dashboard.paramState({
            'api-settings': apiInfo.code
        }, {
            modal: modal
        });

        let settings = $('<div class="settings"><br></div>');

        $(modal).find('.dialog-body').append(settings);

        if(!Core.syncSettings[apiInfo.name]) {

            settings.append('<p>Não há configurações disponíveis para essa plataforma</p>');

        } else{

            Object.keys(Core.syncSettings[apiInfo.name]).forEach((key) => {

                let setting = Core.syncSettings[apiInfo.name][key];
    
                let settingElm = $('<div class="setting round-card"></div>');
    
                settingElm.append('<h3>' + I18n.get(setting.label) + '</h3><br>');
    
                let lastSync = 'Nunca sincronizado';
                let qtd = 0;
    
                let entityInfo = info[key];
    
                if(entityInfo){
    
                    let date = new Date(entityInfo.last_update);
    
                    lastSync = 'Última sincronização: ' + Helpers.getBeautifulDate(date) + ', ' + Helpers.getSimpleHour(date);
                    qtd = entityInfo.count || 0;
    
                }
    
                let syncButton = $('<p><button>' + I18n.get('Sincronizar') + '</button>&nbsp;&nbsp;&nbsp;<small>' + lastSync + '</small></p>');
    
                syncButton.find('button').click(() => {
    
                    let loading = Helpers.loading(syncButton.find('button'));
    
                    // syncFunctions: ['brands'],
                    // total: totalBrands
    
                    Styles.onProp('syncFunctions', (progress) => {
    
                        // Muda o texto do botão pra sincronizando
                        syncButton.find('button').text(I18n.get('Sincronizando'));
    
                        console.log(progress);
    
                        if(progress?.syncFunctions){
    
                            if(progress.syncFunctions.includes(key)){
    
                                let total = progress.total || 0;
    
                                // Vamos mudar o texto de itens
                                $(modal).find('.settings .setting p.items-count').text(total + ' ' + I18n.get('itens'));
    
                            }
                            
                        }
    
                    });
    
                    Api.post('/v1/apis/' + apiInfo.code + '/sync/' + key).then(() => {
    
                        loading.reset();
    
                        // Vamos fechar esse modal e abrir novamente
                        modal.close();
    
                        Apis.openSyncSettings(apiInfo.code);
    
                    }).catch(e => {
    
                        loading.reset();
    
                        Alerts.ok('Erro', e);
    
                    });
    
                });
    
                settingElm.append('<p class="items-count">' + qtd + ' ' + I18n.get('itens') + '</p>');
    
                settingElm.append('<br>');
                settingElm.append(syncButton);
    
                settings.append(settingElm);
                settings.append('<br>');
    
            });
    
        }

        // Exibe um botão de baixar tudo, button.secondary /img/icons/export-underline.svg e um de importar, button.primary /img/icons/import-underline.svg

        let buttons = $('<div class="buttons"></div>');

        let exportButton = $('<button class="secondary" title="' + I18n.get('Exportar') + '"><img src="/img/icons/export-underline.svg"> Exportar</button>');

        exportButton.click(() => {

            Alerts.ok('Exportar', 'Aqui você poderá exportar dados da plataforma para um arquivo .xlsx');

        });

        let importButton = $('<button class="secondary" title="' + I18n.get('Importar') + '"><img src="/img/icons/import-underline.svg"></button>');

        importButton.click(() => {

            Alerts.ok('Importar', 'Aqui você conseguirá importar dados para a plataforma sem precisar de uma integração, além de poder importar dados caso já tenha uma integração configurada.');

        });

        if(Apis.infosByApi[apiInfo.name]) {

            let additionalSettingsBtn = $('<button class="secondary">' + I18n.get('Configurações adicionais') + '</button>');

            additionalSettingsBtn.click(() => {

                Apis.infosByApi[apiInfo.name](apiInfo);

            });
            
            settings.append('<br>');
            settings.append(additionalSettingsBtn);
            
        }

        // buttons.append(exportButton);
        // buttons.append(importButton);

        // settings.append(buttons);

    },

    testOnLoad: ['publicapi'],

    openSettings(code){

        let platform = code.split('_')[0];

        if(platform == 'bling') platform = 'blingv2';
        if(platform == 'blingv3') platform = 'bling';

        Apis.setApi(code);

        Nav.to('/dashboard/platforms/' + platform);

    },

    loadInfo(){

        let data = Dashboard.info;

        if(Apis.testOnLoad.includes($('[name=platform]').val())){

            // Se tiver algum publicapi, não vamos testar automaticamente
            if(data.apis && data.apis.length && data.apis.find(api => api.name == 'publicapi')){

                $('.pos-authorize').show();
                $('.hide-after-test').hide();

                Apis.loadPreferences();

            } else{

                Apis.actionTest();

            }

        }

        if(data.apis && data.apis.length){

            $('.apis .configure').hide();

            $('.profile .apis .api').remove();

            data.apis.forEach((api) => {

                let name = api.code.split('_')[1];

                let apiElm = $('<div class="api" alt="' + api.code + '" title="' + api.code + '"><img src="/img/icons/' + api.name + '.png" ></div>');

                if(api.status == 'errored') apiElm.addClass('errored');

                if(api.message) apiElm.attr('title', api.message);

                // Vamos sempre exibir o código da integração
                apiElm.append($('<span class="api-title">' + name + '</span>'));

                apiElm.append(Helpers._assets.animationSVGWidth30);

                apiElm.append($('<img src="img/icons/settings.svg" class="api-settings">'));

                $(apiElm).find('.api-settings').off('click');
                $(apiElm).find('.api-settings').click((event) => {

                    event.stopPropagation();

                    Apis.openSettings(api.code);

                });

                $('.profile .apis').prepend(apiElm);

                $(apiElm).off('click');
                $(apiElm).click(() => {

                    Apis.setApi(api.code);

                    $('.apis .api').removeClass('active');
                    $(apiElm).addClass('active');

                    if(api.status == 'errored'){

                        let platform = api.name;

                        // @todo Adicionar ao core
                        // No caso do bling, vamos traduzir pra um alias
                        if(platform == 'blingv3') platform = 'bling';

                        Nav.to('/dashboard/platforms/' + platform);
                        
                    }

                });

            });

            let activeApi = Apis.getApi();

            // Verify if activeApi is valid
            if(activeApi && !data.apis.find(api => api.code == activeApi)){

                activeApi = false;

            }

            if(!activeApi) $('.apis .api').first().click();
            else{

                $('[alt=' + activeApi + ']').addClass('active');

                // Apenas para forçar o recarregamento de informações importantes
                Apis.setApi(activeApi);
                
            }

        } else{

            $('.apis .configure').show();
            
        }

        $('.apis').show();

    },

    autoSaveAfterTest: {
        blingv3: true,
        publicapi: true
    },

    oauth2: {

        // @dry E9A43M
        tray(credentials){

            localStorage.removeItem('api_tray_code');

            return Api.post('/api/branch/configure/oauth2/tray', credentials).then(url => {

                if(url.url){

                    localStorage.waiting_tray_code = true;

                    window.open(url.url);

                    $('.loading-notify').empty();
                    $('.loading-notify').append(Helpers._assets.animationSVGWidth30);

                    $('.loading-notify').append(`<span> Aguardando credenciais</span>`);
                    $('.loading-notify').append(`<span class="help" data-tooltip="Se certifique já estar logado na tray ao clicar em autorizar.<br><br>As vezes a falta de www no domínio pode impedir a integração.<br><br>Clique novamente em autorizar caso a tray não redirecione a esta janela."></span>`);
                    $('.loading-notify').show();

                    let interval = setInterval(() => {

                        let code = localStorage.getItem('api_tray_code');

                        if(code){

                            clearInterval(interval);

                            try{

                                code = JSON.parse(code);

                            } catch(e){

                                throw e;

                            }

                            $('.loading-notify').empty();
                            $('.loading-notify').hide();

                            $('.authorize').hide();
                            $('.onboarding-actions .save').show();
        
                            $('input[name=credential3]').val(code.api_address);
                            $('input[name=credential4]').val(code.code);

                            $('.pos-authorize').show();

                            localStorage.removeItem('api_tray_code');

                            Apis.save();

                        }

                    }, 1000);                            

                    return;

                }

            });

        },

        // @dry E9A43M
        nuvemshop(credentials){

            localStorage.removeItem('api_nuvemshop_code');

            return Api.post('/api/branch/configure/oauth2/nuvemshop', credentials).then(url => {

                let interval = setInterval(() => {

                    let code = localStorage.getItem('api_nuvemshop_code');

                    if(code){

                        clearInterval(interval);

                        $('input[name=credential1]').val(code);

                        localStorage.removeItem('api_nuvemshop_code');

                        $('.authorize').hide()
                        $('.pos-authorize').show();

                        // @todo Fazer isso de um modo mais padronizado
                        $('.onboarding-actions .save').show();
                        
                        Apis.save();

                    }

                }, 1000);

                if(url.url){

                    window.open(url.url);

                }

            });

        },

        // @dry E9A43M
        blingv3(credentials){

            localStorage.removeItem('api_bling_code');

            return Api.post('/api/branch/configure/oauth2/blingv3', credentials).then(url => {

                let interval = setInterval(() => {

                    let code = localStorage.getItem('api_bling_code');

                    if(code){

                        clearInterval(interval);

                        $('input[name=credential1]').val(code);

                        localStorage.removeItem('api_bling_code');

                        Apis.actionTest();

                    }

                }, 1000);

                if(url.url){

                    window.open(url.url);

                    localStorage.waiting_bling_code = true;

                }

            });

        },

        mercadolivre(credentials) {
            localStorage.removeItem('api_mercadolivre_code');

            return Api.post('/api/branch/configure/oauth2/mercadolivre', credentials).then(url => {

                let interval = setInterval(() => {

                    let code = localStorage.getItem('api_mercadolivre_code');

                    if(code){

                        clearInterval(interval);

                        $('input[name=credential1]').val(code);

                        localStorage.removeItem('api_mercadolivre_code');

                        $('.authorize').hide()
                        $('.pos-authorize').show();

                        // @todo Fazer isso de um modo mais padronizado
                        $('.onboarding-actions .save').show();
                        
                        Apis.save();
                    }

                }, 1000);

                if(url.url){

                    window.open(url.url);

                }

            });
        }

    },

    tested: {},
    testing: {},

    test(form){

        let platform = form.find('[name=platform]').val();

        let credentials = {};
        let flag = false;
        let openOauth = false;

        form.find($('input')).each(function(){

            if(flag) return;

            credentials[$(this).attr('name')] = $(this).val();

            if(!$(this).val() && $(this).attr('type') != 'hidden'){

                if($(this).attr('data-oauth2')){

                    return openOauth = true;

                }

                flag = true;

                $(this).focus();

            }

        });

        if(flag) return Promise.reject('Preencha todos os campos');

        if(openOauth){

            return Apis.oauth2[credentials.platform](credentials);

        }

        // Se o código possuir caracteres diferentes de a-zA-Z0-9, vamos rejeitar
        if(credentials.code && credentials.code.match(/[^a-zA-Z0-9]/g)) return Promise.reject('O nome da integração deve conter apenas letras e números');

        Apis.testing[platform] = true;

        return Api.post('/api/branch/configure/apitest', credentials).then(success => {

            Apis.testing[platform] = false;

            $('.pos-test').show();
            $('.hide-after-test').hide();

            if(success?.success == false) throw success.message;

            if(success){

                Apis.tested[credentials.platform] = true;
                
                return success;

            }

        }).catch(e => {

            $('.pos-test').show();
            $('.hide-after-test').hide();

            Apis.testing[platform] = false;

            Helpers.type(form.find($('.msg')), e);

            if(Apis.autoSaveAfterTest[credentials.platform]){

                delete Apis.tested[credentials.platform];

                $('.api-form input[name=credential1]').val('');
                $('.api-form input[name=credential2]').val('');
                $('.api-form input[name=credential3]').val('');
                $('.api-form input[name=credential4]').val('');
                $('.api-form input[name=credential5]').val('');

            }

            throw e;

        });

    },

    existsByCode(code){

        let apis = Apis.get();

        for(let apiCode of apis){

            if(apiCode.toLowerCase() == code.toLowerCase()) return true;

        }

        return false;
        
    },

    isValidCode(code){

        return /^[a-zA-Z0-9]+$/.test(code) && !/\s/.test(code);

    },

    actionTest(){

        var form = $('.platform-content .api-form').length > 0 ? $('.platform-content .api-form') : $('.api-form');

        let platform = form.find('[name=platform]').val();
        let code     = form.find('[name=code]').val();

        if(Apis.testing[platform]) return;

        let fullCode = platform + '_' + code;

        if(Apis.existsByCode(fullCode)){
            
            return Helpers.type(form.find($('.msg')), I18n.get('Nome da integração já utilizado'));
            
        }

        if(!code){

            return Helpers.type(form.find($('.msg')), I18n.get('Preencha o nome da integração'));

        }

        if(!Apis.isValidCode(code)){

            return Helpers.type(form.find($('.msg')), I18n.get('Use apenas letras, sem espaços pra o nome da integração'));
            
        }

        Apis.test(form).then(success => {

            if(success?.success){

                if(success.credentials){

                    for(let name in success.credentials){

                        form.find($('input[name=' + name + ']')).val(success.credentials[name]);

                    }

                }

                if(Apis.autoSaveAfterTest[platform]) return Apis.afterSave(platform, code);

                let msg = 'Sucesso, as credenciais para a API estão corretas';

                if(success.message) msg = I18n.get(success.message);

                if(success.range) msg = I18n.get('Sucesso, foram encontrados') + ' ' + success.range + ' ' + I18n.get('registros');

                Helpers.type(form.find($('.msg')), msg);

            }

        }).catch(error => {

            Helpers.type(form.find($('.msg')), error);

        });

    },

    async testBeforeSave() {
        const form = $('.platform-content .api-form').length > 0
            ? $('.platform-content .api-form')
            : $('.api-form');

        const platform = form.find('[name=platform]')
            .val();
        const code = form.find('[name=code]')
            .val();

        if(platform == "nuvemshop" || platform == "mercadolivre") {
            return {
                success: true
            }
        }

        const fullCode = `${platform}_${code}`;
        if (Apis.existsByCode(fullCode)) {
            return Apis.displayFormMessage('Nome da integração já está sendo utilizado, e não pode ser repetido.');
        }

        if (!code) {
            return Apis.displayFormMessage('Preencha o Nome da integração');
        }

        if (!Apis.isValidCode(code)){
            return Apis.displayFormMessage('Use apenas letras, sem espaços pra o Nome da integração');
        }

        try {
            const response = await Apis.test(form);

            if (response?.success === false) {
                await Apis.displayFormMessage('Ocorreu um erro não identificado ao realizar a integração');

                return {
                    success: false,
                }
            }

            response?.credentials?.forEach(credential => {
                form.find($(`input[name=${credential}]`))
                    .val(credential);
            });

            if (response?.success && Apis.autoSaveAfterTest[platform]) {
                return Apis.afterSave(platform, code);
            }

            if (response?.message) {
                await Apis.displayFormMessage(response.message);
            }

            if (response?.range) {
                await Apis.displayFormMessage(
                    `${I18n.get('Sucesso, foram encontrados')} ${response.range} ${I18n.get('registros')}`
                );
            }

            return {
                success: true,
            };
        } catch (error) {
            await Apis.displayFormMessage(error);

            return {
                success: false,
            };
        }
    },

    async displayFormMessage(message) {
        const form = $('.platform-content .api-form').length > 0
            ? $('.platform-content .api-form')
            : $('.api-form');

        return Helpers.type(
            form.find($('.msg')),
            I18n.get(message),
        );
    },

    /*
        First, validate the data before testing.
        If the tests are successful, save the data directly using Apis.genericSave.
     */
    async save(){

        // Se for nuvemshop nao vamos testar antes
        const testing = await Apis.testBeforeSave();

        if (!testing?.success) {
            return;
        }

        try {
            const form = $('.api-form');
            await Apis.genericSave(form);

            await Apis.displayFormMessage('Sucesso, as credenciais foram salvas');

            const saveButton = $('[onclick="Apis.save();"]');
            saveButton.hide();
        } catch (error) {

            // Se error é objeto, vamos converter pra json
            if(typeof error == 'object') error = JSON.stringify(error);

            if(error == "{}" || !error) error = 'Ocorreu um erro ao salvar as credenciais';

            await Apis.displayFormMessage(error);

        }
    },

    afterSave(platform, code){

        Apis.setApi(platform + '_' + code);

        Helpers.type($('.api-form .msg'), I18n.get('API configurada com sucesso'));

        return Dashboard.loadInfo();

    },

    genericSave(form){

        let credentials = {};
        let flag        = false;

        form.find('input').each(function(){

            if(flag) return;

            credentials[$(this).attr('name')] = $(this).val();

            if(!$(this).val() && $(this).attr('type') != 'hidden'){

                flag = true;
                $(this).focus();

            }

        });

        if(flag) return Helpers.type(form.find($('.msg')), I18n.get('Preencha todos os campos'));

        // Se o código possuir caracteres diferentes de a-zA-Z0-9, vamos rejeitar
        if(credentials.code && credentials.code.match(/[^a-zA-Z0-9]/g)){

            return Helpers.type(form.find($('.msg')), I18n.get('O nome da integração deve conter apenas letras e números'));

        }

        return Api.post('/api/branch/configure/api', credentials).then(success => {

            Apis.afterSave(credentials.platform, credentials.code);

        });

    },

    editErp(platform){
        
        $('.integration-menu a[href="/dashboard/platforms/' + platform + '"]').click();

    },

    loadPreferences(apiInfo){

        Apis.loadStores();
        Apis.loadActions();

    },

    storesByApi(api_id){

        return Api.get('/v1/apis/' + api_id + '/stores');

    },

    buildActions(info){

        // .products-approve-pipeline

        // Se a api for a TINY, então consegeuiremos colocar um .list e outros elementos nesse documento de api, se a api tiver a vars actions: true
        if(Apis.vars.get(info.name, 'actions')){

            $('.action-form').remove();

            let internalForm = $('.api-form');

            if($('.pipelines')){

                internalForm = $('.pipelines');

            }

            let actionForm = $('<div class="action-form round-card lists products-approve-pipeline"></div>');

            let h3 = $('<h3></h3>');

            h3.append('<span>' + I18n.get('Multi-lojas (Aprovação)') + '</span>');

            let small = $('<small></small>');

            let button = $('<button class="float-right" onclick="Apis.addAction(\'products-approve-pipeline\')">' + I18n.get('Adicionar Ação') + '</button>');

            small.append(button);

            h3.append(small);

            actionForm.append(h3);

            actionForm.append('<br>');

            let list = $('<div class="list">Você não possui ações cadastradas para essa integração</div>');

            actionForm.append(list);

            // products-creation-pipeline
            let creationForm = $('<div class="action-form round-card lists products-creation-pipeline"></div>');

            let h3Creation = $('<h3></h3>');

            h3Creation.append('<span>' + I18n.get('Multi-anúncios') + '</span>');

            let smallCreation = $('<small></small>');

            let buttonCreation = $('<button class="float-right" onclick="Apis.addAction(\'products-creation-pipeline\')">' + I18n.get('Adicionar Ação') + '</button>');

            smallCreation.append(buttonCreation);

            h3Creation.append(smallCreation);

            creationForm.append(h3Creation);

            creationForm.append('<br>');

            let listCreation = $('<div class="list">Você não possui ações cadastradas para essa integração</div>');

            creationForm.append(listCreation);

            internalForm.append(creationForm);
            internalForm.append('<br>');
            internalForm.append(actionForm);

        }

    },

    async loadActions(){

        let info = Apis.getApiInfo();

        let actions = await Api.get('/v1/apis/' + info.api_id + '/actions');

        Apis.buildActions(info);

        let perSection = {};

        actions.forEach(action => {

            if(!perSection[action.section]) perSection[action.section] = [];

            perSection[action.section].push(action);

        });

        let sections = Object.keys(perSection);

        let apis = Dashboard.info.apis;

        let typeRender = {

            'Criar anúncio': function(props){

                if(!props) return $('<p class="round-card">Ação mal configurada</p>');

                let api = apis.find(api => api.api_id == props.api_id);

                let createAdElm = $('<p class="action-holder round-card"><span class="action">Ação</span> <img src="/img/icons/' + api.name + '.png" height="20" class="vertical-align"> Criar anúncio</p>');

                let templates = {
                    "-1": "Copiar descrição do anúncio principal",
                    "0": "Identificar pela categoria"
                }

                if(templates[props.template]) {

                    props.template = templates[props.template];
                    
                }

                if(props.auto_categorize == 'on') createAdElm.append('<p>[Categorizador ativado]</p>');
                if(props.template != '0') createAdElm.append('<p>Template ' + props.template + '</p>');

                return createAdElm;

            },

            'Enviar para Integração': function(props){

                let api = apis.find(api => api.api_id == props.api_id);

                let platform = api.code.split('_')[1];

                if(props.store_id) platform += ' (Código da loja ' + props.store_id + ')';

                let apiElm = $('<p class="action-holder round-card"><span class="action">Ação</span> <img src="/img/icons/' + api.name + '.png" height="20" class="vertical-align"> Enviar para ' + platform + '</p>');

                return apiElm;

            },

            'Webhook': function(props){

                let webhookElm = $('<p class="action-holder round-card"><span class="action">Ação</span> Enviar para ' + props.webhook_url + '</p>');

                return webhookElm;

            },

            'Enviar arquivos por FTP': function(props){

            },

            'Aguardar um tempo': function(props){

                let timerElm = $('<p class="action-holder round-card"><span class="action">Timer</span> Aguarda por ' + props.seconds + ' ' + I18n.get('segundos') + '</p>');

                return timerElm;

            }

        };

        sections.forEach(section => {

            let sectionElm = $('.' + section);

            if(!sectionElm.length) return;

            let list = sectionElm.find('.list');

            let actions = perSection[section];

            list.empty();

            if(!actions.length) return list.append('Você não possui ações cadastradas para essa integração');

            actions.forEach(action => {

                let type = action.type;
                let props;

                try{

                    props = JSON.parse(action.props);

                } catch(e){

                    props = {};

                }

                let typeRendered = typeRender[type](props);

                typeRendered.append('<div class="remove"><button onclick="Apis.removeAction(\'' + action.id + '\')">X</button></div>');

                list.append(typeRendered);

            });

        });

        $('.lists').find('svg').replaceWith('<p>Você não possui ações cadastradas para essa integração</p>');

    },

    async loadStores(){

        let info = Apis.getApiInfo();

        let apiStores = await Apis.storesByApi(info.api_id);

        $('.stores .list').empty();

        if(!apiStores.length) return $('.stores .list').append('Você não possui lojas cadastradas para essa integração');

        apiStores.forEach(store => {

            let api = Dashboard.info.apis.find(_api => {

                return _api.api_id == store.api_id;

            });

            let storeElm = $('<p></p>');

            if(!api) {

                console.log(store);

                api = {
                    code: 'Desconectado_Desconectado'
                };
                
            }

            let code = api.code.split('_')[1];

            let image = `<img src="/img/icons/${api.name}.png" height="20" class="vertical-align">`;

            if(!api.name) image = '';

            storeElm.append(`
                <div class="item-store round-card">

                    <span class="item-store-infos">
                        ${image}
                        <label>
                            <span>${code}:</span>
                            <input type="text" value="${store.store_id}" placeholder="Id multi loja" disabled>
                        </label>
                    </span>

                    <div class="actions">
                        <button onclick="Apis.removeMultiStore('${store.id}')">X</button>
                    </div>

                </div>
            `);

            $('.stores .list').append(storeElm);

        });

    },

    getById(api_id){

        return Dashboard.info.apis.find(api => api.api_id == api_id);

    },

    removeAction(action_id){

        let info = Apis.getApiInfo();

        Alerts.confirm('Remover ação', 'Deseja realmente remover essa ação?').then(() => {
 
            Api.delete('/v1/apis/' + info.api_id + '/action/' + action_id).then(() => {

                Apis.loadActions();

            });

        });

    },

    addAction(section){
        let modal = this.createActionModal(section);

        $(modal).find('.type').change(function(){
            let type = $(this).val();
            let space = $(modal).find('.api-stores .space');
            space.empty();
            Apis.typesActions[type](space);
        });

        $(modal).find('.type').change();
    },

    createActionModal(section){
        let modal = Alerts.btns('Adicionar ação', '<div class="api-stores"></div>', {
            Adicionar: function(){
                let type = $(modal).find('.type').val();
                let props = {};

                $(modal).find('.api-stores input, .api-stores select, .api-stores textarea').each(function(){
                    if(!$(this).attr('name')) return;
                    props[$(this).attr('name')] = $(this).val();
                });

                let api = Apis.getApiInfo();

                Api.post('/v1/apis/' + api.api_id + '/action', {
                    type: type,
                    props: props,
                    section: section
                }).then(() => {
                    Apis.loadPreferences();
                });
            }
        });

        let types = [];
        let typeSelect;

        switch(section){
            case 'products-creation-pipeline':
                types = ['Criar anúncio'];
                break;
            case 'products-approve-pipeline':
                types = ['Enviar para Integração', 'Webhook', 'Enviar arquivos por FTP', 'Aguardar um tempo'];
                break;
            default:
                break;
        }

        typeSelect = $('<label><span class="block">Tipo de ação</span><select class="type"></select></label>');
        types.forEach(type => {
            let option = $('<option value="' + type + '">' + type + '</option>');
            typeSelect.find('select').append(option);
        });

        $(modal).find('.api-stores').append(typeSelect);
        $(modal).find('.api-stores').append('<br><br><div class="space"></div>');

        return modal;
    },

    typesActions: {
        'Criar anúncio': function(space){
            space.append('<p class="round-warning">Atenção, para cada anúncio criado, uma nova descrição será gerada, consumindo um crédito</p>');
            space.append('<label><span>Integração</span><select name="api_id"></select></label>');

            let apis = Apis.getAll();
            apis.forEach(api => {
                let option = $('<option value="' + api.api_id + '">' + api.code.split('_')[1] + ' (' + api.name + ')</option>');
                option.data('api', api);
                space.find('select[name=api_id]').append(option);
            });

            space.append('<br><br><p><label><input type="checkbox" name="auto_categorize" checked> <span>Categorizar automaticamente</span></label></p><br>');
            space.append('<input type="hidden" name="api_code">');

            space.find('select[name="api_id"]').change(function(){
                let api = $(this).find('option:selected').data('api');
                space.find('input[name="api_code"]').val(api.code);
            });

            space.append('<p><label><span>Modelo de descrição</span><select name="template"></select></label></p>');
            Templates.list().then(templates => {
                let select = space.find('select[name="template"]');
                select.append('<option value="-1">Copiar descrição do anúncio principal</option>');
                select.append('<option value="0">Identificar pela categoria</option>');
                templates.forEach(template => {
                    let option = $('<option value="' + template.name + '">' + template.name + '</option>');
                    select.append(option);
                });
            });
        },

        'Enviar para Integração': function(space){

            let apis = Apis.getAll();

            let select = $('<label><span class="block">Integração</span><select class="api" name="api_id"></select></label>');

            apis.forEach(api => {
                if(api.api_id == Apis.getApiInfo().api_id) return;
                let option = $('<option value="' + api.api_id + '">' + api.code.split('_')[1] + ' (' + api.name + ')</option>');
                select.find('select').append(option);
            });

            // Vamos adicionar um campo visivel label para colocar o código da API
            let text = $('<label><span class="block">Código da API</span><input type="text" name="store_id"></label>');
            
            space.append(select);

            space.append('<br>');
            space.append('<br>');

            space.append(text);

        },

        'Webhook': function(space){
            space.append('<label><span class="block">URL do webhook [POST]</span><input type="text" class="webhook" name="webhook_url" placeholder="https://"></label>');
            space.append('<br><br><label><span class="block">Headers</span><textarea style="font-size: 0.8em;line-height: 1;height: 110px;" class="headers" placeholder="Authorization: eyJhbGciOiJSUzI1....\nContent-Type: application/json" name="webhook_headers"></textarea></label>');
            // let testButton = $('<button>Testar webhook</button>');
            // testButton.click(() => {});
            // space.append('<br><br>');
            // space.append(testButton);
            space.append('<br><br>');
        },

        'Enviar arquivos por FTP': function(space){
            space.append('<label><p class="round-warning">Ainda não implementado</p></label>');
        },

        'Aguardar um tempo': function(space){
            space.append('<label><span class="block">Segundos</span><input type="text" class="seconds" placeholder="Tempo em segundos" value="10" name="seconds"></label>');
        }
    },

    editMultiStore(){

        let modal = Alerts.btns('Adicionar loja', '<p class="round-warning">' + I18n.get('Selecione a integração e associe com o número de identificação dessa integração no bling (Código da loja API)') + '</p><div class="api-stores"></div>', {

            Salvar: function(){

                let storeId = $(modal).find('.store-id').val();
                let targetApi = $(modal).find('.api').val();

                if(!storeId) return Alerts.ok('Erro', 'Preencha o id da loja');

                let platform_id = Apis.getApiInfo().api_id;

                Api.post('/v1/apis/' + platform_id + '/store/configure', {
                    store_id: storeId,
                    target_api: targetApi
                }).then(() => {

                    Apis.loadPreferences();

                });

            }

        });

        let apis = Apis.getAll();
        
        // Vamos escolher uma integração, posteriormente vamos asocia-la ao store_id
        let select = $('<label><span class="block">Integração</span><select class="api"></select></label>');

        apis.forEach(api => {

            if(api.api_id == Apis.getApiInfo().api_id) return;

            let option = $('<option value="' + api.api_id + '">' + api.code.split('_')[1] + ' (' + api.name + ')</option>');

            select.find('select').append(option);

        });

        $(modal).find('.api-stores').append(select);
        $(modal).find('.api-stores').append('<br><br>');

        $(modal).find('.api-stores').append('<label><span class="block">Número identificador da loja</span><input type="text" class="store-id"></label>');

        $(modal).find('.store-id').focus();

    },

    removeMultiStore(id){

        Alerts.confirm('Remover loja', 'Deseja realmente remover essa loja?').then(() => {

            $('.stores .list').empty();
            $('.stores .list').append(Helpers._assets.animationSVGWidth30);
    
            Api.delete('/v1/apis/store/' + id).then(() => {
    
                Apis.loadPreferences();
    
            }).catch(e => {

                Alerts.ok('Erro', e);

            });

        });
    },

    getConfig(){

        let config = Apis.getApiInfo();

        try{

            config = JSON.parse(config.config);

        } catch(e){

            config = {};

        }
    
        return config;

    },

    getApiInfo(code){

        if(!code) code = Apis.getApi();

        return Dashboard.info.apis.filter(api => api.code == code)[0];

    },

    edit(){

        let actualPlatform = $('.api-form input[name=platform]').val();

        let activePlatform = Apis.getApi();
        
        if(activePlatform) activePlatform = activePlatform.split('_')[0];
        else return $('.api-form').show();
        
        $('.alert.alert-danger').remove();
        
        let haveMultipleNames = false;
        let names = [];
        
        // @todo Verificar, pelo visto está sempre sendo haveMultipleNames = true
        Dashboard.info.apis.forEach(api => {

            if(names.includes(api.name)){

                haveMultipleNames = true;

            }

            names.push(api.name);

        });

        if(actualPlatform != activePlatform && names.includes(actualPlatform)){

            if(haveMultipleNames){
    
                $('.api-form').before('<div class="alert alert-danger"><p>' + I18n.get('Selecione a plataforma que deseja configurar') + '</p><div class="multiple-api-list"></div></div>');

                Apis.getAll().forEach(api => {

                    if(api.name != actualPlatform) return;

                    $('.multiple-api-list').append('<p><button onclick="Apis.setByCode(\'' + api.code + '\')"><img src="/img/icons/' + api.name + '.png" height="20"> ' + api.code.split('_')[1] + '</button></p>');

                });

                return $('.api-form').hide();
                
            } else{
                
                // Vamos selecionar a plataforma antes de editar
                return Apis.setByFirstPlatform(actualPlatform);
                
            }
            
        }
        
        $('.api-form').show();

        if(actualPlatform != activePlatform) return;

        Api.get('/api/branch/configure/api/' + Apis.getApi()).then(apiInfo => {

            Apis.loadPreferences(apiInfo);

            let isConfigured = false;

            for(let name in apiInfo){

                if(name == 'code') apiInfo[name] = apiInfo[name].split('_')[1];
                
                $('.api-form input[name=' + name + ']').val(apiInfo[name]);

                $('.api-form input[name=' + name + ']').attr('disabled', 'disabled');

                if(apiInfo[name]) isConfigured = true;

            }

            if(isConfigured){

                $('.hide-on-saved').hide();

                $('[onclick="Apis.clear();"]').show();
                $('[onclick="Apis.infos();"]').show();
                $('[onclick="Apis.resync();"]').show();

                $('.authorize').hide();
                $('.pos-authorize').show();
                $('[onclick="Apis.addNew();"]').show();

            }

        });

    },

    syncEntity(entity){

        return Api.post('/v1/apis/' + Apis.getApi() + '/sync/' + entity);

    },

    resync(){

        Api.get('/v1/apis/' + Apis.getApi() + '/sync').then((info) => {

            Alerts.ok('Informações', JSON.stringify(info, null, 4).replace(/\n/g, '<br>').replace(/ /g, '&nbsp;').replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;'));

        });

    },

    addNew(){

        $('.authorize').show();
        $('.pos-authorize').hide();
        $('.pipelines').hide();

        // Vamos apagar os campos, para permitir que o usuário configure uma nova integração
        $('.api-form input:not([type=hidden])').val('');
        $('.api-form input:not([type=hidden])').removeAttr('disabled');

        $('.api-form input:not([type=hidden])').each(function(){

            if($(this).attr('value')) $(this).val($(this).attr('value'));

        });

        $('.hide-on-saved').show();

        $('[onclick="Apis.clear();"]').hide();
        $('[onclick="Apis.infos();"]').hide();
        $('[onclick="Apis.addNew();"]').hide();

        $('.api-form [name=credential1]').first().focus();

    },

    configApi(){

        // @todo Criar aqui o bloqueador de categorias e marcas

    },

    // @todo Padronizar o código, para que não tenhamos que repetir
    infosByApi: {

        vtex(){

            let descriptionElm = $('<div></div>');

            descriptionElm.append($('<p><button name="block-categories">' + I18n.get('Bloqueio de categorias') + '</button></p>'));
            descriptionElm.append('<br>');
            descriptionElm.append($('<p><button name="block-brands">' + I18n.get('Bloqueio de marcas') + '</button></p>'));
    
            let modal = Alerts.blank('Informações da API (vTex)');
    
            $(modal).find('.modal-body').append(descriptionElm);
    
            descriptionElm.find('button[name=block-categories]').click(() => {
    
                Apis.blockCategories();
    
            });
    
            descriptionElm.find('button[name=block-brands]').click(() => {
    
                Apis.blockBrands();
    
            });
    
        },

        tray(){

            let descriptionElm = $('<div></div>');

            descriptionElm.append($('<p><button name="block-categories">' + I18n.get('Bloqueio de categorias') + '</button></p>'));
            descriptionElm.append('<br>');
            descriptionElm.append($('<p><button name="block-brands">' + I18n.get('Bloqueio de marcas') + '</button></p>'));
    
            let modal = Alerts.blank('Informações da API (Tray)');
    
            $(modal).find('.modal-body').append(descriptionElm);
    
            descriptionElm.find('button[name=block-categories]').click(() => {
    
                Apis.blockCategories();
    
            });
    
            descriptionElm.find('button[name=block-brands]').click(() => {
    
                Apis.blockBrands();
    
            });
    
        },

        lojaintegrada(){

            let descriptionElm = $('<div></div>');

            descriptionElm.append($('<p><button name="block-categories">' + I18n.get('Bloqueio de categorias') + '</button></p>'));
            descriptionElm.append('<br>');
            descriptionElm.append($('<p><button name="block-brands">' + I18n.get('Bloqueio de marcas') + '</button></p>'));
    
            let modal = Alerts.blank('Informações da API (vTex)');
    
            $(modal).find('.modal-body').append(descriptionElm);
    
            descriptionElm.find('button[name=block-categories]').click(() => {
    
                Apis.blockCategories();
    
            });
    
            descriptionElm.find('button[name=block-brands]').click(() => {
    
                Apis.blockBrands();
    
            });
    
        },

        bling(){

            let descriptionElm = $('<div></div>');

            let modal = Alerts.blank('Informações da API (Bling)');

            descriptionElm.append(__('Em breve...'));
    
            $(modal).find('.modal-body').append(descriptionElm);
    
            descriptionElm.find('button[name=block-categories]').click(() => {
    
                Apis.blockCategories();
    
            });
    
            descriptionElm.find('button[name=block-brands]').click(() => {
    
                Apis.blockBrands();
    
            });
    
        },

        bagy(){

            let descriptionElm = $('<div></div>');

            descriptionElm.append($('<p><button name="block-categories">' + I18n.get('Bloqueio de categorias') + '</button></p>'));
            descriptionElm.append('<br>');
            descriptionElm.append($('<p><button name="block-brands">' + I18n.get('Bloqueio de marcas') + '</button></p>'));
    
            let modal = Alerts.blank('Informações da API (Bagy)');
    
            $(modal).find('.modal-body').append(descriptionElm);
    
            descriptionElm.find('button[name=block-categories]').click(() => {
    
                Apis.blockCategories();
    
            });
    
            descriptionElm.find('button[name=block-brands]').click(() => {
    
                Apis.blockBrands();
    
            });
        },

        nuvemshop(){

            let descriptionElm = $('<div></div>');

            descriptionElm.append($('<p><button name="block-categories">' + I18n.get('Bloqueio de categorias') + '</button></p>'));
            descriptionElm.append('<br>');
            descriptionElm.append($('<p><button name="block-brands">' + I18n.get('Bloqueio de marcas') + '</button></p>'));
    
            let modal = Alerts.blank('Informações da API (NuvemShop)');
    
            $(modal).find('.modal-body').append(descriptionElm);
    
            descriptionElm.find('button[name=block-categories]').click(() => {
    
                Apis.blockCategories();
    
            });
    
            descriptionElm.find('button[name=block-brands]').click(() => {
    
                Apis.blockBrands(false);
    
            });
    
        },

        bling(){

            let descriptionElm = $('<div></div>');

            descriptionElm.append($('<p><button name="block-categories">' + I18n.get('Bloqueio de categorias') + '</button></p>'));
            descriptionElm.append('<br>');
            descriptionElm.append($('<p><button name="block-brands">' + I18n.get('Bloqueio de marcas') + '</button></p>'));
    
            let modal = Alerts.blank('Informações da API (Bling)');
    
            $(modal).find('.modal-body').append(descriptionElm);
    
            descriptionElm.find('button[name=block-categories]').click(() => {
    
                Apis.blockCategories();
    
            });
    
            descriptionElm.find('button[name=block-brands]').click(() => {
    
                Apis.blockBrands(false);
    
            });
    
        }

    },

    infos(){

        let code = Apis.getApi();

        Apis.openSyncSettings(code);

    },

    blockCategories(){

        let modal = Alerts.blank('Bloqueio de categorias', 'Enumere as categorias que deseja bloquear, separando por vírgula.<br><br>');

        // Agora, vamos listar dois campos, um responsável por Ids, e o outro pelo nome
        // Assim, vamos salvar os nomes, separados por virgula, e os ids, separados por virgula
        $(modal).find('.dialog-body').append('<div class="form-group"><label>' + I18n.get('Bloquear categorias por nome') + '<input class="form-control" type="text" name="block-categories-by-name"></label></div>');
        $(modal).find('.dialog-body').append('<br>');
        $(modal).find('.dialog-body').append('<br>');
        $(modal).find('.dialog-body').append('<div class="form-group"><label>' + I18n.get('Bloquear categorias por ID') + '<input class="form-control" type="text" name="block-categories-by-id"></label></div>');

        $(modal).find('.dialog-body').append('<br>');
        $(modal).find('.dialog-body').append('<br>');
        $(modal).find('.dialog-body').append('<button class="save">' + I18n.get('Salvar') + '</button>');

        let config = Apis.getConfig();

        if( config && config.ignoreCategoryIds) $(modal).find('.dialog-body input[name=block-categories-by-id]').val(config.ignoreCategoryIds);
        if( config && config.ignoreCategoryNames) $(modal).find('.dialog-body input[name=block-categories-by-name]').val(config.ignoreCategoryNames);

        $(modal).find('.dialog-body button.save').click(() => {

            let ids = $(modal).find('.dialog-body input[name=block-categories-by-id]').val();
            let names = $(modal).find('.dialog-body input[name=block-categories-by-name]').val();

            // if(!ids && !names) return Alerts.ok(I18n.get('Preencha pelo menos um campo'));

            let apiToBlock = Apis.getApi();

            Api.post('/v1/apis/block/categories', {
                ids: ids,
                names: names,
                api: apiToBlock
            }).then(() => {

                Dashboard.loadInfo();
                modal.close();

            }).catch(error => {
                
                Alerts.ok(error);

            });

        });

    },

    blockBrands(isIdSupported = true){

        let modal = Alerts.blank('Bloqueio de marcas', 'Enumere as marcas que deseja bloquear, separando por vírgula.<br><br>');

        // Agora, vamos listar dois campos, um responsável por Ids, e o outro pelo nome
        // Assim, vamos salvar os nomes, separados por virgula, e os ids, separados por virgula
        $(modal).find('.dialog-body').append('<div class="form-group"><label>' + I18n.get('Bloquear marcas por nome') + '<input class="form-control" type="text" name="block-brands-by-name"></label></div>');
        $(modal).find('.dialog-body').append('<br>');
        $(modal).find('.dialog-body').append('<br>');
        
        if(isIdSupported)$(modal).find('.dialog-body').append('<div class="form-group"><label>' + I18n.get('Bloquear marcas por ID') + '<input class="form-control" type="text" name="block-brands-by-id"></label></div>');

        if(isIdSupported)$(modal).find('.dialog-body').append('<br>');
        if(isIdSupported)$(modal).find('.dialog-body').append('<br>');

        $(modal).find('.dialog-body').append('<button class="save">' + I18n.get('Salvar') + '</button>');

        let config = Apis.getConfig();

        if(!config) config = {};

        if( isIdSupported && config.ignoreBrandIds) $(modal).find('.dialog-body input[name=block-brands-by-id]').val(config.ignoreBrandIds);
        if(config.ignoreBrandNames) $(modal).find('.dialog-body input[name=block-brands-by-name]').val(config.ignoreBrandNames);

        $(modal).find('.dialog-body button.save').click(() => {

            let ids = '';
            if(isIdSupported) ids = $(modal).find('.dialog-body input[name=block-brands-by-id]').val();

            let names = $(modal).find('.dialog-body input[name=block-brands-by-name]').val();

            // if(!ids && !names) return Alerts.ok(I18n.get('Preencha pelo menos um campo'));

            let apiToBlock = Apis.getApi();

            Api.post('/v1/apis/block/brands', {
                ids: ids,
                names: names,
                api: apiToBlock
            }).then(() => {

                Dashboard.loadInfo();
                modal.close();

            }).catch(error => {
                
                Alerts.ok(error);

            });

        });

    },

    clear(){

        Alerts.confirm(I18n.get('Deseja apagar essas credenciais?'), I18n.get('Essa ação é irreversível.')).then(function(){

            let apiToClear = Apis.getApi();

            Api.get('/api/branch/clear/api/' + apiToClear).then(() => {

                let apiToSet = '';

                Dashboard.info.apis.forEach(api => {

                    if(api.code == Apis.getApi()) return $('.apis .api[alt=' + api.code + ']').remove();
                
                    apiToSet = api.code;
                
                });

                if(apiToSet){

                    Apis.setApi(apiToSet);

                }

                $('.logo a').click();

                setTimeout(function(){

                    window.location.reload();

                }, 500);

            });
    
        });

    },

    unormalize(line){

        if(!line.meta){

            line.meta = {
                title: '',
                description: '',
                tags: ''
            }

        }

        if(!line.category){

            line.category = {
                id: '',
                name: ''
            }

        } else{

            if(line.category.id) line.category.id = parseInt(line.category.id);
            
        }

        let data = {
            "Id": line.id,
            "Código de Referencia": line.reference,
            "Descrição": line.description,
            "Ean": line.ean,
            "Nome": line.name,
            "Marca": line.brand,
            "Peso": line.weight,
            "Altura da embalagem": line.height,
            "Largura da embalagem": line.width,
            "Comprimento da embalagem": line.length,
            "Meta Title": line.meta.title,
            "Meta Description": line.meta.description,
            "Meta Tags": line.meta.tags,
            "Id da Categoria": line.category.id,
            "Categoria": line.category.name
        };

        return data;

    },

    vars: {

        get(api, key){

            let vars = Core.apiVars;

            if(!vars[api]) return;

            if(!vars[api][key]) return;

            return vars[api][key];

        }

    },

    // Transforma uma linha interna em uma linha padrão de aprovação, human-readable
    normalize(line){

        // @todo Depreciar o resto das linhas
        if(line.payload?.normalized){

            return line.payload;

        }

        let reference = line.reference;
        let weight    = line.weight;
        let height    = line.height;
        let width     = line.width;
        let length    = line.length;
        let payload   = {};

        // @deprecated
        if(!reference){

            try{

                let json = {};

                json = JSON.parse(line.json);

                if(json){
    
                    reference = json['Código de Referencia'] || json['RefId'];
                    weight    = json.Peso;
                    height    = json['Altura da embalagem'];
                    width     = json['Largura da embalagem'];
                    length    = json['Comprimento da embalagem'];
    
                    payload = json;

                }

            } catch(e){
    
                // console.log(e);

            }

        }

        let images = Approve.allImages(line);

        // @todo Entender se é a melhor solução
        if(!images.length) images = undefined;

        let ret = {

            reference: reference,
            ean: line.ean,
            name: line.name,
            brand: line.brand,

            // @deprecated, vamos apenas deixar line.description
            description: line.content || line.description,

            weight: weight || '',
            height: height || '',
            width: width || '',
            length: length || '',

            images: images,

            meta: {
                title: line.meta_title,
                description: line.meta_description,
                tags: line.meta_tags
            },

            category: {},

            attributes: [],

            skus: [],

            price: null,

        };

        if(line.category){

            if(!line.category.id){

                // Se for objeto, vamos nem tentar dar parse
                if(typeof line.category !== 'object'){

                    try{

                        ret.category = JSON.parse(line.category);

                    } catch(e){

                        console.log(e);

                    }

                }

            }

        }

        // Se as coisas não tiverem sido definidas pelo usuário, vamos pegar o payload do backend
        if(line.payload){

            payload = line.payload;

            if(typeof line.payload == 'string'){

                try{

                    payload = JSON.parse(line.payload);
                    
                } catch(e){
        
                    console.log(e);
        
                }
    
            }

            let api = Helpers.guessApi(payload);

            switch(api){
                case 'vtex':

                    // ean
                    if(!ret.ean && payload.skus && payload.skus[0] && payload.skus[0].AlternateIds && payload.skus[0].AlternateIds.Ean){

                        ret.ean = payload.skus[0].AlternateIds.Ean;

                    }

                    // Se o usuário não tiver definido a categoria
                    if((!ret.category || !ret.category.name) && payload.CategoryId){

                        ret.category = Apis.categoriesById[payload.CategoryId];

                        if(!ret.category){

                            // Bom, nesse caso não encontramos a categoria no backend,
                            // vamos extrair pelo payload.skus[0].ProductCategories[payload.CategoryId]
                            if(payload.skus && payload.skus[0] && payload.skus[0].ProductCategories && payload.skus[0].ProductCategories[payload.CategoryId]){

                                ret.category = {
                                    id: payload.CategoryId,
                                    name: payload.skus[0].ProductCategories[payload.CategoryId]
                                }

                            }
                            
                        }

                    }

                    // Se não tiver definido ass metas
                    if(!ret.meta.title && payload.Title) ret.meta.title = payload.Title;
                    if(!ret.meta.description && payload.MetaTagDescription) ret.meta.description = payload.MetaTagDescription;
                    if(!ret.meta.tags && payload.KeyWords) ret.meta.tags = payload.KeyWords;

                    if(!ret.reference && payload.RefId) ret.reference = payload.RefId;
                    if(!ret.name && payload.Name) ret.name = payload.Name;

                    if(payload.skus && payload.skus.length){

                        if(!ret.reference){

                            console.log(payload.skus)
                            
                        }

                        let skus = payload.skus;

                        // Escolhe o sku principal como o primeiro, isso pode mudar de acordo com 
                        // a evolução do cadastraai
                        let sku = skus[0];

                        if(!ret.brand && sku.BrandName){

                            ret.brand = sku.BrandName;
    
                        }
    
                        if(sku.Dimension){
    
                            if(!ret.width  && sku.Dimension.width)  ret.width  = sku.Dimension.width;
                            if(!ret.height && sku.Dimension.height) ret.height = sku.Dimension.height;
                            if(!ret.weight && sku.Dimension.weight) ret.weight = sku.Dimension.weight;
                            if(!ret.length && sku.Dimension.length) ret.length = sku.Dimension.length;
    
                        }

                        // @todo Aqui, temos que adaptar para quando um produto possuir multiplos SKUs
                        if(!ret.images && sku.Images && sku.Images.length){

                            ret.images = sku.Images.map(i => i.ImageUrl);

                        }
    
                    }

                    if(!ret.description && payload.Description) ret.description = payload.Description;

                    ret.id = payload.Id;

                break;
                case 'bling':

                    if(!ret.reference && payload.codigo) ret.reference = payload.codigo;
                    if(!ret.ean && (payload.gtin || payload.gtinEmbalagem)) ret.ean = payload.gtin || payload.gtinEmbalagem;
                    if(!ret.name && payload.descricao) ret.name = payload.descricao;
                    if(!ret.brand && payload.marca) ret.brand = payload.marca;
                    if((!ret.category  || !ret.category.name) && payload.categoria) ret.category = {id: payload.categoria.id, name: payload.categoria.descricao};

                    if(!ret.description && payload.descricaoCurta) ret.description = payload.descricaoCurta;
                    // if(!ret.description && payload.descricaoComplementar) ret.description = payload.descricaoComplementar;

                    if(!ret.height && payload.alturaProduto) ret.height = payload.alturaProduto;
                    if(!ret.weight && payload.pesoBruto) ret.weight = payload.pesoBruto;
                    if(!ret.width && payload.larguraProduto) ret.width = payload.larguraProduto;
                    if(!ret.length && payload.profundidadeProduto) ret.length = payload.profundidadeProduto;

                    if(!ret.images && payload.imagem && payload.imagem.map) ret.images = payload.imagem.map(i => i.link);

                    let attributes = [];
        
                    if(ret.name){
        
                        let matches = payload.descricao.match(/\s[a-zA-Z0-9_]+:[a-zA-Z0-9_]+/g);
        
                        if(matches){
        
                            matches.forEach(match => {
        
                                let attribute = match.trim();
        
                                // attributes.push({
                                //     name: 'test',
                                //     values: ['amae']
                                // });

                                let name = attribute.split(':')[0].trim();
                                let value = attribute.split(':')[1].trim();

                                attributes.push({
                                    name: name,
                                    values: [value]
                                });

                                ret.name = ret.name.replace(attribute, '').trim();

                            });
        
                        }
        
                    }
        
                    if(attributes.length){
        
                        ret.attributes = attributes;
        
                    }

                    ret.id = payload.codigo;
        
                break;
                case 'nuvemshop':

                    let lang = 'pt';

                    if(!ret.name && payload.name[lang]) ret.name = payload.name[lang];
                  
                    if(!ret.description && payload.description[lang]) ret.description = payload.description[lang];
                  
                    if(!ret.brand && payload.brand) ret.brand = payload.brand;
                  
                    if(payload.variants && payload.variants.length){
                  
                        let variant = payload.variants[0];

                        if(!ret.reference && variant.sku) ret.reference = variant.sku;

                        if(!ret.ean && variant.barcode) ret.ean = variant.barcode;

                        if(!ret.weight && variant.weight) ret.weight = variant.weight;

                        if(!ret.width && variant.width) ret.width = variant.width;

                        if(!ret.height && variant.height) ret.height = variant.height;

                        if(!ret.length && variant.depth) ret.length = variant.depth;

                    }
                  
                    if(payload.images && payload.images.length){
                  
                        ret.images = payload.images.map(image => image.src);
                  
                    }

                    if(payload.categories && payload.categories.length){
                  
                        ret.category = {
                            id: payload.categories[0].id,
                            name: payload.categories[0].name[lang]
                        };
                  
                    }

                    if(!ret.meta.title && payload.seo_title[lang]) ret.meta.title = payload.seo_title[lang];
                    if(!ret.meta.description && payload.seo_description[lang]) ret.meta.description = payload.seo_description[lang];
                    if(!ret.meta.tags && payload.tags) ret.meta.tags = payload.tags;

                    ret.id = payload.id;

                break;
                case 'tiny':

                    if(!ret.name && payload.nome) ret.name = payload.nome;

                    ret.brand = payload.marca;

                    if(!ret.description && payload.descricao_complementar) ret.description = payload.descricao_complementar;

                    if(!ret.ean && payload.gtin) ret.ean = payload.gtin;
                    if(!ret.reference && payload.codigo) ret.reference = payload.codigo;

                    if(payload.situacao != 'A') ret.active = false;

                    if(payload.seo_title) ret.meta.title = payload.seo_title;
                    if(payload.seo_description) ret.meta.description = payload.seo_description;
                    if(payload.seo_keywords) ret.meta.tags = payload.seo_keywords;

                    if(!ret.height && payload.alturaEmbalagem)     ret.height  = payload.alturaEmbalagem;
                    if(!ret.weight && payload.peso_bruto)           ret.weight = payload.peso_bruto;
                    if(!ret.width  && payload.larguraEmbalagem)     ret.width  = payload.larguraEmbalagem;
                    if(!ret.length && payload.comprimentoEmbalagem) ret.length = payload.comprimentoEmbalagem;

                    if(payload.anexos){

                        if(!ret.images) ret.images = [];

                        payload.anexos.forEach(anexo => {

                            ret.images.push(anexo.anexo);

                        });
                        
                    }

                    if(!ret.category || !ret.category.name){

                        if(payload.categoria){

                            let category = payload.categoria.split(' >> ');

                            ret.category = {
                                id: false,
                                name: category[category.length - 1]
                            }

                        }

                    }

                    ret.id = payload.id;

                break;
                case 'bagy':
                    
                    if(!ret.name && payload.name) ret.name = payload.name;

                    if(!ret.brand && payload.brand) ret.brand = payload.brand.name;

                    if(!ret.description && payload.description) ret.description = payload.description;

                    let variations = payload.variations;
                    let variation;

                    if(variations && variations.length){
                        
                        variation = variations[0];

                        if(!ret.reference && variation.reference) ret.reference = variation.reference;

                        if(!ret.ean && variation.gtin) ret.ean = variation.gtin;

                        for(let i = 0; i < variations.length; i++){

                            let v = variations[i];

                            if(!v.images) v.images = [];

                            let sku = {

                                id: v.id,
                                name: v.name,

                                prices: {
                                    price: v.price,
                                    promo: v.special_price,
                                    cost: v.cost
                                },

                                stocks: {
                                    quantity: v.balance,
                                    reserved: v.reserved_balance
                                },

                                ean: v.gtin,

                                fiscal: {
                                    ncm: v.ncm
                                },

                                images: v.images.map(image => image.src),
                                weight: v.weight,
                                height: v.height,
                                width: v.width,
                                length: v.depth,
                                reference: v.reference,

                                specs: [],

                                payload: v

                            };

                            if(v.attribute){

                                sku.specs.push({
                                    [v.attribute.attribute_name]: {
                                        name: v.attribute.attribute_name,
                                        value: v.attribute.name,
                                        id: v.attribute.id,
                                        payload: v.attribute
                                    }
                                });
                                
                            }

                            if(v.attribute_secondary){

                                sku.specs.push({
                                    [v.attribute_secondary.attribute_name]: {
                                        name: v.attribute_secondary.attribute_name,
                                        value: v.attribute_secondary.name,
                                        id: v.attribute_secondary.id,
                                        payload: v.attribute_secondary
                                    }
                                });

                            }

                            if(v.color){

                                sku.specs.push({
                                    _color: {
                                        name: 'Cor',
                                        value: v.color.name,
                                        id: v.color.id,
                                        payload: v.color
                                    }
                                });

                            }

                            if(v.color_secondary){

                                sku.specs.push({
                                    [v.color_secondary.name]: {
                                        name: 'Cor secundária',
                                        value: v.color_secondary.name,
                                        id: v.color_secondary.id,
                                        payload: v.color_secondary
                                    }
                                });

                            }

                            ret.skus.push(sku);

                        }

                    }

                    if(!ret.images && payload.images && payload.images.length){

                        ret.images = payload.images.map(image => image.src);

                    }

                    if(!ret.category || !ret.category.name){

                        if(payload.categories && payload.categories.length){

                            let category = payload.categories[0];

                            ret.category = {
                                id: category.id,
                                name: category.name
                            }

                        }

                    }

                    payload.features.forEach(feature => {

                        ret.attributes.push({
                            name: feature.name,
                            values: feature.values.map(value => value.name)
                        });

                    });

                    if(!ret.meta.title && payload.meta_title) ret.meta.title = payload.meta_title;
                    if(!ret.meta.description && payload.meta_description) ret.meta.description = payload.meta_description;
                    if(!ret.meta.tags && payload.meta_keywords) ret.meta.tags = payload.meta_keywords;

                    if(!ret.height && payload.height) ret.height = payload.height;
                    if(!ret.weight && payload.weight) ret.weight = payload.weight;
                    if(!ret.width && payload.width) ret.width = payload.width;
                    if(!ret.length && payload.depth) ret.length = payload.depth;

                    ret.id = payload.id;

                break;
                case 'lojaintegrada':

                    if(!ret.name && payload.nome) ret.name = payload.nome;

                    if(!ret.brand && payload.brand) ret.brand = payload.brand.nome;

                    if(!ret.description && payload.descricao_completa) ret.description = payload.descricao_completa;

                    if(!ret.reference && payload.sku) ret.reference = payload.sku;

                    if(!ret.ean && payload.gtin) ret.ean = payload.gtin;

                    if(!ret.images && payload.images && payload.images.length){

                        ret.images = payload.images.map(image => image.imagem_url);

                    }

                    if(!ret.category || !ret.category.name){

                        if(payload.category){

                            let category = payload.category;

                            ret.category = {
                                id: category.id,
                                name: category.nome
                            }

                        }

                    }

                    if(!ret.meta.title && payload.meta.title) ret.meta.title = payload.meta.title;

                    if(!ret.meta.description && payload.meta.description) ret.meta.description = payload.meta.description;

                    if(!ret.meta.tags && payload.meta.keyword) ret.meta.tags = payload.meta.keyword;

                    if(!ret.height && payload.altura) ret.height = payload.altura;
                    if(!ret.weight && payload.peso) ret.weight = payload.peso;
                    if(!ret.width && payload.largura) ret.width = payload.largura;
                    if(!ret.length && payload.profundidade) ret.length = payload.profundidade;

                    ret.id = payload.id;

                break;
                case 'tray':

                    payload = payload.Product;

                    if(!ret.name && payload.name) ret.name = payload.name;

                    // or
                    if(!ret.brand || !ret.brand.id) {

                        ret.brand = {
                            id: payload.brand_id,
                            name: payload.brand
                        }

                    }
    
                    if(!ret.description && payload.description) ret.description = payload.description;
                    if(!ret.ean && payload.ean) ret.ean = payload.ean;
                    if(!ret.reference && payload.reference) ret.reference = payload.reference;

                    payload.metatag.forEach(metatag => {

                        if(metatag.type == 'title') ret.meta.title = metatag.content;
                        if(metatag.type == 'description') ret.meta.description = metatag.content;
                        if(metatag.type == 'keywords') ret.meta.tags = metatag.content;

                    });

                    for(let info of payload.AdditionalInfos){

                        if(info.type != 'text') continue;

                        let existAttribute = ret.attributes.find(attr => attr.name == info.name)

                        if(existAttribute){

                            existAttribute.values = [info.value]

                        } else ret.attributes.push({
                            name: info.name,
                            values: [info.value]
                        })
                    }

                    if(!ret.height && payload.height) ret.height = payload.height;
                    if(!ret.weight && payload.weight) ret.weight = payload.weight;
                    if(!ret.width && payload.width) ret.width = payload.width;
                    if(!ret.length && payload.length) ret.length = payload.length;

                    if(!ret.images) ret.images = [];

                    payload.ProductImage.forEach(image => {
    
                        ret.images.push(image.https);
    
                    });
    
                    if(!ret.category || !ret.category.name){

                        if(payload.category_id && payload.category_name){

                            ret.category = {
                                id: payload.category_id,
                                name: payload.category_name
                            }

                        }

                    }

                    ret.id = payload.id;

                break;
                default:

                    console.log(payload);

                    console.log('Não foi possível determinar o payload');
                
                break;
            }

        }

        if(parseFloat(ret.weight) == 0) ret.weight = '';
        if(parseFloat(ret.height) == 0) ret.height = '';
        if(parseFloat(ret.width)  == 0) ret.width  = '';
        if(parseFloat(ret.length) == 0) ret.length = '';

        if(!ret.category || !ret.category.name){
            ret.category = {
                name: '(A definir)'
            }
        }

        if(!ret.meta.title) ret.meta.title = '';
        if(!ret.meta.description) ret.meta.description = '';
        if(!ret.meta.tags) ret.meta.tags = '';
        if(!ret.ean) ret.ean = '';

        if(!ret.images) ret.images = [];

        if(ret.brand && ret.brand.id){

            ret.brand_id = ret.brand.id;
            ret.brand = ret.brand.name;

        }

        return ret;

    },

    tree(){

        let apis = Apis.get();

        let byPlatform = {};

        apis.forEach(api => {

            let platform = api.split('_')[0];

            byPlatform[platform] ??= [];
            byPlatform[platform].push(api);

        });

        return byPlatform;

    },

    testByExternal(api, credentials){

        let byPlatform = Apis.tree();

        let platform = api.split('_')[0];

        if(byPlatform[platform]){

            Apis.addNew();
            $('.api-form [name="code"]').focus();

        } else{

            $('.api-form [name="code"]').val(credentials.code);

            Apis.actionTest();
            
        }


    }

}

Apis.syncing = new Promise((resolve) => {

    Apis.synced = resolve;

});

$(document).ready(() => {

    $('.integration-menu a').each(function(){

        Nav.addTrigger($(this).attr('href'), async (data) => {

            await Dashboard.ready;

            Apis.edit();

        });

    });

    if(!!Session.jwt()){

        let url = new URL(location.href);

        if(location.href.indexOf('platforms/nuvemshop?code=') > -1){

            let code = location.href.split('code=')[1];
   
            // Se o host for cadastra.ai, vamos redirecionar para app.indexa.ai
            if(url.host == 'cadastra.ai'){

                return location.href = 'https://app.indexaai.com' + url.pathname + url.search;

            }

            localStorage['api_nuvemshop_code'] = code;
    
            window.close();
    
        }

        if(location.href.indexOf('platforms/mercadolivre?code=') > -1){
            
            const code = url.searchParams.get('code');

            localStorage['api_mercadolivre_code'] = code;

            window.close();
        }
    
        if(location.href.indexOf('platforms/tray?code=') > -1){

            let code = url.searchParams.get('code');
            let api_address = url.searchParams.get('api_address');
    
            localStorage['api_tray_code'] = JSON.stringify({
                code: code,
                api_address: api_address
            });
    
            console.log(localStorage['api_tray_code']);
    
            if(localStorage.waiting_tray_code){
    
                localStorage.removeItem('waiting_tray_code');
                window.close();
    
            } else{
    
                Alerts.ok('Código de autorização Tray', '<p>Api address: <span class="yellow">' + api_address + '</span></p><p class="nobreak">Code: <span class="yellow">' + code + '</span></p>');
    
            }
    
        }

        if(location.href.indexOf('platforms/bling?code=') > -1){

            // Se o host for cadastra.ai, vamos redirecionar para app.indexa.ai
            if(url.host == 'alpha.cadastra.ai'){

                return location.href = 'https://test.cadastra.ai' + url.pathname + url.search;

            }

            // Se o host for cadastra.ai, vamos redirecionar para app.indexa.ai
            if(url.host == 'cadastra.ai'){

                return location.href = 'https://app.indexaai.com' + url.pathname + url.search;

            }

            let code = url.searchParams.get('code');

            localStorage['api_bling_code'] = code;

            if(localStorage.waiting_bling_code){

                localStorage.removeItem('waiting_bling_code');

                window.close();

            } else{

                let modal = Alerts.ok('Código de autorização Bling', '<p>Code: <span class="yellow">' + code + '</span></p>');

                $(modal).find('.btns').append('<button class="lets-integrate">Integrar</button>');

                $(modal).find('.lets-integrate').click(() => {

                    modal.close();

                    Apis.testByExternal('blingv3', {
                        code: 'Bling'
                    });

                });

            }

        }
    
    }

    Styles.type('range', (progressObj) => {

        let percent = 0;

        if(progressObj.value.context_count && progressObj.value.context_index){

            percent = (progressObj.value.context_index / progressObj.value.context_count) * 100;

        }

        let progress = Styles.getById(progressObj.progress_id);

        progress.find('.progress-bar-inner').css('width', percent + '%');

        progress.find('.progress-body').html(progressObj.value.message);

        if(progressObj.value.title){

            progress.find('.progress-title').text(progressObj.value.title);

        }

        Catalog.reloadDueProgress(progressObj.value);

    });

    Styles.type('pending', (progressObj) => {

        let progress = Styles.getById(progressObj.progress_id);

        progress.addClass('progress-pending');

        // Se a message for diferente
        if(progress.find('.progress-body').html() != progressObj.value.message){

            progress.find('.progress-body').html(progressObj.value.message);

        }

        if(progressObj.value.title){

            // Se o título for diferente
            if(progress.find('.progress-title').text() != progressObj.value.title){

                progress.find('.progress-title').text(progressObj.value.title);
            }


        }

        Catalog.reloadDueProgress(progressObj.value);

    });

});

$(function(){

    // Dashboard.checkParam('api-settings', (value) => {

    //     Apis.openSettings(value);

    // });

});
