<?php

use system\library\marketplace\MktPriceAdjustments;

class DModelmarketplacemktproduto extends Model
{

    public function __construct($registry)
    {
        parent::__construct($registry);
    }

    public function setError($error, $product_key_id, $mkt_tipo, $product_ket_type = Type_ProdutoMkt::Tp_MktProd_Normal)
    {
        $arrayError = explode('-', $error);
        $mensagemError = $this->mercadolivre->TranslateError($error);
        $dataLastError = $this->db->dataAtual();

        $sql = "UPDATE oc_marketplace_product SET date_last_error = '" . $this->db->escape($dataLastError) . "', cod_error = '" . $this->db->escape(trim($arrayError[0])) . "', mensagem_error = '" . $this->db->escape($mensagemError) . "' WHERE product_key_id = '" . $product_key_id . "' and tipo_produto = " . $product_ket_type . " and tipo_integracao = $mkt_tipo";

        $query = $this->db->query($sql);
    }

    public function getProdutoClasses($product_key_id, $type_produto, $marketplace, $data = array())
    {
        if (empty($product_key_id)) {
            return false;
        }

        $mktPriceAdjustments = new MktPriceAdjustments($this->registry, ['tipo_integracao' => $marketplace]);

        $this->load->dmodel('catalog/product');
        $this->load->dmodel('catalog/productgrid');
        $this->load->dmodel('mercadolivre/meliproduto');
        $this->load->dmodel('skyhub/skyproduto');
        $this->load->dmodel('galeriapage/gpproduto');
        $this->load->dmodel('shopee/shopeeproduto');
        $this->load->dmodel('catalog/category');
        $this->load->dmodel('marketplace/mktproduto' . strtolower(Type_MarketPlace::getNickFromConstValue($marketplace)));
        $this->load->helper('ftr_validacao');

        /**
         * função que me retonar a mktprice padrão caso não tenha nada setado na marketplace_product
         */
        $request_merca_table_price = (isset($data['merca_table_price']) && ($data['merca_table_price'] != '')) ? $data['merca_table_price'] : NULL;
        $resultMktPrice = $this->dmodel_marketplace_mktprice->getMktPriceOrStandard($request_merca_table_price, $product_key_id, $marketplace);
        if (!$resultMktPrice) {
            throw new Exception('Nenhuma marketprice encontrada');
        }

        $this->{'dmodel_marketplace_mktproduto' . strtolower(Type_MarketPlace::getNickFromConstValue($marketplace))}->setCustomerGroupId($resultMktPrice->getCustomerGroupId());

        if ($type_produto == Type_ProdutoMkt::Tp_MktProd_Normal) {
            $product = $this->{'dmodel_marketplace_mktproduto' . strtolower(Type_MarketPlace::getNickFromConstValue($marketplace))}->getProduct($product_key_id);
        } else {
            $product = $this->{'dmodel_marketplace_mktproduto' . strtolower(Type_MarketPlace::getNickFromConstValue($marketplace))}->getProductGrid($product_key_id);
        }

        $produtoClass = new MktProduto();

        //----Carregando as imagens Ps. Quando grade, carrega as imagens do produto principal, vinculado a grade
        $ProdutoimagemClass = new MktProdutoImagem();

        // Limite de imagens aceito pelos Marketplaces
        switch ($marketplace){
            case Type_MarketPlace::Tp_SkyHub:
                $limitImages = 19;
                break;
            case Type_MarketPlace::Tp_Shopee:
                $limitImages = 8;
                break;
            default: $limitImages = null;
        }
        $product_images = $this->dmodel_catalog_product->getProductImages($product['product_id'], $limitImages, $marketplace);

        if ($product['image']) {
            $ProdutoimagemClass->addImagem($this->urlloja->link('', '', 'SSL', false) . 'image/' . $product['image'],
                DIR_IMAGE . $product['image'], 0, $product['marketplace_image_id'], $product['id_futura_img'], $product['marketplace_image_id_futura']);
        }

        foreach ($product_images as $product_image) {
            $ProdutoimagemClass->addImagem($this->urlloja->link('', '', 'SSL', false) . 'image/' . $product_image['image'],
                DIR_IMAGE . $product_image['image'], $product_image['product_image_id'], $product_image['marketplace_image_id'],
                $product_image['id_futura'], $product_image['marketplace_image_id_futura']);
        }

        $produtoClass->setImagemObj($ProdutoimagemClass);
        //----Carregando as imagens^^

        $specialPrice = $this->dmodel_catalog_product->getPriceTabelaproduct_id($product['product_id']);
        if ($specialPrice > 0) {
            $price = $specialPrice;
        } else {
            $price = (isset($product['table_price']) && !is_null($product['table_price'])) ? $product['table_price'] : $product['price'];
        }

        // Marketplaces Preço
        if (in_array($marketplace, [Type_MarketPlace::Tp_SkyHub, Type_MarketPlace::Tp_Galeriapage, Type_MarketPlace::Tp_Shopee])) {
            $mktPriceInfo = array(
                'price' => $price,
                'marketplace_price_id' => (isset($data['merca_table_price']) && ($data['merca_table_price'] != '')) ? $data['merca_table_price'] : $product['marketplace_price_id'],
                'product_id' => $product['product_id']
            );
            $price = $mktPriceAdjustments->getMktPrice($mktPriceInfo);
        }

        if (strlen($product['name']) > 60) {
            $product['name'] = mb_substr($product['name'], 0, 60);
        }

        $desc = (isset($product['description_complete_s_format']) && (trim($product['description_complete_s_format']) != '')) ? trim($product['description_complete_s_format']) : trim(str_replace(array('<br>', '<BR>', '<br/>', '<br class="Apple-interchange-newline">'), PHP_EOL, strip_tags(html_entity_decode(str_replace('&nbsp;', '', $product['description']), ENT_QUOTES, 'UTF-8'), '<br>')));

        $produtoClass->setProductid($product['product_key_id']);
        $produtoClass->setSku($product['product_id']);
        $produtoClass->setModel($product['model']);
        $produtoClass->setCodigoBarra($product['codigo_barra']);
        if (isset($data['custom_title'])) {
            $produtoClass->setCustomTitle($data['custom_title']);
        } else {
            $produtoClass->setCustomTitle($product['mkt_custom_title']);
        }
        $produtoClass->setName($product['name']);
        $produtoClass->setDescription($desc);
        $produtoClass->setWeight($product['weight']);
        $produtoClass->setHeight($product['height']);
        $produtoClass->setWidth($product['width']);
        $produtoClass->setLength($product['length']);
        $produtoClass->setMarca($product['manufacturer_name']);
        $produtoClass->setQuantity($product['qty_mkt']);
        $produtoClass->setTipo($product['tipo']);
        $produtoClass->setPrice($price);
        $produtoClass->setMktId($product['product_marketId']);
        $produtoClass->setMktCodigoBarras($product['mkt_codigo_barras']);

        if (!isset($product['marketplace_price_id']) || is_null($product['marketplace_price_id'])
            || (!is_null($request_merca_table_price) && ($product['marketplace_price_id'] != $resultMktPrice->getMarketplacePriceId()) )) {
            $product['marketplace_price_id'] = $resultMktPrice->getMarketplacePriceId();
            $product['marketplaceprice_config_md5'] = $resultMktPrice->getMarketplacePriceMd5();
        }
        $produtoClass->setMarketplacePriceId($product['marketplace_price_id']);
        $produtoClass->setMarketplacepriceConfigMd5($product['marketplaceprice_config_md5']);

        if ($marketplace == Type_MarketPlace::Tp_Mercadolivre) {
            $produtoClass->setVariationColor($product['mercaVariationColor']);
            $produtoClass->setVariationSize($product['mercaVariationSize']);
            $produtoClass->setVariationSpecification($product['mercaVariationSpecification']);
            $produtoClass->setIdYoutubeVideo($product['mercaVideoId']);
        }

        if ($type_produto == Type_ProdutoMkt::Tp_MktProd_Grade) {
            $status_grade_geral = TypeProduct_Status::Tp_Desabilitado;

            $gridItens = $this->{'dmodel_marketplace_mktproduto' . strtolower(Type_MarketPlace::getNickFromConstValue($marketplace))}->getProductsFromGrid($product['product_key_id']);
            //vamos buscar todas as opções da grade para montar as variações...
            $quantity = 0;
            foreach ($gridItens as $items) {
                //Captura as imagens da grade...
                $ProdutoimagemClass = new MktProdutoImagem();

                // Limite de imagens aceito pelos Marketplaces
                switch ($marketplace){
                    case Type_MarketPlace::Tp_SkyHub:
                        $limitImages = 19;
                        break;
                    case Type_MarketPlace::Tp_Shopee:
                        $limitImages = 8;
                        break;
                    default: $limitImages = null;
                }
                $product_images = $this->dmodel_catalog_product->getProductImages($items['product_id'], $limitImages, $marketplace);

                if ($items['image']) {
                    $ProdutoimagemClass->addImagem($this->urlloja->link('', '', 'SSL', false) . 'image/' . $items['image'],
                        DIR_IMAGE . $items['image'], 0, $items['marketplace_image_id'], $items['id_futura_img'], $items['marketplace_image_id_futura']);
                }

                foreach ($product_images as $product_image) {
                    $ProdutoimagemClass->addImagem($this->urlloja->link('', '', 'SSL', false) . 'image/' . $product_image['image'],
                        DIR_IMAGE . $product_image['image'], $product_image['product_image_id'], $product_image['marketplace_image_id'],
                        $items['id_futura_img'], $items['marketplace_image_id_futura']);
                }

                /*$mktPriceInfo = array (
                    'price' => $items['price'],
                    'marketplace_price_id' => $product['marketplace_price_id'],
                    'product_id' => $items['product_id']
                );
                $itemPrice = $mktPriceAdjustments->getMktPrice($mktPriceInfo);*/

                // POR QUE O ESQUISITO QUE FEZ ISSO AQUI NÃO JOGA O PREÇO CORRETO NA GRADE, E COLOCA A REGRA DE NEGÓCIO NO MARKETPLACE ?????????????
                // AGORA EU TENHO QUE COLOCAR UM IF LIXO, PORQUE EU NÃO VOU RETESTAR TODOS OS MARKETPLACES PRA VER SE FUNCIONA DO JEITO CERTO
                if (in_array($marketplace, [Type_MarketPlace::Tp_Shopee])) {
                    $mktPriceInfo = array(
                        'price' => $items['price'],
                        'marketplace_price_id' => $product['marketplace_price_id'],
                        'product_id' => $items['product_id']
                    );
                    $itemPrice = $mktPriceAdjustments->getMktPrice($mktPriceInfo);
                } else {
                    $itemPrice = $price; /*(isset($items['table_price']) && !is_null($items['table_price'])) ? $items['table_price'] : $items['price'];
                      A grade de produto não tem variação de preço por item...
                    */
                }

                $variacoes = new MktVariacoes();
                $variacoes->setProductID($items['product_id']);
                $variacoes->setSku($items['product_id']);
                $variacoes->setCor($items['color_description']);
                $variacoes->setEspecificacao($items['specification_description']);
                $variacoes->setTamanho($items['size_description']);
                $variacoes->setTemplateID($items['grid_template_id']);
                $variacoes->setTemplateCor($items['color_template_description']);
                $variacoes->setTemplateEspecificacao($items['specification_template_description']);
                $variacoes->setTemplateTamanho($items['size_template_description']);
                $variacoes->setCodigoBarra($items['codigo_barra']);
                $variacoes->setQuantity($items['qty_mkt']);
                $variacoes->setValor($itemPrice);
                $variacoes->setImagens($ProdutoimagemClass);
                $variacoes->setStatus($items['status']);

                if (ftr_validacao::validaTipo($items['status'], TypeProduct_Status::Tp_Habilitado)) {
                    $quantityAux = $items['qty_mkt'] > 0 ? $items['qty_mkt'] : 0;
                    $quantity += $quantityAux;
                    $status_grade_geral = TypeProduct_Status::Tp_Habilitado;
                }

                $mktVariation = $this->{'dmodel_marketplace_mktproduto' . strtolower(Type_MarketPlace::getNickFromConstValue($marketplace))}->getMktVariationId($items['product_id']);

                if ($mktVariation) {
                    $variacoes->setMktVariation_id($mktVariation);
                } else {
                    $variacoes->setMktVariation_id(null);
                }

                $produtoClass->setVariacao($variacoes);
            }
            $produtoClass->setQuantity($quantity);
            $produtoClass->setStatus($status_grade_geral);

        } else {

            if ($marketplace == Type_MarketPlace::Tp_Mercadolivre) {
                // transforma um produto normal em um produto com variação
                $gradeInfo = array(
                    $product['product_color_id'],
                    $product['product_size_id'],
                    $product['product_specification_id']
                );

                if(count(array_filter($gradeInfo)) > 0){
                    $variacoes = new MktVariacoes();
                    $variacoes->setProductID($product['product_key_id']);
                    $variacoes->setSku($product['product_id']);
                    $variacoes->setCor($product['color']);
                    $variacoes->setTamanho($product['size']);
                    $variacoes->setEspecificacao($product['specification']);
                    $variacoes->setCodigoBarra($product['mkt_codigo_barras']);
                    $variacoes->setQuantity($product['qty_mkt']);
                    $variacoes->setValor($price);
                    $variacoes->setImagens($ProdutoimagemClass);
                    $variacoes->setStatus($product['status']);

                    $mktVariation = $this->{'dmodel_marketplace_mktproduto' . strtolower(Type_MarketPlace::getNickFromConstValue($marketplace))}->getMktVariationId($product['product_id']);

                    if ($mktVariation) {
                        $variacoes->setMktVariation_id($mktVariation);
                    } else {
                        $variacoes->setMktVariation_id(null);
                    }

                    $produtoClass->setVariacao($variacoes);
                }

            }

            $produtoClass->setQuantity($product['qty_mkt']);
            $produtoClass->setPrice($price);
            $produtoClass->setStatus($product['status']);
        }

        $categoryList = $this->dmodel_catalog_category->getCategorysTreeProduto($product['product_id']);

        if (sizeof($categoryList) > 0) {
            //quer dizer que tem departamento, pois tem 3 niveis...
            if (isset($categoryList[Type_NivelCategoria::Tp_Departamento])) {
                $catList = new MktProdutoCategoria();
                $catList->setCode($categoryList[Type_NivelCategoria::Tp_Departamento]['category_id']);
                $catList->setName($categoryList[Type_NivelCategoria::Tp_Departamento]['category_name']);
                $produtoClass->setDepartamento($catList);
            }

            $catList = new MktProdutoCategoria();
            $catList->setCode($categoryList[Type_NivelCategoria::Tp_Grupo]['category_id']);
            $catList->setName($categoryList[Type_NivelCategoria::Tp_Grupo]['category_name']);
            $produtoClass->setGrupo($catList);

            $catList = new MktProdutoCategoria();
            $catList->setCode($categoryList[Type_NivelCategoria::Tp_SubGrupo]['category_id']);
            $catList->setName($categoryList[Type_NivelCategoria::Tp_SubGrupo]['category_name']);
            $produtoClass->setSubGrupo($catList);
        }

        switch ($marketplace){
            case Type_MarketPlace::Tp_Mercadolivre:
                $addFields = $this->dmodel_mercadolivre_meliproduto->getAdtionalFieldsML($product, $type_produto);
                break;
            case Type_MarketPlace::Tp_SkyHub:
                $addFields = $this->dmodel_skyhub_skyproduto->getAdtionalFields($product, $type_produto);;
                break;
            case Type_MarketPlace::Tp_Galeriapage:
                $addFields = $this->dmodel_galeriapage_gpproduto->getAdtionalFields($product, $type_produto, $data);
                break;
            case Type_MarketPlace::Tp_Shopee:
                $addFields = $this->dmodel_shopee_shopeeproduto->getAdditionalFieldsShopee($product, $type_produto, $data);
                break;
        }

        foreach ($addFields as $key => $field) {
            $produtoClass->setParam($key, $field);
        }

        return $produtoClass;
    }

