<?php
$loader = $this->registry->get('load');
$loader->dmodel('marketplace/mktpedido');

final class DModelgaleriapagegppedido extends DModelmarketplacemktpedido
{

    public function proccessOrder($tempoLimite = false){
        $this->load->dmodel('marketplace/mktpedido');
        $gpUtils = new GaleriaPageUtils($this->registry);

        $retorno = array("fail_order" => 0);

        $data = array('statusId' => TypeGaleriaPageOrder_Status::Tp_aprovado);
        $orders = $this->marketplace->getOrders(Type_MarketPlace::Tp_Galeriapage, $data);

        if (($orders instanceOf StdClass) && ($orders->sucess)) {
            foreach ($orders->data as $key => $value) {
                try {
                    $this->db->startTransaction();

                    $jsonOrder = $gpUtils->orderJsonToObject($value);

                    $order_info = $this->getMktOrder($value->code, Type_MarketPlace::Tp_Galeriapage);

                    if ($order_info){
                        $this->updateOrderGaleriaPage($order_info['order_id'], $jsonOrder->getParam('status'), null);
                    } else {
                        $this->addOrderGaleriaPage($jsonOrder);
                    }


                    $this->db->commit();
                } catch (Exception $e) {
                    $this->db->rollback();
                    $retorno['fail_order']++;
                }

                if (($tempoLimite) && (new DateTime($this->db->dataAtual()) > $tempoLimite)){
                    break;
                }
            }
        }
        return $retorno;
    }

