var Creation = {

    loading: false,

    stopInterval: null,

    product: {

        lastTemplate: null,

        changeTemplate(elm){

            // Sets to the localStorage the template
            localStorage.setItem('template', $(elm).val());

            Creation.product.lastTemplate = $(elm).val();

        },

        load(){

            if(location.pathname != '/cadastro/produto') return false;

            LayoutGradesAndVariante();

            Templates.list().then(templates => {

                let select = $('.creation.product select[name="template"]');

                select.html('');

                select.append('<option value="0">Selecione um modelo</option>');

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

                    let template = templates[i];

                    select.append('<option value="' + template.name + '">' + template.name + '</option>');

                }

                let preValue = Creation.product.lastTemplate;

                if(!preValue && localStorage.getItem('template')){

                    preValue = localStorage.getItem('template');

                }

                if(preValue) select.val(preValue);

            });

            if(Creation.loading){

                Creation.loading.close();
                Creation.loading = false;

            }

            Creation.product.addOther();

        },

        addFile(){

            Helpers.readFile().then(content => {

                try{

                    let products = [];

                    // Parseando o texto XML
                    const parser = new DOMParser();
                    const xmlDoc = parser.parseFromString(content, "application/xml");
    
                    const nfeProc = xmlDoc.getElementsByTagName("nfeProc")[0];
                    const NFe = nfeProc.getElementsByTagName("NFe")[0];
                    const infNFe = NFe.getElementsByTagName("infNFe")[0];
                    const dets = infNFe.getElementsByTagName("det");
    
                    for(let i = 0; i < dets.length; i++){
    
                        let det = dets[i];
                        
                        const prod = det.getElementsByTagName("prod")[0]; // Acessa o nó 'prod' dentro de 'det'
                        const imp = det.getElementsByTagName("imposto")[0]; // Acessa o nó 'prod' dentro de 'det'

                        const cProd = prod.getElementsByTagName("cProd")[0]?.textContent;
                        const cEAN = prod.getElementsByTagName("cEAN")[0]?.textContent;
                        const xProd = prod.getElementsByTagName("xProd")[0]?.textContent;
                        const NCM = prod.getElementsByTagName("NCM")[0]?.textContent;
                        const cBenef = prod.getElementsByTagName("cBenef")[0]?.textContent || "";
                        const CFOP = prod.getElementsByTagName("CFOP")[0]?.textContent;
                        const uCom = prod.getElementsByTagName("uCom")[0]?.textContent;
                        const qCom = prod.getElementsByTagName("qCom")[0]?.textContent;
                        const vUnCom = prod.getElementsByTagName("vUnCom")[0]?.textContent;
                        const vProd = prod.getElementsByTagName("vProd")[0]?.textContent;
                        const cEANTrib = prod.getElementsByTagName("cEANTrib")[0]?.textContent;
                        const uTrib = prod.getElementsByTagName("uTrib")[0]?.textContent;
                        const qTrib = prod.getElementsByTagName("qTrib")[0]?.textContent;
                        const vUnTrib = prod.getElementsByTagName("vUnTrib")[0]?.textContent;
                        const indTot = prod.getElementsByTagName("indTot")[0]?.textContent;
                        const xPed = prod.getElementsByTagName("xPed")[0]?.textContent;
                        const nItemPed = prod.getElementsByTagName("nItemPed")[0]?.textContent;
  
                        const vICMS = prod.getElementsByTagName("vICMS")[0]?.textContent;
                        const vIPI = prod.getElementsByTagName("vIPI")[0]?.textContent;
                        const vPIS = prod.getElementsByTagName("vPIS")[0]?.textContent;
                        const vCOFINS = prod.getElementsByTagName("vCOFINS")[0]?.textContent;
                        const vICMSST = prod.getElementsByTagName("vICMSST")[0]?.textContent;
                        const CST = prod.getElementsByTagName("CEST")[0]?.textContent;

                        let Orig;

                        if(imp){

                            let icms = imp.getElementsByTagName('ICMS')[0];

                            if(icms) {
                                
                                let icms00 = icms.getElementsByTagName('ICMS00')[0];

                                if(icms00) {

                                    Orig = icms00.getElementsByTagName('orig')[0]?.textContent;

                                }

                            }
                            
                        }

                        let product = {
                            "Ean": cEAN,
                            "Nome": xProd,
                            "Estoque *": Number(qCom),
                            "Custo *": vProd,
                            "Sku": cProd,
                            "Ncm *": NCM,
                            "CFOP *": CFOP
                        }

                        if(Orig){

                            product["Origem *"] = Orig;
                            
                        }

                        if(CST){

                            product["CEST *"] = CST;
                            
                        }

                        if(vProd && vIPI && vICMSST){

                            product["Custo Final Unitário *"] = Number(vProd) + Number(vIPI) + Number(vICMSST);
                            
                        }

                        if(vICMS){

                            product["ICMS *"] = vICMS;

                        }

                        if(vIPI){

                            product["IPI *"] = vIPI;

                        }

                        if(vPIS){

                            product["PIS *"] = vPIS;

                        }

                        if(vCOFINS){

                            product["COFINS *"] = vCOFINS;

                        }

                        if(vICMSST){

                            product["ICMSST *"] = vICMSST;

                        }
    
                        products.push(product);
    
                    }
    
                    Creation.product.addProducts(products);
    
                } catch(e){

                    console.log(e);

                    Alerts.ok('Não foi possível ler o XML');

                }

            });

        },

        addProducts(products){

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

                let product = products[i];

                let elm = Creation.product.addOther();

                elm.find('[name="ean"]').val(product.Ean);
                elm.find('[name="name"]').val(product.Nome);

                let attrTemplate = elm.find('.atributo.hidden').clone();

                for(let prop in product){

                    if(prop.includes('*') || prop == 'Sku'){

                        let attrElm = attrTemplate.clone();

                        attrElm.removeClass('hidden');

                        attrElm.find('[name=atributo_nome]').val(prop);
                        attrElm.find('[name=atributo_valor]').val(product[prop]);

                        elm.find('.atributos').append(attrElm);

                    }
                    
                }

                // <div class="atributo"><img class="close" src="img/icons/close-icon.svg"><label><span class="block"><span>Nome do Atributo</span><span class="help" data-tooltip="Insira o nome do atributo, como material, cor, tamanho, etc."></span></span><input type="text" name="atributo_nome"></label><label><span class="block"><span>Valor do Atributo</span><span class="help" data-tooltip="Insira o valor do atributo, como algodão, azul, P-M-G, etc."></span></span><input type="text" name="atributo_valor"></label></div>

                Creation.product.card.getCard(elm).validInputs();

                console.log(elm, product);
                
            }

        },

        // Clona o elemento zero, para criar um novo card na tela
        addOther(){

            let card = $('.round-card[data-id=0]').clone();

            card.find('input').val('');
            card.find('.images.pending').html('');
            card.find('.images.pending').append('<div class="images-errored"></div>');
            card.removeClass('lock');
            card.find('.atributos .atributo:not(.hidden)').remove();

            card.attr('data-id', $('.creation.product .list [data-id]').length);

            $('.creation.product .list').append(card);

            card.find('.close').show();

            let preValue = Creation.product.lastTemplate;

            if(!preValue && localStorage.getItem('template')){

                preValue = localStorage.getItem('template');

            }

            if(preValue) card.find('select[name="template"]').val(preValue);

            return card;

        },

        dao:{

            getInputLine(id){

                return Api.get('/api/dashboard/line/' + id );

            },

            // A partir de um planUsageId e um conjunto de files
            sendImage(planUsageId, files){

                let formData = new FormData();

                for(let i = 0; i < files.length; i++) formData.append('file', files[i]);

                return Api.file('/v1/file/approve/' + planUsageId, formData);

            },

            sendImageInputLine(inputLineId, files){

                let formData = new FormData();

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

                    let file = files[i];
                    formData.append('file', file);

                }

                return Api.file('/v1/file/inputline/' + inputLineId, formData);

            }

        },

        check(elm){

            Creation.product.card.getCard(elm).validInputs();

        },

        card:{

            getCard: (btn) => {

                let elm = $(btn).closest('.round-card[data-id]');

                elm.complete = () => {

                    return elm.hasClass('sendPlanUsage');

                }

                elm.checkOk = () => {
    
                    if(elm.complete()) {

                        Alerts.blank('Esse produto já foi enviado');

                        return false;

                    }

                    if($(elm).hasClass('lock')){

                        Alerts.blank('Esse produto já está sendo processado.');

                        return false;
                        
                    }

                    return true;

                }

                elm.getImages = () => {

                    return elm.data('imgs')? elm.data('imgs') : [];

                }

                elm.validInputs = () => {

                    return Creation.product.card.validInputs(elm);

                }

                elm.checkImages = () => {

                    if(!$('.images-errored:visible').find('img').length) {
                        return true;
                    };
                    
                    Alerts.blank('Por favor, remova as imagens com erro antes de enviar o produto.');
                    return false;

                }

                elm.setLock = () => {

                    elm.addClass('lock');
                    elm.find('input').attr('disabled','true');

                }

                elm.unLock = () => {

                    elm.removeClass('lock');
                    elm.find('input').removeAttr('disabled');

                }

                return elm;

            },

            send(event, elm){

                let card = Creation.product.card.getCard(elm);

                if(!card.checkImages()) return;

                if(card.complete()) return true;

                if(card.data('lock') == 'true') return;

                if(card.hasClass('lock')){
                    
                    return Alerts.blank('Esse produto já esta sendo processado');

                }

                let name         = card.find('input[name="name"]').val();
                let brand        = card.find('input[name="brand"]').val();
                let ean          = card.find('input[name="ean"]').val();
                let supplierCode = card.find('input[name="supplier_code"]').val();

                let data = {}

                if(name)         data["Nome"]  = name;
                if(brand)        data["Marca"] = brand;
                if(ean)          data["Ean"]   = ean;
                if(supplierCode) data["Código do Fornecedor"] = supplierCode;

                let hasInvalidAtribute = false;

                card.find('.atributo:not(.hidden)').each(function(){

                    let name  = $(this).find('input[name="atributo_nome"]').val().trim()  || '';
                    let value = $(this).find('input[name="atributo_valor"]').val().trim() || '';

                    let validAtribute = name.length > 0 && value.length > 0;

                    if(validAtribute){

                        data[name] = value;
                        $(this).removeClass('invalid');

                    } else{

                        hasInvalidAtribute = true;
                        $(this).addClass('invalid');

                    }

                });

                if(hasInvalidAtribute) return Alerts.blank('Existem atributos inválidos!','');

                card.setLock();

                $(elm).text('Processando...');

                let imagesToSend = card.getImages();

                let sendPromise = Promise.resolve();

                let template = card.find('select[name="template"]').val();

                if(imagesToSend.length > 0){

                    let imageObj = {
                        fields: data,
                        files: imagesToSend.map(img => img[1]),
                        opts: {},
                        api: Apis.getApi()
                    };

                    if(Dashboard.getFeatures().description_templates && template){

                        imageObj.opts.template = template;

                    }

                    console.log(imageObj);

                    sendPromise = Api.post('/v1/creation/image', imageObj).catch((err) => {
                        Alerts.blank('Ocorreu um erro!', err);
                    });

                } else{

                    let massObj = {

                        data: [data],

                        opts: {
                            preserveName: false,
                            company_info: false,
                            brand_info: false,
                            namePattern: [ 
                                { name: "Nome", order: 0 },
                                { name: " - ", order: 1 }
                            ]
                        },
    
                        api: Apis.getApi()
    
                    };

                    if(Dashboard.getFeatures().description_templates && template){

                        massObj.opts.template = template;

                    }

                    sendPromise = Api.post('/api/dashboard/mass', massObj).catch((err) => {

                        Alerts.blank('Ocorreu um erro!', err);

                    });

                }

                sendPromise.then(res => {

                    let notSendImage = true;

                    card.data('lock', 'true');

                    if(res.batchId) res.success = true;

                    if(!res.success){

                        card.unLock();

                        $(elm).addClass('invalid');
                        $(elm).text(res.error);

                        // Caso retorne o campo imagem, reconhecemos que foi um erro ao ler a imagem e adicionamos uma visualização de qual imagem não foi lida corretamente
                        if(res.image != null) {
                            
                            const erroredImage = $(card[0]).find($('.images.pending img')[res.image]);
                            $(erroredImage).addClass('errored');
                            
                            $(erroredImage).appendTo($(card[0]).find($('.images-errored')));
                            
                        }

                        card.data('lock','false')
                        
                        return;
                    
                    }

                    // @todo dry 31039019
                    Styles.hook('Criando descrições', async (dataWs) => {

                        let batchIsCurrent = res.batchId == dataWs.batchId;
                        
                        // bloqueia de outros batch 
                        if(!batchIsCurrent) return;
                        
                        // tratamento de erro
                        if(dataWs.error) {

                            card.unLock();

                            $(elm).addClass('invalid');
                            $(elm).text(dataWs.error || 'EAN não Encontrado');

                            card.data('lock','false');

                            return;

                        }
                        
                        $(elm).removeClass('invalid');
                        
                        if(notSendImage && dataWs.id && !dataWs.error){
                            
                            notSendImage = false;

                            // verify input line and filter card
                            let inputline = await Creation.product.dao.getInputLine(dataWs.id);

                            let hasFiles = card.getImages().length > 0;
                            
                            let files = card.getImages();
                            
                            // Send Image
                            if(hasFiles){
                                
                                console.log("tentando Enviar imagem",card.getImages());
                                
                                // [ data, peer ] -> perr [ file, base64 ]
                                files = files.map(peer => peer[0]);
                                
                                Creation.product.dao.sendImageInputLine(inputline.id, files).catch(e => console.error(e));
                                
                            }
                            
                            card.attr("data-line", dataWs.id);
                            
                        }

                        // Send Files
                        if(dataWs.planUsageId){

                            card.addClass('sendPlanUsage');

                            $(elm).addClass('sendPlanUsage');

                            $(elm).off('click');
                            
                            $(elm).text('Ir para Produto Gerado').click((event) => {

                                window.open(`/aprovacao/cadastro?id=${dataWs.planUsageId}`, '_blank');

                            });

                        }

                    });

                }).catch(e => {

                    console.error(e);

                });

            },

            validInputs(elm){

                if(!elm) return false;

                let card = Creation.product.card.getCard(elm);

                let btn = card.find('button.gerar-generico'); 
                let brandHolder = card.find('.brand-holder');

                let hasEan   = card.find('input[name="ean"]').val();
                let hasName  = card.find('input[name="name"]').val();
                let hasBrand = card.find('input[name="brand"]').val();
                let hasSupplierCode = card.find('input[name="supplier_code"]').val();

                let hasImages = card.getImages().length > 0;

                // Reseta o botão
                brandHolder.removeClass('error');
                btn.removeClass('jump');
                btn.removeClass('invalid');
                btn.text('Gerar Cadastro');

                if(hasEan || (hasName && hasBrand) || (hasImages && hasBrand) || (hasSupplierCode && hasBrand)){

                    btn.addClass('jump');

                }

                if(!hasEan && (hasName || hasImages || hasSupplierCode) && !hasBrand){
                    brandHolder.addClass('error');
                    btn.removeClass('jump');
                }

                return {
                    hasEan,
                    hasName,
                    hasBrand,
                    hasImages,
                    hasSupplierCode
                }

            },

            // Adiciona Image para um card
            addImage(elm){

                let card = Creation.product.card.getCard(elm);

                if(!card.checkOk()) return;

                Images.getImagesInComputer().then(peers => {

                    card.validInputs();

                    for(let [file, base64] of peers){

                        let image = $(`<img src='${base64}'>`);

                        $(card).find('.images.pending').append(image);

                        // Remove Hook
                        image.click(() => {
                            
                            if(!card.checkOk()) return;
                
                            Alerts.confirm('Remover Foto?','').then(() => {

                                image.remove();

                                // Remontando as imagens
                                let imgs = card.getImages();

                                imgs = imgs.filter(img => {

                                    let [fileImg, base64] = img;

                                    return fileImg.name != file.name;

                                });

                                $(card).data('imgs', imgs);

                                card.validInputs();

                            });

                        });

                    }

                    let imgs = card.data('imgs')? card.data('imgs') : [];

                    imgs = imgs.concat(peers);

                    card.data('imgs', imgs);

                    if(imgs.length > 0) card.validInputs();

                }).catch(e => console.error(e))

            },

            // Adiciona um atributo para um card
            addAttributes(elm){

                let card = Creation.product.card.getCard(elm);

                if(!card.checkOk()) return;

                let novoAtributo = card.find('.atributo.hidden').clone();

                // hook remove atribute
                novoAtributo.find('img.close').click(()=>{
                    novoAtributo.remove()
                });

                novoAtributo.removeClass('hidden');

                card.find('.atributos').append(novoAtributo)

            },

            addGrades(elm) {
                let card = Creation.product.card.getCard(elm);

                if(!card.checkOk()) return;

                let novoAtributo = card.find('.gradesWrapper.hidden');

                novoAtributo.find('.wrap-image-close').click(()=>{
                    novoAtributo.addClass('hidden')
                });

                novoAtributo.removeClass('hidden');
                
            },

            closeGrades() {

            },

            // Remove um card
            remove(elm){
                let card = Creation.product.card.getCard(elm);

                card.remove()

                $('p.fixed-painel-bottom button').removeClass('jump')
            }

        }

    },

    startCheckingForStop(){

        Creation.stopInterval = setTimeout(function(){

            // Se não tiver o elemento que recebe o video na tela, visível, vamos parar o stream
            if(!$('.ean-holder').is(':visible')){

                Creation.stopAllStreams();
                clearInterval(Creation.stopInterval);

            } else{
                    
                Creation.startCheckingForStop();

            }
            
        }, 1000);

    },

    stopAllStreams(){

        Creation.ean.starting = false;

        Quagga.stop();

    },

    im: {

        allFiles: {},
        sheets: {},

        sheetData: [],

        byRef: {},

        pagination: null,

        async loadSheet(name){

            let file = Creation.im.sheets[name];

            await Helpers.parseExcelRows(file).then(data => {

                let rows = data.data;

                Creation.im.sheetData = Creation.im.sheetData.concat(rows);

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

                    let row = rows[i];

                    console.log(row);

                    if(!row['Código de Referencia']) continue;

                    let ref = row['Código de Referencia'];

                    Creation.im.byRef[ref] ??= {

                        father: null,

                        children: [],

                        all: [],

                        // Armazena todos os atributos e seus valores, por exemplo {Cor: ['Azul', 'Vermelho']}
                        attributes: {},

                    };

                    Creation.im.byRef[ref].all.push(row);

                }

                for(let ref in Creation.im.byRef){

                    let father = Creation.im.byRef[ref].all[0];

                    Creation.im.byRef[ref].father = father;

                    for(let i = 1; i < Creation.im.byRef[ref].all.length; i++){

                        let line = Creation.im.byRef[ref].all[i];

                        // As colunas que tiverem # na frente são atributos
                        for(let column in line){    

                            if(column.startsWith('#')){

                                let attribute = column.substr(1);

                                Creation.im.byRef[ref].attributes[attribute] ??= [];

                                let value = line[column];

                                if(!Creation.im.byRef[ref].attributes[attribute].includes(value)){

                                    Creation.im.byRef[ref].attributes[attribute].push(value);

                                }

                            }

                        }

                    }

                }                    

                Creation.im.setAllTags();

            });

        },

        async buildMultiple(lastElm){

            console.log(lastElm);

            lastElm.addClass('multiple-imgs')

        },

        // Cria o elemento de imagem que será utilizado
        async buildImg(key, file, sku){

            console.log(key, file);

            let obj = Creation.im.allFiles[key];

            console.log(key, obj);

            let url = URL.createObjectURL(file);
            // let name = file.name;

            let imageElm = $('<div class="image finding"><div><div class="name" title="' + key + '">' + key + '</div><button class="add-name">Nome</button></div><img src="' + url + '"><div><button class="add-variant">+ Variante</button></div><div class="tags"></div><div class="info-btns"><button class="add-category">Categoria</button>&nbsp;&nbsp;<button class="add-category">Marca</button><br><button class="add-price">Preco</button>&nbsp;&nbsp;<button class="add-stock">Estoque</button></div></div>');

            $('.image-mass .image-preview').append(imageElm);

            obj.elm = imageElm;
            
            imageElm.data('key', key);

            Creation.im.setTags(imageElm);

            imageElm.attr('data-sku', sku);

            imageElm.on('mouseover', function(){

                // Vamos colocar uma corzinha em todos os elementos que tiverem o mesmo sku
                $('.image-mass .image-preview .image').removeClass('hover');

                $('.image-mass .image-preview .image[data-sku="' + sku + '"]').addClass('hover');

            });

            imageElm.on('mouseout', function(){

                $('.image-mass .image-preview .image').removeClass('hover');

            });

            // Turns draggable, only capable of dragging into others
            imageElm.draggable({

                revert: true,
                // helper: 'clone',
                // appendTo: 'body',
                zIndex: 100,

                start: function(event, ui){

                    // $(this).addClass('dragging');

                },

                stop: function(event, ui){

                    // $(this).removeClass('dragging');

                }

            });

            // Turns droppable, only capable of receiving from others
            imageElm.droppable({

                accept: '.image-mass .image-preview .image',

                drop: function(event, ui){

                    // Add .even to both elements
                    $(this).addClass('even');
                    $(ui.draggable).addClass('even');

                    // Not revert if dropped
                    $(ui.draggable).draggable('option', 'revert', false);

                    // Refresh draggable
                    // $(ui.draggable).draggable('refresh');

                    // Hide the dropping element
                    $(ui.draggable).css('visibility', 'hidden');

                    // And the element goes right after the other
                    $(this).after(ui.draggable);

                },

                over: function(event, ui){

                    // $(this).addClass('dragging');

                },

                out: function(event, ui){

                    // $(this).removeClass('dragging');

                }

            });

            return imageElm;

        },

        model(){

            Helpers.download('/cadastro-em-massa.xlsx', 'Cadastro em Massa.xlsx');

        },

        async setup(){

            $('body').removeClass('dragging');

            // On scroll of the body, we'll load more pages
            $(window).on('scroll', function(){

                if($(window).scrollTop() + $(window).height() > $(document).height() - 100){

                    Creation.im.pagination.nextPage();

                }

            });

            Creation.im.pagination = new Pagination([], 1000);

            $('.image-mass .image-preview').html('');

            let load = async () => {

                $('.backimage').hide();
                // $('.image-dropzones .droparea').hide();

                const pageItems = Creation.im.pagination.getPageItems();
                
                for(let i = 0; i < pageItems.length; i++){

                    let sku = pageItems[i];

                    let files = Creation.im.skus[sku];

                    let lastSku = null;
                    let lastElm = null;

                    for(let j = 0; j < files.length; j++){

                        let file = Creation.im.allFiles[files[j]];

                        // Aqui, vamos pegar o SKU base, para identificar se o anterior é igual ao de agora
                        let skuBaseName = files[j].split(' ')[0];

                        if(file.nativeAtrributes){

                            for(let attribute in file.nativeAtrributes){

                                skuBaseName += ' ' + attribute + '-' + file.nativeAtrributes[attribute].join('-');

                            }
                            
                        }

                        if(lastSku == skuBaseName && skuBaseName != sku){

                            // Vamos adicionar a imagem no último elemento
                            await Creation.im.buildMultiple(lastElm);

                            continue;

                        }

                        lastSku = skuBaseName;

                        if(!file) continue;

                        let imgElm = await Creation.im.buildImg(files[j], file, sku);

                        lastElm = imgElm;

                        if(files.length > 1){

                            if(i % 2 == 0) imgElm.addClass('even');
                            else imgElm.addClass('odd');

                        }

                    }

                }

                // Se ainda não tivermos itens o suficientes para gerar um scroll, vamos carregar mais
                if(document.body.scrollHeight <= $(window).height()){

                    await new Promise((resolve, reject) => setTimeout(resolve, 100));

                    Creation.im.pagination.nextPage();

                }

            };

            Creation.im.pagination.on('change', load);

            Creation.im.pagination.on('itemsUpdated', () => {

                // Apaga a listagem, volta pra página 1
                $('.backimage').show();
                $('.image-mass .image-preview').html('');

                Creation.im.organize();

            });

            load();

        },

        // Organiza os itens, estruturalmente, para facilitar
        organize(files = Creation.im.allFiles){

            // Guarda a informação, virtualmente
            let info = {};

            let sheetData = Creation.im.sheetData;

            if(sheetData.length) $('.image-preview').addClass('sheet');

            for(let file in files){

                // Atributos na imagem que são sinalizados por #
                let nativeAtrributes = {};

                let extension = Helpers.ext(file);

                let filename = file.substr(0, file.length - extension.length);

                // Vamos definir o sku do item
                let sku = filename.split(' ')[0];

                Creation.im.allFiles[file].sku = sku;

                // Vamos pegar pelo match em palavras que começam com #, por exemplo #Cor-Azul #Tamanho-P-M-G, até o primeiro espaço
                let matches = filename.match(/#[A-Za-z0-9-]+/g);

                if(!matches) continue;

                // Vamos passar por cada item
                for(let i = 0; i < matches.length; i++){

                    let match = matches[i];

                    // A primeira palavra é o nome do atributo, os outros itens são os valores
                    let attribute = match.substr(1);

                    let root = attribute.split('-')[0];

                    let values = attribute.split('-').slice(1);

                    // @todo Quando não tiver valores, vamos exibir pela UX tal erro
                    // if(!values) continue;

                    nativeAtrributes[root] = values;

                }

                Creation.im.allFiles[file].nativeAtrributes = nativeAtrributes;

            }

        },

        async parseFiles(files){

            if(!Creation.im.pagination) await Creation.im.setup();

            let excel = ['xls', 'xlsx', 'csv', 'ods'];
            let images = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'avif', 'webp', 'tiff'];

            let allExtensions = excel.concat(images);

            files = Object.values(files);

            // Ordena pelo nome
            files.sort(function(a, b){

                return a.name.localeCompare(b.name);

            });

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

                let extension = Helpers.ext(files[i].name);
                let filename = files[i].name.substr(0, files[i].name.length - extension.length - 1);

                // Remove tudo aquilo que não estiver nos formatos aceitos
                if(!allExtensions.includes(extension)) continue;

                if(excel.includes(extension)){

                    Creation.im.sheets[filename] = files[i];

                    await Creation.im.loadSheet(filename);

                    continue;

                }

                Creation.im.allFiles[filename] = files[i];

            }

            Creation.im.organize();

            Creation.im.skus = {};

            for(let image in Creation.im.allFiles){

                let sku = Creation.im.allFiles[image].sku;

                Creation.im.skus[sku] ??= [];

                Creation.im.skus[sku].push(image);
                
            }

            let skus = Object.keys(Creation.im.skus);

            let toCombine = [];

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

                let sku = skus[i];

                if(Creation.im.skus[sku].length != 1) continue;

                toCombine.push(Creation.im.skus[sku][0]);

            }

            let macroCombinations = Suggest.macroCombinations(toCombine);

            let newCombinations = {};

            for(let sku in macroCombinations){

                let combination = macroCombinations[sku];

                newCombinations[combination] ??= [];

                newCombinations[combination].push(sku);

            }

            for(let combination in newCombinations){

                if(!combination) continue;
                
                let skus = newCombinations[combination];

                if(skus.length == 1) continue;

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

                    let sku = skus[i];

                    delete Creation.im.skus[sku];

                    Creation.im.skus[combination] ??= [];
                    
                    Creation.im.skus[combination].push(sku);

                }

            }

            Creation.im.pagination.setItems(Object.keys(Creation.im.skus));

        },

        setAllTags(){

            $('.image-mass .image-preview .image').each(function(i){

                let image = $('.image-mass .image-preview .image').eq(i);

                Creation.im.setTags(image);

            });

        },

        setTags(elm){

            let key = $(elm).data('key');

            let file = Creation.im.allFiles[key];

            let name = key;

            let attributes = {};

            if(file.nativeAtrributes){

                attributes = file.nativeAtrributes;
                
            }

            for(let attr in attributes){

                let values = attributes[attr];

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

                    let value = values[i];

                    let tag = $('<div class="tag">' + value + '</div>');

                    $(elm).find('.tags').append(tag);

                }

            }

        },

        load(){

            if(location.pathname != '/cadastro/imagem/massa') return false;

            $('.send-image').show();

            $('.creation.image-mass').show();

        },

    },

    ean: {

        searching: false,
        viewing: null,
        starting: false,

        // @tarefas:
        // Remover a url ao deletar/aprovar, 
        // Pegar dados da ficha tecnica
        // Ao deletar, voltar para a tela do ean
        // Remover os campos que veem undefined
        // Permitir edição da referencia
        // O remover não está mais saindo da tela

        startCam(){

            Creation.ean.starting = true;

            $('.spacing').css({
                height: (($('body').height() / 2000) * 700) + 10
            });

            $(function() {

                var App = {
            
                    init : function() {

                        Creation.startCheckingForStop();

                        Quagga.init({
            
                            inputStream: {
            
                                type : "LiveStream",
            
                                constraints: {
                                    width: {
                                        min: 640
                                    },
            
                                    height: {
                                        min: 480
                                    },
            
                                    aspectRatio: {
                                        min: 1, max: 100
                                    },
            
                                    facingMode: "environment"
            
                                },
                                target: '.ean-holder'
                            },
            
                            locator: {
                                patchSize: "medium",
                                halfSample: true
                            },
            
                            numOfWorkers: 2,
                            frequency: 10,

                            willReadFrequently: true,
            
                            decoder: {
            
                                readers : [{
                                    format: "ean_reader",
                                    config: {}
                                }]
            
                            },
            
                            locate: true
            
                            }, function(err) {
            
                            if (err) {
                                console.log(err);
                                return;
                            }

                            Quagga.start();

                            Quagga.onProcessed(function() {

                                $('.ean-holder').css({
                                    opacity: 1
                                });

                                Creation.ean.starting = false;

                            });

                        });
            
                    }
            
                };
            
                App.init();
    
                let lastresults = [];
    
                Quagga.onDetected(function(result) {
            
                    var code = result.codeResult.code;
    
                    lastresults.push(code);
    
                    $('[name="ean"]').val(code);
    
                    if(lastresults.length > 3) lastresults.shift();
    
                    if(lastresults[0] == lastresults[1] && lastresults[1] == lastresults[2]){
    
                        Quagga.stop();
    
                        Creation.ean.search();
    
                    }
    
                });
            
            });
    

        },

        reload(){

            if(location.pathname != '/cadastro/ean') return false;

            // Click on the [href="/cadastro/ean"]
            $('[page="ean"]').click();

        },

        load(){

            if(location.pathname != '/cadastro/ean') return false;

            if(Creation.loading){
                Creation.loading.close();
                Creation.loading = false;
            }

            // Reseta o elemento .ean-holder, colocando o html dele como o html do outer
            $('.ean-holder').html($('.ean-holder-outer').html());


            Creation.ean.startCam();

            Creation.ean.searching = false;

            Creation.ean.getLastCreated();

        },

        getLastCreated: function(){

            Api.get('/v1/creation/last/ean').then(function(res){

                if(res.error){

                    // @dry
                    $('.creation.ean').show();

                    $('.creation.ean [name="ean"]').focus();

                    $('.creation.ean [name="ean"]').off('keyup');
                    $('.creation.ean [name="ean"]').on('keyup', function(e){

                        if(e.keyCode == 13){

                            Creation.ean.search();

                        }

                    });

                    $('.creation .prod-info').html('');

                } else{

                    $('.ean-holder').hide();
                    $('.creation.ean').hide();

                    // Aqui, vamos também finalizar o stream de video, para não ficar consumindo processo
                    setTimeout(function(){

                        if(!Creation.ean.starting) Quagga.stop();

                    }, 4000);

                    let approve = res;

                    Creation.ean.viewing = approve;

                    Creation.ean.view(approve);

                }

            }).catch(function(error){

                // @dry
                $('.creation.ean').show();

                $('.creation.ean [name="ean"]').focus();

                $('.creation.ean [name="ean"]').off('keyup');
                $('.creation.ean [name="ean"]').on('keyup', function(e){

                    if(e.keyCode == 13){

                        Creation.ean.search();

                    }

                });

                $('.creation .prod-info').html('');

            });

        },

        viewUsage: function(id){

            Approve.byId(id).then(approve => {

                Creation.ean.view(approve);

            });

        },

        view(usage){

            $('.creation.ean').hide();
            $('.creation.view-description').show();

            // Caso não encontre o item .prod-info dentro de .creation.view-description, vamos criar um
            if(!$('.creation.view-description .prod-info').length){

                $('.creation.view-description').append('<div class="prod-info"></div>');

            }

            Approve.showLine(usage);

            $('.creation.view-description .remove').off('click');
            $('.creation.view-description .remove').on('click', function(){

                Approve.remove(usage.id).then(function(){

                    history.pushState({}, '', location.pathname);

                    Creation.ean.load();

                });

            });

        },

        parseEventGenerated(usage){

            $('.creation.ean').hide();
            $('.creation.loading').hide();

            if(usage.error && Creation.ean.searching){

                return Helpers.type($('.creation.ean .msg'), 'Ocorreu um erro ao gerar o cadastro');

            }

            Creation.ean.viewUsage(usage.id);

        },

        isValid: function(ean){

            return true;

            // @todo Talvez vamos aceitar outros códigos, mas por enquanto é essa a verificação
            // return ean.length == 13 && ean.match(/^[0-9]+$/);

        },

        waitingBatch: null,

        search: function(){

            let ean = $('.creation.ean [name="ean"]').val();

            if(!ean){

                Helpers.type($('.creation.ean .msg'), 'Preencha o campo EAN');

                $('.creation.ean [name="ean"]').focus();

                return false;

            }

            if(!Creation.ean.isValid(ean)){

                return Helpers.type($('.creation.ean .msg'), 'EAN inválido');

            }

            $('.creation.ean').hide();
            $('.ean-holder').hide();

            $('.creation.loading').show();
            $('.creation.loading .loading-msg').text(I18n.get('Buscando produto'));

            let sendData = {
                data: [
                    {
                        "Nome": "",
                        "Marca": "",
                        "Ean": ean
                    }
                ],
                opts: {
                    preserveName: false,
                    company_info: false,
                    brand_info: false,
                    namePattern: [
                        {
                            name: "Nome",
                            order: 0
                        },
                        {
                            name: " - ",
                            order: 1
                        }
                    ]
                }
            }

            // @todo dry 31039019
            Styles.hook('Criando descrições', async (dataWs) => {

                console.log(dataWs);

                if(dataWs.planUsageId && dataWs.batchId == Creation.ean.waitingBatch){

                    console.log('Opaa foi encontrado e tá pronto');

                    $('.creation.loading').hide();

                    Creation.ean.viewUsage(dataWs.planUsageId);
                    
                }

            });

            Creation.ean.waitingBatch = null;

            Api.post('/api/dashboard/mass', sendData).then(function(response){

                Creation.ean.waitingBatch = response.batchId;

                $('.creation.loading .loading-msg').text(I18n.get('Oba! Encontramos o produto!'));

            }).catch(function(error){

                $('.creation.ean').show();

                if(error.error){

                    Creation.toWithoutEan();

                    return Helpers.type($('.creation.ean .msg'), error.error);

                }

                return Alerts.ok('Ocorreu um erro ao buscar o produto', JSON.stringify(error));

            });

        }

    },

    toWithoutEan: function(){

        $('[page="produto"]').click();

    },

    toEan: function(){

        $('[page="ean"]').click();

    }

}