    public function mountSystemVariations($produtoClass){
        $result = [];

        foreach ($produtoClass->getVariacao() as $variacoes){
            $object = [
                'product_id' => $variacoes->getProductID(),
                'description' => $this->getVariationDescription($variacoes),
                'price' => $variacoes->getValor(),
                'formated_price' => $this->currency->format($variacoes->getValor()),
                'stock' => $variacoes->getQuantity(),
            ];

            $result[] = $object;
        }

        return $result;
    }

    public function getVariationDescription(MktVariacoes $variation){
        $variationDescription = '';

        if (!is_null($variation->getCor())){
            $this->concatVariationDescription($variationDescription, $variation->getTemplateCor() . ': ' . $variation->getCor());
        }

        if (!is_null($variation->getTamanho())){
            $this->concatVariationDescription($variationDescription, $variation->getTemplateTamanho() . ': ' . $variation->getTamanho());
        }

        if (!is_null($variation->getEspecificacao())){
            $this->concatVariationDescription($variationDescription, $variation->getTemplateEspecificacao() . ': ' . $variation->getEspecificacao());
        }

        return $variationDescription;
    }

    public function concatVariationDescription(&$description, $variationString){
        $description .= (empty($description) ? '' : ' - ') . $variationString;
    }

    public function synchronizeProductEstoque($product_id, $mkt_id, $marketplace, $type_produto = Type_ProdutoMkt::Tp_MktProd_Normal)
    {
        if ($marketplace == Type_MarketPlace::Tp_Mercadolivre) {
            $this->load->dmodel('mercadolivre/meliproduto');
            if ($this->dmodel_mercadolivre_meliproduto->getProductsMercadolivreHaveGradeItem($product_id)) {
                throw new Exception(Type_ErrorGrade::Tp_ErGrid . " - " . Type_ErrorGrade::getNickFromValue(Type_ErrorGrade::Tp_ErGrid));
            }
        }
        $produtoClass = $this->getProdutoClasses($product_id, $type_produto, $marketplace);
        return $this->marketplace->setAtualizarEstoque($produtoClass, $mkt_id, $marketplace);
    }