    public function addOrderGaleriaPage($pedido, $data = array()){
        $status = $data['status'] ?? $pedido->getParam('status');
        $this->db->startTransaction();
        try{
            $this->load->dmodel('marketplace/mktproduto');
            $this->load->dmodel('marketplace/mktprodutogaleriapage');
            $this->load->dmodel('catalog/product');
            $this->load->dmodel('checkout/order');
            $adjustmentKit  = false;

            $order_id = $this->addOrder($pedido, 0, TypeGaleriaPage_Module::Tp_Payment, TypeGaleriaPage_Module::Tp_Shipping, array(), array(), true);
            foreach ($pedido->getItens() as $product) {
                $oc_mktproduct = $this->dmodel_marketplace_mktproduto->getMarketPlaceFromMarketId($product->getMktId(), Type_MarketPlace::Tp_Galeriapage);

                $product_id    = 0;
                $variation_id  = '';
                $productDB     = null;

                $productDB     = $this->dmodel_marketplace_mktprodutogaleriapage->getProduct($oc_mktproduct['product_key_id']);
                if ($productDB) {
                    $product_id  = $productDB['product_id'];
                }

                if((is_null($productDB)) && ($product_id != 0)){
                    $productDB     = $this->dmodel_marketplace_mktprodutogaleriapage->getProduct($product_id);
                }


                $brinde = $this->getMktBrinde($product_id);
                if ($brinde){
                  if ($productDB['product_kit_id']){
                      $brinde['product_kit_id']  = $productDB['product_kit_id'];
                      $brinde['product_kit_qtd'] = $product->getQuantity();
                  }
                  $dadosProd[] = $brinde;
                  $product->setPrice($product->getPrice()-0.01);
                }

                if(!$productDB){
                    $dadosProd[] = array(
                        'product_id'        => $product_id,
                        'name'              => $product->getProductName(),
                        'model'             => '',
                        'quantity'          => $product->getQuantity(),
                        'price'             => $product->getPrice(),
                        'total'             => $product->getQuantity() * $product->getPrice(),
                        'marketId'          => $product->getMktId(),
                        'mkt_comission'     => 0,
                        'mkt_variation_id'  => $variation_id
                    );
                }else{
                    if ($productDB['product_kit_id']){
                        $adjustmentKit = true;
                        $itens_kit = $this->dmodel_catalog_product->getProductKitItens($productDB['product_kit_id'],$product->getPrice());

                        foreach ($itens_kit as $item_kit) {
                          $dadosProd[] = array(
                            'product_id'        => $item_kit['product_id'],
                            'name'              => $item_kit['descricao'],
                            'model'             => $item_kit['model'],
                            'quantity'          => $item_kit['quantidade']*$product->getQuantity(),
                            'price'             => $item_kit['price'],
                            'total'             => ($item_kit['price'] * $item_kit['quantidade']) * $product->getQuantity(),
                            'marketId'          => "",
                            'mkt_comission'     => 0,
                            'mkt_variation_id'  => "",
                            'product_kit_id'    => $productDB['product_kit_id'],
                            'product_kit_qtd'   => $product->getQuantity(),
                            'id_futura'         => $item_kit['product_id_futura'],
                            'discount'          => ($item_kit['acerto'])<0 ? ($item_kit['acerto'] *-1)*$product->getQuantity() : 0,
                            'increase'          => ($item_kit['acerto'])>0 ? $item_kit['acerto']*$product->getQuantity() : 0
                          );
                        }
                    }else{
                        $dadosProd[] = array(
                            'product_id'        => $product_id,
                            'name'              => $productDB['name'],
                            'model'             => $productDB['model'],
                            'quantity'          => $product->getQuantity(),
                            'price'             => $product->getPrice(),
                            'total'             => $product->getQuantity() * $product->getPrice(),
                            'marketId'          => $product->getMktId(),
                            'mkt_comission'     => 0,
                            'mkt_variation_id'  => $variation_id
                        );
                    }
                }



            }

            foreach ($dadosProd as $prod){
                if (isset($prod['product_kit_id']) && !isset($prod['brinde_product_id']) ){
                    $extraFields = array("product_kit_id","product_kit_qtd","desconto_valor","acrescimo_valor");
                    $extraValues = array($prod["product_kit_id"],$prod["product_kit_qtd"],$prod["discount"],$prod["increase"]);
                    $this->addOrderProduct($order_id, $prod,$extraFields,$extraValues);
                }elseif (isset($prod['brinde_product_id'])){
                    $extraFields = array("brinde_product_id","brinde_tipo");
                    $extraValues = array($prod["brinde_product_id"],$prod["brinde_tipo"]);
                    if(isset($prod['product_kit_id'])){
                        $extraFields = array_merge($extraFields,["product_kit_id","product_kit_qtd"]);
                        $extraValues = array_merge($extraValues,[$prod["product_kit_id"],$prod["product_kit_qtd"]]);
                    }
                    $this->addOrderProduct($order_id, $prod,$extraFields,$extraValues);
                }else{
                    $this->addOrderProduct($order_id, $prod);
                }
            }

            $this->addMktOrder(array(
                'order_id'         => (int)$order_id,
                'mktOrderId'       => $pedido->getMktId(),
                'order_product_id' => null,
                'tipo_integracao'  => Type_MarketPlace::Tp_Galeriapage
            ));

            $total_data = array();

            if ($adjustmentKit){
                //Ajuste dos descontos e totais dos produtos caso possua KIT
                $this->language->load('total/descontoacrescimokit');
                $fullSubTotal = array_sum(array_column($dadosProd,'total'));
                $adjustmentKitValue = $pedido->getSubTotal()-$fullSubTotal;
                $pedido->setSubTotal($fullSubTotal);
                if($adjustmentKitValue >= 0){
                  $text_kit = $this->language->get('acrescimo_kit');
                  $pedido->setAcresKit($adjustmentKitValue);
                }else{
                  $text_kit = $this->language->get('desconto_kit');
                  $pedido->setDiscountKit($adjustmentKitValue*-1);
                }

                $text_kit = ($adjustmentKitValue > 0) ? $this->language->get('acrescimo_kit') : $this->language->get('desconto_kit');
                $total_data[] = array(
                  'code'        => 'descontoacrescimokit',
                  'title'       => $text_kit,
                  'text'        => $this->currency->format($adjustmentKitValue, $this->currency->getCode()),
                  'value'       => (float)$adjustmentKitValue,
                  'sort_order'  => $this->config->get('sub_total_sort_order')+1//Exibir o desconto do Kit logo em seguida do subtotal
                );
            }

            $this->language->load('total/sub_total');
            $total_data[] = array(
                'code'        => 'sub_total',
                'title'       => $this->language->get('heading_title'),
                'text'        => $this->currency->format($pedido->getSubTotal(), $this->currency->getCode()),
                'value'       => (float)$pedido->getSubTotal(),
                'sort_order'  => $this->config->get('sub_total_sort_order')
            );

            $shipping_cost = $pedido->getShippingCost();

            $method_title = $pedido->getShippingName();

            if ($shipping_cost <= 0) {
                $method_title .= ' (Envio Grátis)';
            }

            $total_data[] = array(
                'code'        => 'shipping',
                'title'       => $method_title,
                'text'        => $this->currency->format((float)$shipping_cost, $this->currency->getCode()),
                'value'       => (float)$shipping_cost,
                'sort_order'  => $this->config->get('shipping_sort_order')
            );

            $this->language->load('total/total');
            $total_data[] = array(
                'code'        => 'total',
                'title'       => $this->language->get('heading_title'),
                'text'        => $this->currency->format((float)$pedido->getTotal(), $this->currency->getCode()),
                'value'       => (float)$pedido->getTotal(),
                'sort_order'  => $this->config->get('total_sort_order')
            );

            $orderModule = 0;
            if($pedido->getDiscount() > 0){
                $total_data[] = array(
                    'code'       => 'descontogaleriapage',
                    'title'      => 'Descontos' ,
                    'text'       => $this->currency->format($pedido->getDiscount()*-1),
                    'value'      => $pedido->getDiscount() *-1,
                    'sort_order' => $this->config->get('sub_total_sort_order')+1
                );
                $orderModule = $this->config->get('sub_total_sort_order') + 1;
            }

            if($pedido->getAcres() > 0){
                $total_data[] = array(
                    'code'       => 'acrescimogaleriapage',
                    'title'      => 'Acrescimos' ,
                    'text'       => $this->currency->format($pedido->getAcres()),
                    'value'      => $pedido->getAcres(),
                    'sort_order' => $orderModule + 1
                );
            }

            $this->dmodel_checkout_order->updateApportionmentAll($order_id,
                array(
                    Type_Apportionment::Shipping => $shipping_cost,
                    Type_Apportionment::Discount => $pedido->getDiscount(),
                    Type_Apportionment::Increase => $pedido->getAcres()
                )
            );

            $this->addOrderTotal($order_id, $total_data);

            $commentHistory = 'Galeria Pagé (Venda #' . $pedido->getMktId() . ')';
            $order_status_id = $this->getGpStatus($status);

            $order_history_id = $this->updateOrderHistory($order_id, $order_status_id, $commentHistory);

            $historyData = array('order_id' => $order_id, 'order_history_id' => $order_history_id,
              'tipo_origem' => TypeGaleriaPage_Origem::Tp_Recebimento, 'tipo_situacao' => TypeGaleriaPage_Situacao::Tp_SituacaoRecebido);
            $this->addMktOrderStatus($historyData);

            $order_status_id = $this->getGpStatus(TypeGaleriaPageOrder_Status::Tp_processando);
            $order_history_id = $this->updateOrderHistory($order_id, $order_status_id, '');

            $this->sendStatus($order_id, $order_status_id, $order_history_id);

            $this->saveMarketplaceLog();

            $this->db->commit();

            return $order_id;

        }catch(Exception $e){
            $this->db->rollback();
            throw new Exception($e->getMessage());
        }
    }

