<?php

use system\entity\filter\baseFilter;

class ControllerMercadolivreMercadolivre extends Controller
{

    public function index()
    {

        $this->language->load('module/mercadolivre');
        $this->data['breadcrumbs'] = array();

        $this->data['breadcrumbs'][] = array(
            'text' => $this->language->get('text_home'),
            'href' => $this->url->link('common/home'),
            'separator' => false
        );

        $this->data['breadcrumbs'][] = array(
            'text' => $this->language->get('text_title'),
            'href' => $this->url->link('mercadolivre/mercadolivre'),
            'separator' => $this->language->get('text_separator')
        );

        $this->breadcrumbs->setbreadcumbs($this->data['breadcrumbs']);

        $this->document->setTitle($this->language->get('text_title'));

        $this->data['heading_title'] = $this->language->get('text_title');
        $this->data['text_intro'] = $this->language->get('text_intro');
        $this->data['text_auth'] = $this->language->get('text_auth');
        $this->data['text_auth_done'] = $this->language->get('text_auth_done');
        $this->data['button_continue'] = $this->language->get('button_continue');
        $this->data['continue'] = $this->url->link('common/home');

        $this->data['error'] = '';
        if (isset($this->request->get['error'])) {
            $this->data['error'] = 'Error: ' . $this->request->get['error'] . (($this->request->get['error_description']) ? ' - ' . $this->request->get['error_description'] : '');
        }

        if (isset($this->request->get['code'])) {
            $this->data['error'] = $this->mercadolivre->getAccessToken($this->request->get['code']);
        }

        $this->data['auth_done'] = '';
        if ($this->mercadolivre->getAccess()) {
            $this->data['auth_done'] = '1';
            $this->data['text_auth'] = $this->language->get('text_reauth');
        }

        $this->data['login_url'] = $this->mercadolivre->getLoginUrl();


        if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/mercadolivre/auth.tpl')) {
            $this->template = $this->config->get('config_template') . '/template/mercadolivre/auth.tpl';
        } else {
            $this->template = 'default/template/mercadolivre/auth.tpl';
        }

        $this->children = array(
            'common/breadcrumbs',
            'common/column_left',
            'common/column_right',
            'common/content_top',
            'common/content_bottom',
            'common/footer',
            'common/header'
        );