    public function synchronizeProductEstoquePreco($product_id, $mkt_id, $marketplace, $type_produto = Type_ProdutoMkt::Tp_MktProd_Normal)
    {
        $produtoClass = $this->getProdutoClasses($product_id, $type_produto, $marketplace);
        return $this->marketplace->setAtualizarEstoquePreco($produtoClass, $mkt_id, $marketplace);
    }

    public function synchronizeProductEstoquePrecoStatus($product_id, $mkt_id, $marketplace, $type_produto = Type_ProdutoMkt::Tp_MktProd_Normal)
    {
        $produtoClass = $this->getProdutoClasses($product_id, $type_produto, $marketplace);
        return $this->marketplace->setAtualizarEstoquePrecoStatus($produtoClass, $mkt_id, $marketplace);
    }

    public function synchronizeProduct($product_id, $type_produto, $marketplace,
                                       $stockUpdate = false, $urlautomatica = false, $data = array())
    {
        if (empty($product_id)) {
            return false;
        }

        if ($marketplace == Type_MarketPlace::Tp_Mercadolivre) {
            $this->load->dmodel('mercadolivre/meliproduto');
            if ($this->dmodel_mercadolivre_meliproduto->getProductsMercadolivreHaveGradeItem($product_id)) {
                throw new Exception(Type_ErrorGrade::Tp_ErGrid . " - " . Type_ErrorGrade::getNickFromValue(Type_ErrorGrade::Tp_ErGrid));
            }
        }

        $this->load->dmodel('catalog/product');
        $this->load->type('tipocomum');
        $this->load->helper('ftr_geral');

        $dataAtualizacao = $this->db->dataAtual();
        $produtoClass = $this->getProdutoClasses($product_id, $type_produto, $marketplace, $data);
        $data_prod_estoque_att = null;
        $not_price_page = array();

        if ($marketplace == Type_MarketPlace::Tp_Galeriapage) {
            if (($produtoClass->getMktId() != null) && ($produtoClass->getCodigoBarra() != $produtoClass->getMktCodigoBarras())) {
                throw new Exception(sprintf($this->language->get('error_barcode_changed'), $produtoClass->getMktCodigoBarras(), $produtoClass->getCodigoBarra()));
            }

            if (empty($produtoClass->getParam('gp_subcategory_id'))) {
                throw new Exception(Type_GaleriaPageErrors::getNickFromValue(Type_GaleriaPageErrors::Tp_EmptyCategory));
            }
        }

        if ((($marketplace == Type_MarketPlace::Tp_Mercadolivre)) && (empty($produtoClass->getParam('mercaId')))) {
            foreach ($produtoClass->getVariacao() as $variation) {
                if ((!empty($variation->getMktVariation_id())) && ($variation->getMktVariation_id() != '')) {
                    $sql = 'delete from oc_marketplace_product_variation where product_id = ' . $variation->getProductID() . ' and  tipo_integracao =' . $marketplace;
                    $this->db->query($sql);
                }
            }
            $produtoClass = $this->getProdutoClasses($product_id, $type_produto, $marketplace, $data);
        }

        // Essa parte serve pra enviar os produtos da grade como se fossem unicos, porque na Galeria Page nao tem grade de produtos
        if ($marketplace == Type_MarketPlace::Tp_Galeriapage && $type_produto == Type_ProdutoMkt::Tp_MktProd_Grade) {
            foreach ($produtoClass->getVariacao() as $variation) {
                if ($variation->getValor() <= 0) {
                    $this->session->data['mkt_warning'][$variation->getProductID()] = 'Não é possivél sincronizar produtos com valor zerado!';
                    $this->session->data['warning_mkt_global'] = 'Impossível sincronizar produtos com preços zerados';
                    continue;
                }
                $this->setGpGridData($produtoClass, $variation, $data);
                $this->synchronizeProduct($variation->getSku(), Type_ProdutoMkt::Tp_MktProd_Normal, $marketplace, $stockUpdate, $urlautomatica, $data);
            }
        } else {
            try {
                $data['type_product'] = $type_produto;
                $dadosproduto_att = $this->marketplace->setAtualizarProduto($produtoClass, $marketplace, $data);
                if ($dadosproduto_att === false) {
                    return false;
                }
                $data_prod_att = $dataAtualizacao;

                if ($stockUpdate) {
                    $dadosproduto_att = $this->marketplace->setAtualizarEstoqueFromProdutos($produtoClass, $dadosproduto_att->getMktRetorno(), $marketplace);
                    $data_prod_estoque_att = $dataAtualizacao;
                }

                $this->limpaErrosDB($produtoClass->getProductid(), $marketplace, $type_produto);

                if (!$urlautomatica) {
                    $marketplaceNick = strtolower(Type_MarketPlace::getNickFromValue($marketplace));
                    $config_md5 = $this->config->get($marketplaceNick . '_configs_md5');
                    $config_md5_mktfield = 'marketplace_config_md5';

                    $dataUpdate = array (
                        $config_md5_mktfield => $config_md5,
                        'marketplace_price_id' => (int)$produtoClass->getMarketplacePriceId(),
                        'marketplaceprice_config_md5' => $produtoClass->getMarketplacepriceConfigMd5(),
                        'date_att_price' => $data_prod_estoque_att
                    ) ;
                    $this->saveProductMarketPlaceFromProd($dadosproduto_att, $produtoClass->getProductid(), $type_produto, $data_prod_estoque_att, $data_prod_att, $dataUpdate);
                }

                if ($marketplace == Type_MarketPlace::Tp_Mercadolivre) {
                    $this->dmodel_mercadolivre_meliproduto->salvarDadosMercadoLivre($dadosproduto_att, $type_produto, $marketplace);
                    $this->dmodel_mercadolivre_meliproduto->setWarningsMeli($produtoClass);
                }

                return $dadosproduto_att;

            } catch (ExceptionProductNotExists $e) {
                throw new ExceptionProductNotExists($e->getMessage());
            } catch (ExceptionErrorShow $e) {
                throw new Exception($e->getMessage());
            } catch (Exception $e) {
                $this->UpdateProductMarketPlace($produtoClass->getProductid(), null, $marketplace, $type_produto);
                $this->setError($e->getMessage(), $produtoClass->getProductid(), $marketplace, $type_produto);
                throw new Exception($e->getMessage(), 0, $e->getPrevious());
            }
        }

    }