    public function updateOrderGaleriaPage($order_id, $mktStatus, $mktStatusType){
        $this->db->startTransaction();
        try{
            $status_id = $this->getGpStatus($mktStatus);
            $order_history_id = $this->updateOrderHistory($order_id, $status_id, '');

            //Atualizar no tipo também...
            $this->updateTipoStatusPedido($order_id, $mktStatus);

            $dataStatus = array(
                "order_id" => $order_id,
                "order_history_id" => $order_history_id,
                "mktStatus" => $mktStatusType,
                "tipo_origem" => TypeGaleriaPage_Origem::Tp_Recebimento,
                "tipo_situacao" => TypeGaleriaPage_Situacao::Tp_SituacaoRecebido,
                "msg_erro" => ''
            );
            $this->addMktOrderStatus($dataStatus);

            $this->saveMarketplaceLog();

            $this->db->commit();
        }catch(Exception $e){
            $this->db->rollback();
            throw new Exception($e->getMessage());
        }
    }

    public function getGpStatus($order_status){
        switch ($order_status){
            case TypeGaleriaPageOrder_Status::Tp_aguardando_pagamento:
                return $this->config->get('gp_order_status_waiting_payment');
                break;
            case TypeGaleriaPageOrder_Status::Tp_aprovado:
                return $this->config->get('gp_order_status_approved');
                break;
            case TypeGaleriaPageOrder_Status::Tp_processando:
                return $this->config->get('gp_order_status_processing');
                break;

            case TypeGaleriaPageOrder_Status::Tp_faturado:
                return $this->config->get('gp_order_status_invoiced');
                break;
            case TypeGaleriaPageOrder_Status::Tp_enviado:
                return $this->config->get('gp_order_status_send');
                break;
            case TypeGaleriaPageOrder_Status::Tp_entregue:
                return $this->config->get('gp_order_status_delivered');
                break;
            case TypeGaleriaPageOrder_Status::Tp_cancelado:
                return $this->config->get('gp_order_status_canceled');
                break;
        }
    }