Nav.addTrigger('/cadastro/produto', function(){

    Creation.product.load();

});

Nav.addTrigger('/cadastro/ean', function(){

    Creation.ean.load();

});

Nav.addTrigger('/cadastro/imagem/massa', function(){

    // $('.header').on('typed', function(){

    //     if($('.import-files').length) return;

    //     $('.header').append('&nbsp;&nbsp;&nbsp;<button class="import-files">Importar</button>');

    //     $('.import-files').on('click', function(){

    //         $('#images-file').click();

    //     });

    // });

    Creation.im.load();

});

// Handle the directories
$('.image-mass #images-file').on('change', function(e){

    let files = e.target.files;

    Creation.im.parseFiles(files);

    $(this).val('');

});

$('.image-mass .image-dropzones .droparea').on('drop', function(e){

    let files = e.originalEvent.dataTransfer.files;

    Creation.im.parseFiles(files);

});

function LayoutGradesAndVariante() {
    const apiStorage = Apis.getApi();

    if (apiStorage && apiStorage === 'lojaintegrada_LojaIntegrada') {
        $('button.grades').addClass('show');

        function createOptionsComponent(options = []) {
            return options.map(option => `<option value="${option.id}">${option.nome}</option>`).join('');
        }

        function optionDefaultGradeComponent(text = '') {
            return `<option disabled selected>Selecione uma ${text}</option>`;
        }

        Api.get(`/v1/apis/grades/${apiStorage}`).then((items) => {
            const gradeCompnent = createOptionsComponent(items);
            const selectGrade = $('.grades-select');
            const selectVariant = $('.variants-select');

            selectGrade.html(`${optionDefaultGradeComponent('grade')}${gradeCompnent}`);
            selectGrade.on('change', (event) => {
                const value = event.target.value;
        
                selectVariant.html('<option>Buscando...</option>');
                Api.get(`/v1/apis/variaveis/${value}/${apiStorage}`).then((items) => {
                    const variantCompnent = createOptionsComponent(items.objects);
                    selectVariant.html(`${optionDefaultGradeComponent('variável')}${variantCompnent}`);
                })
                .catch(() => selectVariant.html(''));
            });
        });
    }
}