        $this->response->setOutput($this->render());

    }

    public function syncat()
    {

        $json = array();

        try {
            $this->mercadolivre->updateCategory();
            $this->mercadolivre->updateListingType();
            $json['success'] = 'Categorias atualizadas com sucesso!';
        } catch (Exception $e) {
            $json['error'] = 'Erro ao atualizar as categorias, tente novamente mais tarde ou entre em contato com o suporte técnico!';
        }

        $this->response->setOutputJson($json);

    }

    public function testUser()
    {
        $this->mercadolivre->createTestUser();
    }


    public function callback()
    {
        if ($this->config->get('mercadolivre_status')) {

            $data = file_get_contents('php://input');
            $data = json_decode($data, true);

            if (!is_null($data)) {

                $this->load->dmodel('mercadolivre/melipedido');
                $this->load->dmodel('marketplace/marketplace');
                switch ($data['topic']) {
                    case Type_CallbackTopic::getNickFromConstValue(Type_CallbackTopic::Tp_Items) :
                        $callId = trim(str_replace('/items/', '', $data['resource']));
                        $this->dmodel_marketplace_marketplace->addAPICall(Type_MarketPlace::Tp_Mercadolivre, $callId, $data['topic']);
                        break;
                    case Type_CallbackTopic::getNickFromConstValue(Type_CallbackTopic::Tp_Orders) :
                    case Type_CallbackTopic::getNickFromConstValue(Type_CallbackTopic::Tp_OrdersV2) :
                        $callId = trim(str_replace('/orders/', '', $data['resource']));
                        $this->dmodel_marketplace_marketplace->addAPICall(Type_MarketPlace::Tp_Mercadolivre, $callId, 'order');
                        break;
                    case Type_CallbackTopic::getNickFromConstValue(Type_CallbackTopic::Tp_Shipments) :
                        $callId = trim(str_replace('/shipments/', '', $data['resource']));
                        $this->dmodel_marketplace_marketplace->addAPICall(Type_MarketPlace::Tp_Mercadolivre, $callId, $data['topic']);
                        break;
                    case Type_CallbackTopic::getNickFromConstValue(Type_CallbackTopic::Tp_Questions) :
                        $callId = trim(str_replace('/questions/', '', $data['resource']));
                        $this->dmodel_marketplace_marketplace->addAPICall(Type_MarketPlace::Tp_Mercadolivre, $callId, $data['topic']);
                        break;
                }

                //Isso pode travar todo o sistema.... comentado por questões de segurança....
                //if ($this->config->get('mercadolivre_debug')) {
                //    $this->logml = new Log('errorMercadoLivre.txt');
                //    $this->logml->write('MERCADOLIVRE callback - Type =' . $data['topic'] . ' Response=' . print_r($data, true));
                //}

                ob_start();
                header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");

            }


        } else {
            ob_start();
            header($_SERVER["SERVER_PROTOCOL"] . "404 Not Found");
        }

        ob_end_flush();
        if (headers_sent()) {
            echo "Header Sent to ML";
        } else {
            echo "Header Not Sent  to ML";
        }

        exit;

    }


    public function stockupdate()
    {

        $this->load->dmodel('setting/task');


        if ($this->config->get('mercadolivre_status') && (isset($this->request->get['update']))) {

            $this->load->dmodel('mercadolivre/meliproduto');
            $this->load->dmodel('marketplace/mktprodutomercadolivre');
            $this->load->dmodel('marketplace/mktprice');
            $this->load->dmodel('marketplace/mktproduto');
            $this->load->type('tipocomum');

            ini_set('memory_limit', '32M');       

            if (isset($this->request->get['update'])) {
                switch ($this->request->get['update']) {
                    case 'estoque':
                        $this->ftrgeralregistry->permissaoAcessoUrl($this->dmodel_setting_task->getTaskByType(Type_TaskUrl::Tp_TaskMLEstoque));
                        $result = $this->dmodel_setting_task->getTaskByType(['type' => Type_TaskUrl::Tp_TaskMLEstoque]);
                        $resultPrice = $this->dmodel_marketplace_mktprice->getStandardMktPrice(Type_MarketPlace::Tp_Mercadolivre);

                        $dataTask = array(
                            'date_last_acting' => $this->db->dataAtual(),
                            'type' => Type_TaskUrl::Tp_TaskMLEstoque
                        );
                        $this->dmodel_setting_task->editDateTaskByType($dataTask);

                        $minutos = Type_ExecTimeTask::Tp_ExecTime_5min / 60;
                        $tempoLimite = (new DateTime($this->db->dataAtual()))->add(new DateInterval('PT' . $minutos . 'M'));

                        $data = array(
                            'date_estoque' => (isset($this->request->get['update']) && ($this->request->get['update'] == 'estoque')) ? true : false
                        );
                        $results = $this->dmodel_marketplace_mktprodutomercadolivre->getMktProdutos($data);
                        
                        if (count($results) > 0) {
                            $mlproducts = array_chunk($results, 10);
                            foreach ($mlproducts as $key => $values) {
                              
                                $productReturnList = array();
                                $productType = array();
                                $dataAtt = $this->db->dataAtual();//sempre pegar a data aqui pra não correr o risco de perder informação...

                                foreach ($values as $key => $value) {       
                                    try {
                                        $productReturn = $this->dmodel_marketplace_mktproduto->synchronizeProductEstoque($value['product_key_id'], $value['marketId'], Type_MarketPlace::Tp_Mercadolivre, $value['tipo_produto'], false, true);                  
                                        if ($productReturn) {
                                            $productReturnList[$value['product_key_id']][Type_MarketPlace::Tp_Mercadolivre] = $productReturn;
                                            $productType[$value['product_key_id']][Type_MarketPlace::Tp_Mercadolivre] = $value['tipo_produto'];
                                        }
                                    } catch (ExceptionErrorShow $e) {
                                        //erros de exibição não é para serem salvos na tabela de oc_marketplace_product
                                    } catch (Exception $e) {
                                        $this->mercadolivre->raiseGlobalErrors();
                                        //$this->dmodel_marketplace_mktproduto->UpdateProductMarketPlace($value['product_key_id'], null, Type_MarketPlace::Tp_Mercadolivre, $value['tipo_produto']);
                                        $this->dmodel_marketplace_mktproduto->setError($e->getMessage(), $value['product_key_id'], Type_MarketPlace::Tp_Mercadolivre, $value['tipo_produto']);
                                    }
                                }

                                foreach ($productReturnList as $product_id => $return) {
                                    $dataUpdate = [
                                        'marketplace_price_id' => (int)$return[Type_MarketPlace::Tp_Mercadolivre]->getMarketplacePriceId(),
                                        'marketplaceprice_config_md5' => $resultPrice->getMarketplacePriceMd5(),
                                        'date_att_price' => $dataAtt
                                    ];
                                    $this->dmodel_marketplace_mktproduto->saveProductMarketPlaceFromProd($return[Type_MarketPlace::Tp_Mercadolivre], $product_id, $productType[$product_id][Type_MarketPlace::Tp_Mercadolivre], $dataAtt, null, $dataUpdate);
                                }
                               
                                if (new DateTime($this->db->dataAtual()) > $tempoLimite) {
                                    break;
                                }
                            }               
                        }
                        break;
                    case 'produto':
                        $this->ftrgeralregistry->permissaoAcessoUrl($this->dmodel_setting_task->getTaskByType(Type_TaskUrl::Tp_TaskMLProduto));
                        $result = $this->dmodel_setting_task->getTaskByType(['type' => Type_TaskUrl::Tp_TaskMLProduto]);

                        $dataTask = array(
                            'date_last_acting' => $this->db->dataAtual(),
                            'type' => Type_TaskUrl::Tp_TaskMLProduto
                        );
                        $this->dmodel_setting_task->editDateTaskByType($dataTask);

                        $config_md5 = $this->config->get('mercadolivre_configs_md5');
                        $config_md5_mktfield = 'marketplace_config_md5';

                        $minutos = Type_ExecTimeTask::Tp_ExecTime_3min / 60;
                        $tempoLimite = (new DateTime($this->db->dataAtual()))->add(new DateInterval('PT' . $minutos . 'M'));

                        $data = array(
                            'date_produto' => (isset($this->request->get['update']) && ($this->request->get['update'] == 'produto')) ? true : false,
                            'config_md5' => $config_md5,
                            'config_md5_mktfield' => $config_md5_mktfield,
                        );

                        $dataUpdate = array($config_md5_mktfield => $config_md5);

                        $results = $this->dmodel_marketplace_mktprodutomercadolivre->getMktProdutos($data);

                        if (count($results) > 0) {
                            $mlproducts = array_chunk($results, 10);
                            foreach ($mlproducts as $key => $values) {
                                //pego a data sempre aqui, pra n ocorrer de atualizar um produto pela replicacao
                                //no momento em que sincroniza o produto, como salva a data no final, se não fizer
                                //assim, da problema... byMatheus
                                $dataAtt = $this->db->dataAtual();
                                $productReturnList = array();
                                $productType = array();
                                foreach ($values as $key => $value) {
                                    try {
                                        $productReturn = $this->dmodel_marketplace_mktproduto->synchronizeProduct($value['product_key_id'], $value['tipo_produto'], Type_MarketPlace::Tp_Mercadolivre, false, true);
                                        $productReturnList[$value['product_key_id']][Type_MarketPlace::Tp_Mercadolivre] = $productReturn;
                                        $productType[$value['product_key_id']][Type_MarketPlace::Tp_Mercadolivre] = $value['tipo_produto'];
                                    } catch (ExceptionErrorShow $e) {
                                        //erros de exibição não é para serem salvos na tabela de oc_marketplace_product
                                    } catch (Exception $e) {
                                        $this->mercadolivre->raiseGlobalErrors();
                                        $saveInfos[Type_MarketPlace::Tp_Mercadolivre] = $this->marketplace->getProduto(Type_MarketPlace::Tp_Mercadolivre, $value['marketId']);
                                        $this->dmodel_marketplace_mktproduto->UpdateProductMarketPlace($value['product_key_id'], null, Type_MarketPlace::Tp_Mercadolivre, $value['tipo_produto']);
                                        $this->dmodel_marketplace_mktproduto->setError($e->getMessage(), $value['product_key_id'], Type_MarketPlace::Tp_Mercadolivre, $value['tipo_produto']);
                                    }
                                }
                                foreach ($productReturnList as $product_id => $return) {
                                    $dataUpdate = array_merge($dataUpdate, [
                                        'marketplace_price_id' => (int)$return[0]->getMarketplacePriceId(),
                                        'marketplaceprice_config_md5' => $return[0]->getMarketplacepriceConfigMd5()
                                    ]);
                                    $this->dmodel_marketplace_mktproduto->saveProductMarketPlaceFromProd($return[Type_MarketPlace::Tp_Mercadolivre], $product_id, $productType[$product_id][Type_MarketPlace::Tp_Mercadolivre],
                                        null, $dataAtt, $dataUpdate);
                                }

                                if (new DateTime($this->db->dataAtual()) > $tempoLimite) {
                                    break;
                                }
                            }
                        }
                        break;
                }
              
            }
        } else {
            throw new Exception('Configuração de verificação de informações do produto desabilitada!');
        }
    }

    public function infos()
    {

        $this->load->dmodel('setting/task');

        $this->ftrgeralregistry->permissaoAcessoUrl($this->dmodel_setting_task->getTaskByType(Type_TaskUrl::Tp_TaskMLPergunta));

        if ($this->config->get('mercadolivre_status') && (isset($this->request->get['option']))) {

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

            switch ($this->request->get['option']) {
                case 'question':
                    $result = $this->dmodel_setting_task->getTaskByType(Type_TaskUrl::Tp_TaskMLPergunta);

                    $data = array(
                        'date_last_acting' => $this->db->dataAtual(),
                        'type' => Type_TaskUrl::Tp_TaskMLPergunta
                    );
                    $this->dmodel_setting_task->editDateTaskByType($data);

                    $minutos = Type_ExecTimeTask::Tp_ExecTime_1min / 60;
                    $tempoLimite = (new DateTime($this->db->dataAtual()))->add(new DateInterval('PT' . $minutos . 'M'));

                    $this->load->dmodel('mercadolivre/melipergunta');
                    $this->dmodel_mercadolivre_melipergunta->processAPIQuestions($tempoLimite);
                    break;
            }
        }

    }

}