    public function sendStatus($order_id, $order_status_id,$order_history_id,$reenvio=false){
        $this->load->dmodel('galeriapage/gpsetting');
        $this->load->dmodel('checkout/order');
        $this->load->dmodel('notafiscal/notafiscal');
        $this->load->dmodel('wsceo/pedido/wsnotafiscal');
        $gpUtils = new GaleriaPageUtils($this->registry);


        $key = $this->dmodel_galeriapage_gpsetting->getKeyFromOrderStatus($order_status_id);

        if(!$key){
            return true;//Se não tiver configuração para esse status na page, então sai fora, não tem nada a ser feito...
        }

        $key         = substr($key['key'], 16, strlen($key['key'])+16);
        $order       = $this->dmodel_checkout_order->getOrder($order_id);

        switch ($key) {

            case 'processing':
                $retorno = $gpUtils->updateOrderStatus($order['mktOrderId'], TypeGaleriaPageOrder_ApiStatus::Tp_processing);
                $status_type = TypeGaleriaPageOrder_Status::Tp_processando;
                break;

            case 'invoiced':
                if ($order['numero_nfe'] == null || trim($order['numero_nfe']) ==''){
                    return false;
                }

                $retorno = $this->setEnvioNFE($order_id, $order['mktOrderId'], $order['chave_acesso'], $order['quantidade_volumes'], $order['numero_nfe']);

                $status_type = TypeGaleriaPageOrder_Status::Tp_faturado;
                break;

            case 'send':
                $retorno = $this->setOrderShipped($order_id, $order['mktOrderId'], $order);
                $status_type = TypeGaleriaPageOrder_Status::Tp_enviado;
                break;

            case 'delivered':
                $retorno = $gpUtils->updateOrderStatus($order['mktOrderId'], TypeGaleriaPageOrder_ApiStatus::Tp_delivered);
                $status_type = TypeGaleriaPageOrder_Status::Tp_entregue;
                break;

            default : return true; //Para não tentar enviar status que são apenas recebidos ou status que não são da page
        }

        if(!$retorno->sucess){
            $mensagemErro = $retorno->message ?? 'Erro desconhecido';
            $tipoSituacao = TypeGaleriaPage_Situacao::Tp_SituacaoErro;
        }else{
            $tipoSituacao = TypeGaleriaPage_Situacao::Tp_SituacaoNotificado;
            $mensagemErro = '';
        }

        $dataStatus = array(
            "order_id" => $order_id,
            "order_history_id" => $order_history_id,
            "mktStatus" => $status_type,
            "tipo_origem" => TypeGaleriaPage_Origem::Tp_Envio,
            "tipo_situacao" => $tipoSituacao,
            "msg_erro" => $mensagemErro
        );

        if($reenvio){
            $this->updateMktOrderStatus($dataStatus);
        }else if(!$this->dmodel_marketplace_mktpedido->isVinculedMktOrderStatus($order_history_id)){
            $this->addMktOrderStatus($dataStatus);
        }

        return true;
    }

    public function setEnvioNFE($order_id, $mktOrderId, $chave_acesso, $qtd_volumes, $numeroNFe){
        $this->load->type('tipocomum');
        $retorno = $this->marketplace->setEnviarNFE(Type_MarketPlace::Tp_Galeriapage, $mktOrderId, $chave_acesso, $qtd_volumes, $numeroNFe);

        if ($retorno->sucess){
            $sql = ' update oc_order_nfe set gp_nf_enviado = ' . Type_Enviado::Tp_Enviado
                . ' where order_id = ?';
            $this->db->executeSql($sql, [$order_id]);
        }
        return $retorno;
    }

    private function setOrderShipped($order_id, $mktOrderId, $order){
        $trakings = '';
        if ($order['tracking_code']){
            foreach($order['tracking_code'] as $traking_code){
                $trakings .= $traking_code['tracking_code'].',';
            }
            $trakings = rtrim($trakings,',');
        }

        $dataSend = array('tracking_code' => $trakings);

        return $this->marketplace->setPedidoEnvio(Type_MarketPlace::Tp_Galeriapage, $mktOrderId, $dataSend);
    }

}