    public function desynchronizeMktProduct($marketid, $id, $marketplace)
    {
        $this->marketplace->setDesincronizarProduto($marketid, $id, $marketplace);
    }

    public function deleteMktProduct($product_id, $tipo_produto, $marketplace)
    {
        $this->db->query("DELETE FROM oc_marketplace_product WHERE product_key_id = '$product_id' and tipo_produto = $tipo_produto and tipo_integracao = $marketplace");
    }

    public function desynchronizeProduct($product_id, $marketplace, $tipo_produto = Type_ProdutoMkt::Tp_MktProd_Normal)
    {
        $product_id = (int)$product_id;
        $product_info = $this->db->query("SELECT * FROM oc_marketplace_product
                                          WHERE product_key_id = '$product_id' and tipo_produto = $tipo_produto and tipo_integracao = $marketplace")->row;

        if ($product_info) {
            try {
                $this->desynchronizeMktProduct($product_info['marketId'], $product_info['id'], $marketplace);
                $this->deleteMktProduct($product_id, $tipo_produto, $marketplace);
            } catch (Exception $e) {
                if ($marketplace == Type_MarketPlace::Tp_SkyHub) {
                    $this->deleteMktProduct($product_id, $tipo_produto, $marketplace);
                    throw new Exception($e->getMessage() . ' (Removido o vinculo no ecommerce)');
                } else {
                    throw new Exception($e->getMessage());
                }
            }
        }

        return true;
    }

    public function unlinkProduct($product_key_id, $tipo_produto, $marketplace)
    {
        $sql = "DELETE FROM oc_marketplace_product WHERE product_key_id = ? and tipo_produto = ? and tipo_integracao = ?";
        $this->db->executeSql($sql, [$product_key_id, $tipo_produto, $marketplace]);
    }

    public function limpaErrosDB($product_key_id, $mkt_tipo, $type_produto = Type_ProdutoMkt::Tp_MktProd_Normal)
    {
        $sql = "UPDATE oc_marketplace_product  set date_last_error = NULL , cod_error = NULL, mensagem_error = NULL WHERE product_key_id = ? and tipo_produto = ? and tipo_integracao = ?";
        $result = $this->db->executeSql($sql, [$product_key_id, $type_produto, $mkt_tipo]);
    }

    public function saveProductMarketPlaceFromProd($produto, $product_key_id, $product_key_tipo = Type_ProdutoMkt::Tp_MktProd_Normal,
                                                   $data_att_estoque = null, $data_att_produto = null, $additional_data = array())
    {

        $prod_retorno = $produto->getMktRetorno();

        $adtional_sql = "";

        if ($data_att_estoque) {
            $adtional_sql .= " , date_att_estoque = '" . $this->db->escape($data_att_estoque) . "'";
        }

        if ($data_att_produto) {
            $adtional_sql .= " , date_att_produto = '" . $this->db->escape($data_att_produto) . "'";
        }

        if (!empty($additional_data)) {
            foreach ($additional_data as $key => $value) {
                /**
                 * verificação feita por que o campo marketplace_price_id é uma foreingkey
                 * e quando não passa nenhum valor nesse campo ele tem que ser NULL
                */
                if(!is_null($value)){
                    $adtional_sql .= " , " . $key . " = '" . $this->db->escape($value) . "'";
                } else {
                    $adtional_sql .= " , " . $key . " = NULL ";
                }

            }
        }

        $codigoBarras = $produto->getCodigoBarra() ?? "";

        $merca_product = $this->db->query(
            " SELECT"
            . " *  "
            . " FROM `oc_marketplace_product` "
            . " WHERE `product_key_id` = '" . $product_key_id . "'"
            . " and `tipo_integracao` = " . $prod_retorno->getmktTipo()
            . " and       `tipo_produto` = " . $product_key_tipo
        )->row;

        if ($merca_product) {
            $this->db->query(
                " UPDATE oc_marketplace_product SET"
                . " `status`      = '" . $this->db->escape($prod_retorno->getmktStatus()) . "',"
                . " substatus     = '',"
                . " url           = '" . $this->db->escape($prod_retorno->getmktLink()) . "',"
                . " custom_title  = '" . $this->db->escape($prod_retorno->getmktName()) . "',"
                . " sold_quantity = '" . $this->db->escape($prod_retorno->getmktQtdVendido()) . "'"
                . $adtional_sql
                . " WHERE product_key_id   = " . $product_key_id
                . "   and (tipo_produto    = " . $product_key_tipo . ")"
                . "   and (tipo_integracao = " . $prod_retorno->getmktTipo() . ")"
            );
        } else {
            $sql = "INSERT into oc_marketplace_product SET"
                . " tipo_integracao = '" . $prod_retorno->getmktTipo() . "',"
                . " status = '" . $this->db->escape($prod_retorno->getmktStatus()) . "',"
                . " substatus = '',"
                . " url = '" . $this->db->escape($prod_retorno->getmktLink()) . "',"
                . " custom_title = '" . $this->db->escape($prod_retorno->getmktName()) . "',"
                . " sold_quantity='" . $this->db->escape($prod_retorno->getmktQtdVendido()) . "',"
                . " marketId = '" . $prod_retorno->getmktIntegrationId() . "',"
                . " tipo_produto = " . $product_key_tipo . ","
                . " product_key_id = " . $product_key_id . ","
                . " codigo_barras = '" . $this->db->escape($codigoBarras) . "'"
                . $adtional_sql;
            $this->db->query($sql);
        }


        //Salvando dados da variação...
        foreach ($produto->getVariacao() as $variation) {
            if ((!empty($variation->getMktVariation_id())) && ($variation->getMktVariation_id() != '')) {
                $sql = 'delete from oc_marketplace_product_variation where product_id = ' . $variation->getProductID() . ' and  tipo_integracao =' . $prod_retorno->getmktTipo();
                $this->db->query($sql);

                $sqlIns = " INSERT INTO oc_marketplace_product_variation set "
                    . " product_id = " . $variation->getProductID() . ","
                    . " mkt_variation_id = '" . $variation->getMktVariation_id() . "',"
                    . " tipo_integracao = " . $prod_retorno->getmktTipo();
                $this->db->query($sqlIns);
            }
        }

    }

    public function setProductMarketPlaceStatus($product_key_id, $product_key_tipo, $type_marketplace, $status){
        return $this->db->query(
            " UPDATE oc_marketplace_product SET"
            . " `status` = '" . $this->db->escape($status) . "'"
            . " WHERE product_key_id   = " . $product_key_id
            . "   and (tipo_produto    = " . $product_key_tipo . ")"
            . "   and (tipo_integracao = " .$type_marketplace . ")"
        );
    }

        public function getTipoKeyMarketplace($marketPlaceId, $marketplace)
    {
        $sql = "SELECT * FROM oc_marketplace_product
                WHERE marketId = '$marketPlaceId' and tipo_integracao = $marketplace";

        $product_mkt = $this->db->query($sql)->row;
        if ($product_mkt) {
            return $product_mkt['tipo_produto'];
        } else {
            return false;
        }


    }

    public function UpdateProductMarketPlace($product_id = null, $marketId = null, $marketplace = null, $tipo_key = Type_ProdutoMkt::Tp_MktProd_Normal)
    {
        if ((!$product_id) && (!$marketId)) {
            throw new Exception('Id do produto ou do marketplace devem ser informados!');
        }
        $sql = "SELECT * FROM oc_marketplace_product";

        if ($product_id) {
            $sql .= " WHERE product_key_id = $product_id and tipo_produto = $tipo_key and tipo_integracao = $marketplace";
        }

        if ($marketId) {
            $sql .= " WHERE marketId = '" . $marketId . "'";
        }

        $product_mkt = $this->db->query($sql)->row;

        if ($product_mkt) {
            $produto = $this->marketplace->getProduto($product_mkt['tipo_integracao'], $product_mkt['marketId']);
            $this->db->query("UPDATE oc_marketplace_product SET"
                . "  `status`      = '" . $this->db->escape($produto->getmktStatus()) . "',"
                . "  substatus     = '',"
                . "  url           = '" . $this->db->escape($produto->getmktLink()) . "',"
                . "  tipo_produto  = '" . $this->db->escape($tipo_key) . "',"
                . "  sold_quantity = '" . $this->db->escape($produto->getmktQtdVendido()) . "'"
                . " WHERE product_key_id = " . $product_mkt['product_key_id'] . " and (tipo_integracao = " . $product_mkt['tipo_integracao'] . ") and (tipo_produto  = " . $product_mkt['tipo_produto'] . ")");

            $productAtt = $this->db->countAffected() > 0 ? true : false;

            if ($product_mkt['tipo_integracao'] == Type_MarketPlace::Tp_Mercadolivre && $productAtt) {
                // catalogo, caso o ML colocou automaticamente o item no catalogo, a verificação fica dentro da função
                $this->dmodel_mercadolivre_meliproduto->insertMercadolivreAdCatalogForced($produto, $product_mkt);
            }
        }

    }

    public function isListedOnMarketplace($product_key_id, $product_type = Type_ProdutoMkt::Tp_MktProd_Normal)
    {
        $sql = "select * from oc_marketplace_product where product_key_id = $product_key_id and tipo_produto = $product_type";

        $retorno = $this->db->query($sql)->rows;
        return $retorno->RowsCount > 0;
    }


    public function getMarketplacesProducts($product_key_id, $product_type, $marketplace)
    {
        $sql = "select * from oc_marketplace_product
                where product_key_id  = $product_key_id
                      and tipo_produto    = $product_type
                      and tipo_integracao = $marketplace";

        $mkt_regs = $this->db->query($sql);

        return $mkt_regs->num_rows ? $mkt_regs->row : false;
    }

    public function getMarketplacesUniqueProductsFromGrid($product_grid_id, $marketplace)
    {
        $sql = "select * from oc_marketplace_product
            where product_key_id in (SELECT pgd.product_id
                                     FROM oc_product_grid_detail pgd
                                     WHERE pgd.product_grid_id = $product_grid_id)
            and tipo_produto    = " . Type_ProdutoMkt::Tp_MktProd_Normal
            . " and tipo_integracao = $marketplace";

        $mkt_regs = $this->db->query($sql);

        return $mkt_regs->num_rows ? $mkt_regs->rows : false;
    }

    public function getMarketPlaceFromMarketId($marketId, $marketplace)
    {
        $sql = "select * from oc_marketplace_product
                where MarketId  = '$marketId'
                      and tipo_integracao = $marketplace";

        $mkt_regs = $this->db->query($sql);

        return $mkt_regs->num_rows ? $mkt_regs->row : false;
    }

    public function getProductFromVariation($mktVariation, $marketplace)
    {
        $sql = "select * from oc_marketplace_product_variation
                where mkt_variation_id  = '$mktVariation'
                      and tipo_integracao = $marketplace";

        $mkt_regs = $this->db->query($sql);

        return $mkt_regs->num_rows ? $mkt_regs->row : false;
    }

    public function getVariationFromProduct($productId, $marketplace)
    {
      $sql = "select * from oc_marketplace_product_variation
              where product_id  = '$productId'
              and tipo_integracao = $marketplace";

      $mkt_regs = $this->db->query($sql);

      return $mkt_regs->num_rows ? $mkt_regs->row : false;
    }

    public function setProductToGrid($product_id, $product_grid_id)
    {

        if (empty($product_id)) {
            return false;
        }

        if (empty($product_grid_id)) {
            return false;
        }

        $this->load->type('tipomarketplace');


        $dataSql = array(
            "UPDATE oc_marketplace_product SET product_key_id = ?, tipo_produto = ? WHERE product_key_id = ? AND tipo_produto = ? AND tipo_integracao = " . Type_MarketPlace::Tp_Mercadolivre,
            "UPDATE oc_mercadolivre_prod_attr SET product_key_id = ?, tipo_produto = ? WHERE product_key_id = ? AND tipo_produto = ?",
            "UPDATE oc_mercadolivre_infos SET product_key_id = ?, tipo_produto = ? WHERE product_key_id = ? AND tipo_produto = ?"
        );

        foreach ($dataSql as $key => $sql) {
            $this->db->executeSql($sql, [$product_grid_id, Type_ProdutoMkt::Tp_MktProd_Grade, $product_id, Type_ProdutoMkt::Tp_MktProd_Normal]);
        }


    }

    private function setGpGridData($produtoClass, $variation, &$data)
    {
        $data['gp_department_id'] = $produtoClass->getParam('gp_department_id');
        $data['gp_category_id'] = $produtoClass->getParam('gp_category_id');
        $data['gp_subcategory_id'] = $produtoClass->getParam('gp_subcategory_id');
        $data['variation_data'] = $variation;
    }

    public function pauseProduct($product_id, $type_product, $type_marketplace, $status)
    {
        $produtoClass = $this->getProdutoClasses($product_id, $type_product, $type_marketplace);

        $this->setProductMarketPlaceStatus($product_id, $type_product, $type_marketplace, $status);

        return $this->marketplace->pauseProduct($type_marketplace, $produtoClass->getMktId());
    }

}