<?php

class ControllerCheckoutCart extends Controller
{
    private $error = array();
    protected $referencePathFile = 'checkout/cart';
    protected $cartName = 'cart';
    protected $fileName;
    protected $pathName;


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

        $referenceArray = explode('/', $this->referencePathFile);
        $this->fileName = $referenceArray[1];
        $this->pathName = $referenceArray[0];

    }

    public function index($cartList = false)
    {
        if(isset($this->session->data['error_list_observation'])){
            $listIdsWitherrors = $this->session->data['error_list_observation'];
            $this->data['error_list_observation'] = json_encode($listIdsWitherrors, JSON_HEX_APOS);
            unset($this->session->data['error_list_observation']);
        }

        $language = $this->language->load($this->referencePathFile);
        $this->data = array_merge($this->data, $language);
        $this->isAjax = isset($this->request->get['ajax']) && $this->request->get['ajax'];
        $this->load->helper('ftr_geral');
        $this->load->type('tipocomum');
        $this->load->model('catalog/product'); // depois ver as particularidades e a possibilidade de migrar tudo para a dmodel
        $this->load->dmodel('catalog/product');
        $this->load->library('google_tracking_code');

        $google_tracking_code = new GoogleTrackingCode($this->registry);

        $this->data['futuragrade_status'] = $this->config->get('futuragrade_status');
        $this->data['buy_later_status'] = $this->config->get('buy_later_status');

        if ($this->ftrgeralregistry->isApp()) {
            $module = $this->config->get('buy_later_module');
            if ($module) {
                $this->data['buy_later_status'] = array_filter($module, function ($k) {
                    return ($k['position'] == 'content_app' and $k['status']);
                });
            }

        }

        $this->data['continue_button_status'] = $this->config->get('cart_continue_button');
        $this->data['continue'] = $this->url->link('common/home', '', 'NONSSL', 'false');
        if (!isset($this->session->data['vouchers'])) {
            $this->session->data['vouchers'] = array();
        }

        $this->loadScript();

        // Update
        if (!empty($this->request->post['quantity'])) {
            $this->quantity();
        }

        // Remove
        if (isset($this->request->get['remove'])) {
            $this->remove($cartList);
        }

        $this->data['clear_cart'] = $this->url->link($this->referencePathFile, 'clear');
        if (isset($this->request->get['clear'])) {
            $this->{$this->cartName}->clear();
            $this->redirect($this->url->link($this->referencePathFile));
        }

        $this->extraActions();

        $this->document->setTitle($this->language->get('heading_title'));
        $this->document->addScript('catalog/view/javascript/jquery/colorbox/jquery.colorbox-min.js');
        $this->document->addStyle('catalog/view/javascript/jquery/colorbox/colorbox.css');

        $this->breadcrumbs();

        if ($this->{$this->cartName}->hasProducts() || !empty($this->session->data['vouchers'])) {
            $this->rewards();

            $this->data['heading_title'] = $this->language->get('heading_title');

            $text_separator_grade = (ftr_geral::isIsset($this->config->get('futuragrade_abrev_title_specification')) && $this->config->get('futuragrade_abrev_title_specification') != "") ? ucwords(strtolower($this->config->get('futuragrade_abrev_title_specification'))) : $this->language->get('text_specification_description');
            $this->data['text_specification_description'] = sprintf($this->language->get('text_separator_grade'), $text_separator_grade);

            $this->data['column_image'] = $this->language->get('column_image');
            $this->data['column_name'] = $this->language->get('column_name');
            $this->data['column_model'] = $this->language->get('column_model');
            $this->data['column_quantity'] = $this->language->get('column_quantity');
            $this->data['column_price'] = $this->language->get('column_price');
            $this->data['column_total'] = $this->language->get('column_total');

            $this->data['entry_coupon'] = $this->language->get('entry_coupon');
            $this->data['entry_voucher'] = $this->language->get('entry_voucher');
            $this->data['entry_country'] = $this->language->get('entry_country');
            $this->data['entry_zone'] = $this->language->get('entry_zone');
            $this->data['entry_postcode'] = $this->language->get('entry_postcode');
            $this->data['text_nao_sei_meu_cep'] = $this->language->get('text_nao_sei_meu_cep');

            $this->data['button_update'] = $this->language->get('button_update');
            $this->data['button_remove'] = $this->language->get('button_remove');
            $this->data['button_buy_later'] = $this->language->get('button_buy_later');
            $this->data['button_coupon'] = $this->language->get('button_coupon');
            $this->data['button_voucher'] = $this->language->get('button_voucher');
            $this->data['button_reward'] = $this->language->get('button_reward');
            $this->data['button_quote'] = $this->language->get('button_quote');
            $this->data['button_shipping'] = $this->language->get('button_shipping');
            $this->data['button_shopping'] = $this->language->get('button_shopping');
            $this->data['button_checkout'] = $this->language->get('button_checkout');

            $this->data['text_trial'] = $this->language->get('text_trial');
            $this->data['text_recurring'] = $this->language->get('text_recurring');
            $this->data['text_length'] = $this->language->get('text_length');
            $this->data['text_recurring_item'] = $this->language->get('text_recurring_item');
            $this->data['text_payment_profile'] = $this->language->get('text_payment_profile');

            $this->messages();

            $this->data['action'] = $this->url->link($this->referencePathFile);
            
            $this->data['google_analytics'] = json_encode($google_tracking_code->getGATrackingCodes());

            if ($this->config->get('config_cart_weight')) {
                $this->data['weight'] = $this->weight->format($this->{$this->cartName}->getWeight(), $this->config->get('select_peso'), $this->language->get('decimal_point'), $this->language->get('thousand_point'));
            } else {
                $this->data['weight'] = '';
            }

            $this->load->model('localisation/zone');
            $this->data['zones_id'] = $this->model_localisation_zone->getZonesByCountryId(Type_PaisId::Tp_Brasil);

            $this->load->dmodel('tool/image');

            $this->data['cartlist'] = array();

            $products = $this->{$this->cartName}->getProducts();

            $wishlist_data = array();
            $total = 0;

            foreach ($products as $key => $product) {
                $data[] = array(
                    'item_id' => $product['product_id'],
                    'item_name' => $product['name'],
                    'quantity' => $product['quantity'],
                    'price' => $product['price']
                );  

                $total += $product['price'];

                $wishlist_data['items'] = $data;
            }

            $wishlist_data['currency'] = "BRL";
            $wishlist_data['value'] = $total;

            $this->data['wishlist_data'] = json_encode($wishlist_data, JSON_HEX_APOS);
        
            if (isset($this->request->post['shipping_method'])) {
                $this->data['shipping_method'] = $this->request->post['shipping_method'];
            } elseif (isset($this->session->data['shipping_method'])) {
                $this->data['shipping_method'] = str_replace("'", "", $this->session->data['shipping_method']['code']);
            } else {
                $this->data['shipping_method'] = '';
            }

            $this->data['listaescolar_cart_obs'] = $this->config->get('listaescolar_cart_obs');
            $this->data['listaescolar_cart_obs_title'] = (!empty($this->config->get('listaescolar_cart_obs_title'))
                ? $this->config->get('listaescolar_cart_obs_title')
                : $this->language->get('text_default_list_cart_obs'));

            foreach ($products as $product) {
                if ($product['image']) {
                    $watermark_config_date_number = $this->dmodel_tool_image->getWatermarkCacheNumber();
                    $image_version_number = '?version=' . preg_replace("/[^0-9]/", "", $product['data_atualizacao_replicacao']) . $watermark_config_date_number;

                    $image = $this->dmodel_tool_image->resizeWithWatermark($product['image'], Type_MiniatureMedium::Tp_width, Type_MiniatureMedium::Tp_height) . $image_version_number;
                } else {
                    $image = $this->dmodel_tool_image->resize('data/sem-imagem.png', Type_MiniatureMedium::Tp_width, Type_MiniatureMedium::Tp_height);
                }

                $cartListAdditionalParameters = $this->productExtraActions([
                    'product' => $product,
                    'products' => $products
                ]);

                [
                    'tipoLista' => $tipoLista,
                    'id_lista' => $id_lista,
                    'total' => $total,

                ] = $cartListAdditionalParameters;

                $this->data['cartlist'][$tipoLista][$id_lista]['products'][] = array_merge([
                    'color_description' => ($this->config->get('futuragrade_status')) ? $product['color_description'] : '',
                    'size_description' => ($this->config->get('futuragrade_status')) ? $product['size_description'] : '',
                    'specification_description' => ($this->config->get('futuragrade_status')) ? $product['specification_description'] : '',
                    'color_template_description' => ($this->config->get('futuragrade_status')) ? $product['color_template_description'] : '',
                    'size_template_description' => ($this->config->get('futuragrade_status')) ? $product['size_template_description'] : '',
                    'specification_template_description' => ($this->config->get('futuragrade_status')) ? $product['specification_template_description'] : '',
                    'key' => $product['key'],
                    'product_id' => $product['product_id'],
                    'schoolProduct' => $tipoLista,
                    'thumb' => $image,
                    'name' => $product['name'],
                    'model' => $product['model'],
                    'quantity' => $product['quantity'],
                    'stock' => $product['stock'] ? true : !(!$this->config->get('config_stock_checkout') || $this->config->get('config_stock_warning')),
                    'total' => $total,
                    'total_value' => str_replace(array('R$ ', ',', '.'), array('', '', ''), $total),
                    'remove' => $this->url->link($this->referencePathFile, 'remove=' . $product['key']),
                    'buy_later' => $this->url->link('module/buy_later/add', 'buy_later=' . $product['product_id']),
                    'id_futura' => $product['id_futura'],
                ], $this->getCartListAdditionalInfo($cartListAdditionalParameters));
            }

            ksort($this->data['cartlist']); //ordenando por tipo e deixando a lista de produtos(que não em lista) na primeira posição

            if (!$this->ftrgeralregistry->isApp()) {
                $this->data['cartListRender'] = $this->render('checkout/cart_list');

                if ($cartList) {
                    return $this->response->setOutput($this->data['cartListRender']);
                }
            }

            $this->extraActionsEnd($products, $this->isAjax);

            if ($this->isAjax) {
                $this->response->setOutputJson($this->data);
            } else {
                $this->response->setOutput($this->render($this->referencePathFile));
            }

            return;
        }

        $this->getEmptyCart();
    }

    public function getEmptyCart()
    {

        $this->language->load($this->referencePathFile);

        $this->data['heading_title'] = $this->language->get('heading_title');
        $this->data['text_error'] = $this->language->get('text_empty');
        $this->data['button_continue'] = $this->language->get('button_continue');
        $this->data['continue'] = $this->url->link('common/home', '', 'NONSSL', 'false');

        unset($this->session->data['success']);

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

        $this->children = $this->getChildren();

        if (isset($this->request->get['ajax']) && $this->request->get['ajax']) {
            $this->response->setOutputJson($this->data);
        } else {
            $this->response->setOutput($this->render('error/not_found'));
        }
    }

    public function getChildren($data = null)
    {
        $children = array(
            'common/breadcrumbs',
            'common/column_left',
            'common/column_right',
            'common/content_top',
            'common/content_app',
            'common/content_bottom',
            'common/footer',
            'common/header'
        );
        if ($data !== null) {
            array_push($children, $data);
        }
        return $children;
    }


    protected function validateCoupon()
    {
        $this->load->model('checkout/coupon');

        $coupon_info = $this->model_checkout_coupon->getCoupon($this->request->post['coupon']);

        if (!$coupon_info) {
            $this->error['warning'] = $this->language->get('error_coupon');
        }

        if ($coupon_info) {

            if (($coupon_info['coupon_display'] == Type_DisplayModuleOption::Tp_Aplicativo) && (!$this->ftrgeralregistry->isApp())) {
                $this->error['warning'] = $this->language->get('error_coupon_app');
            }

            if (($coupon_info['coupon_display'] == Type_DisplayModuleOption::Tp_Ecommerce) && ($this->ftrgeralregistry->isApp())) {
                $this->error['warning'] = $this->language->get('error_coupon_store');
            }
        }

        if (!$this->error) {
            return true;
        } else {
            return false;
        }
    }

    protected function validateReward()
    {
        $points = $this->customer->getRewardPoints();

        $points_total = 0;

        foreach ($this->{$this->cartName}->getProducts() as $product) {
            if ($product['points']) {
                $points_total += $product['points'];
            }
        }

        if (empty($this->request->post['reward'])) {
            $this->error['warning'] = $this->language->get('error_reward');
        }

        if ($this->request->post['reward'] > $points) {
            $this->error['warning'] = sprintf($this->language->get('error_points'), $this->request->post['reward']);
        }

        if ($this->request->post['reward'] > $points_total) {
            $this->error['warning'] = sprintf($this->language->get('error_maximum'), $points_total);
        }

        if (!$this->error) {
            return true;
        } else {
            return false;
        }
    }

    protected function validateShipping()
    {
        if (!empty($this->request->post['shipping_method'])) {
            $shipping = explode('.', $this->request->post['shipping_method']);

            if (!isset($shipping[0]) || !isset($shipping[1]) || !isset($this->session->data['shipping_methods'][$shipping[0]]['quote'][$shipping[1]])) {
                $this->error['warning'] = $this->language->get('error_shipping');
            }
        } else {
            $this->error['warning'] = $this->language->get('error_shipping');
        }

        if (!$this->error) {
            return true;
        } else {
            return false;
        }
    }

    public function onReloadCartList()
    {
        return $this->index(true);
    }


    public function add($dataListColor = false)
    {

        $this->language->load($this->referencePathFile);
        $this->load->model('catalog/product');
        $this->load->type('tipocomum');
        $this->load->library('google_tracking_code');

        $google_tracking_code = new GoogleTrackingCode($this->registry);
        $json = array();
        $errorGrade = false;

        if ($dataListColor) {
            $this->request->post['product_id'] = $dataListColor['product_id'];
            $this->request->post['quantity'] = $dataListColor['quantity'];
        }

        if (isset($this->request->post['product_id'])) {
            $product_id = $this->request->post['product_id'];
        } else {
            $product_id = 0;
        }

        $product_info = $this->model_catalog_product->getProduct($product_id);
        if ($product_info) {
            if (isset($this->request->post['quantity'])) {
                $quantity = $this->request->post['quantity'];
                if ($quantity == '' || $quantity <= 0) {
                    $json['error']['quantity'] = 'Atenção: Não é possivél adicionar produtos sem quantidade!';
                }
                if (!$this->config->get('config_stock_checkout') && $quantity != '' && (($this->{$this->cartName}->getItemQuantity($product_id) + $quantity) > $product_info['qty'])) {
                    $json['error']['quantity_indisponivel'] = 'Atenção: Quantidade solicitada indisponível em nosso estoque!';
                }
            } else {
                $quantity = 1;
            }

            if ($this->config->get('config_fator_multiplicador')) {
                $status = (($this->request->post['quantity'] % $product_info['fator_multiplicador']) == 0) ? true : false;
                if (!$status) {
                    $json['error']['fator_multiplicador'] = 'Atenção: Quantidade solicitada não é multiplo de ' . $product_info['fator_multiplicador'] . '!';
                }
            }

            if ($this->config->get('listapresente_status')) {
                if (isset($this->session->data['cartxitem'])) {
                    $json['error']['lista'] = 'Você adicionou produtos de lista de presente em seu carrinho. Finalize seu pedido ou esvazie seu carrinho para prosseguir com essa compra.';
                }
            }

            if (($this->config->get('futuralimitaritem_status') == Type_Status::Tp_Habilitado) && (($this->config->get('tipopessoa') == Type_CadastroPessoa::Tp_Ambos) || ($this->config->get('tipopessoa') == $this->customer->getTipo_pessoa()))) {
                if ($this->config->get('tipolimite') == Type_LimitacaoItems::Tp_Qtdtotalitens) {
                    if (($this->request->post['quantity'] + $this->{$this->cartName}->countProducts()) > ($this->config->get('qtd_maxitemcart'))) {
                        $json['error']['errmaxitemcart'] = sprintf($this->language->get('text_limiteitens'), $this->config->get('qtd_maxitemcart'), $this->url->link('checkout/checkout'));
                    }
                } else {
                    if (($this->{$this->cartName}->countVariedadeProducts($product_id)) > ($this->config->get('qtd_maxitemcart'))) {
                        $json['error']['errmaxitemcart'] = sprintf($this->language->get('text_limiteitens'), $this->config->get('qtd_maxitemcart'), $this->url->link('checkout/checkout'));
                    }
                }
            }

            if ($this->config->get('futuragrade_status')) {
                $gridhave = $this->model_catalog_product->getGridHave($product_id);
                if ($gridhave['grid_id']) {
                    $this->{$this->cartName}->addQtd($gridhave['grid_id'], $quantity);
                }
                if (!isset($this->request->get['size_id'])) {
                    if ($gridhave['have_size']) {
                        $json['error']['grid_size'] = 'Por favor, informe um(a) ' . $gridhave['template_tamanho'] . '!';
                        $errorGrade = true;
                    }
                }
                if (!isset($this->request->get['specification_id'])) {
                    if ($gridhave['have_specification']) {
                        $json['error']['grid_specification'] = 'Por favor, informe um(a) ' . $gridhave['template_especificacao'] . '!';
                        $errorGrade = true;
                    }
                }
            }

            if (!$json) {
                $this->{$this->cartName}->add($product_id, $quantity, $option = array());
                $json['success'] = sprintf(
                    $this->language->get('text_success'),
                    $this->url->link('product/product', 'product_id=' . $product_id),
                    trim($product_info['name']),
                    $this->url->link($this->referencePathFile)
                );

                if ($this->config->get('wg24_home_redir_carrinho') == Type_DsimDnao::Tp_Sim) {
                    $this->session->data['success'] = $json['success'];
                    $json['redirect'] = $this->url->link($this->referencePathFile, '', 'SSL');
                }

                unset($this->session->data['shipping_method']);
                unset($this->session->data['shipping_methods']);
                unset($this->session->data['payment_method']);
                unset($this->session->data['payment_methods']);

                // Totals
                $this->load->model('setting/extension');

                $total_data = array();
                $total = 0;

                // Display prices
                if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) {
                    $sort_order = array();

                    $results = $this->model_setting_extension->getExtensions('total');

                    foreach ($results as $key => $value) {
                        $sort_order[$key] = $this->config->get($value['code'] . '_sort_order');
                    }

                    array_multisort($sort_order, SORT_ASC, $results);

                    foreach ($results as $result) {
                        if ($this->config->get($result['code'] . '_status')) {
                            $this->load->model('total/' . $result['code']);

                            $this->{'model_total_' . $result['code']}->getTotal($total_data, $total);
                        }

                        $sort_order = array();

                        foreach ($total_data as $key => $value) {
                            $sort_order[$key] = $value['sort_order'];
                        }

                        array_multisort($sort_order, SORT_ASC, $total_data);
                    }
                }

                $json['google_analytics'] = json_encode($google_tracking_code->getGATrackingCodes());
                $json['total'] = sprintf($this->language->get('text_items'), $this->{$this->cartName}->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->currency->format($total));
                $json['total_qtd'] = $this->{$this->cartName}->countProducts();
            }

            //caso o produto seja grade e tenha que ser escolhido tamanho/cor/especificação ele redireciona para a página do produto
            if (isset($this->request->post['layout_id']) && ($this->request->post['layout_id'] == Type_IdLayout::Tp_Idcategory) && ($errorGrade)) {
                $json['redirect'] = $this->url->link(
                    'product/product',
                    'product_id=' . $this->request->post['product_id']
                );
            }
        }

        //validação feita para retornar se o produto foi adicionado ou não no carrinho quando faz a compra de varias cores na página do produto.
        if ($dataListColor) {
            return ($json['success']) ? ['success' => true] : ['message' => current($json['error']), 'success' => false];
        }

        $json['product_id'] = $this->request->post['product_id'];
        $json['product_info'] = $product_info;

        $this->response->setOutput(json_encode($json));
    }

    public function quoteShipping()
    {
        $this->load->controller('postcode/postcode');
        $controllerPostcode = new ControllerPostcodePostcode($this->registry);

        $postcodeSearch = $controllerPostcode->search(true);

        $zoneId = false;
        if (isset($postcodeSearch['dados']) && $postcodeSearch['dados']['zone_id'] != '') {
            $zoneId = $postcodeSearch['dados']['zone_id'];
        }

        $this->quote($zoneId);
    }

    public function quote($zone_id = false)
    {

        $zone_id = $zone_id ?? $this->request->post['zone_id'];

        $this->load->type('tipocomum');
        $this->language->load('checkout/cart');

        $json = array();
        if (!isset($this->request->post['freteproduto_id'])) {
            /*As validações abaixo são feitas para itens do carrinho, quando freteproduto_id estiver prrenchido, significa
            que o calculo está sendo chamado pela tela de produto, essas validações não devem ser feitas*/
            if (!$this->{$this->cartName}->hasProducts()) {
                $json['error']['warning'] = $this->language->get('error_product');
            }

            if (!$this->{$this->cartName}->hasShipping()) {
                $json['error']['warning'] = sprintf($this->language->get('error_no_shipping'), $this->url->link('information/contact'));
            }
        }

        if ((utf8_strlen($this->request->post['postcode']) <= 8)) {
            $json['error']['postcode'] = $this->language->get('error_postcode');
        }

        $this->load->model('localisation/country');

        $country_id = Type_PaisId::Tp_Brasil;

        $country_info = $this->model_localisation_country->getCountry($country_id);

        if ($country_info && $country_info['postcode_required'] && (utf8_strlen($this->request->post['postcode']) < 2) || (utf8_strlen($this->request->post['postcode']) > 10)) {
            $json['error']['postcode'] = $this->language->get('error_postcode');
        }

        if (!$json) {

            // Default Shipping Address
            $this->session->data['shipping_country_id'] = $country_id;
            if (isset($zone_id)) {
                $this->session->data['shipping_zone_id'] = $zone_id;
            }
            $this->session->data['shipping_postcode'] = $this->request->post['postcode'];

            if ($country_info) {
                $country = $country_info['name'];
                $iso_code_2 = $country_info['iso_code_2'];
                $iso_code_3 = $country_info['iso_code_3'];
                $address_format = $country_info['address_format'];
            } else {
                $country = '';
                $iso_code_2 = '';
                $iso_code_3 = '';
                $address_format = '';
            }

            $this->load->model('localisation/zone');

            if (isset($zone_id)) {
                $zone_info = $this->model_localisation_zone->getZone($zone_id);

                if ($zone_info) {
                    $zone = $zone_info['name'];
                    $zone_code = $zone_info['code'];
                } else {
                    $zone = '';
                    $zone_code = '';
                }
            } else {
                $zone = '';
                $zone_code = '';
            }

            $address_data = array(
                'firstname' => '',
                'lastname' => '',
                'company' => '',
                'address_1' => '',
                'address_2' => '',
                'postcode' => str_replace('-', '', $this->request->post['postcode']),
                'city' => '',
                'zone_id' => (isset($zone_id)) ? $zone_id : '',
                'zone' => $zone,
                'zone_code' => $zone_code,
                'country_id' => $country_id,
                'country' => $country,
                'iso_code_2' => $iso_code_2,
                'iso_code_3' => $iso_code_3,
                'address_format' => $address_format,
                'layout_id' => (isset($this->request->post['freteproduto_id'])) ? Type_SendPostcode::Tp_Product : Type_SendPostcode::Tp_Cart
            );

            $quote_data = array();

            $this->load->model('setting/extension');
            $results = $this->model_setting_extension->getExtensions('shipping');

            if (isset($this->request->post['freteproduto_id'])) {
                $freteproduto_id = $this->request->post['freteproduto_id'];
                $this->load->model('catalog/product');
                $product_aux = $this->model_catalog_product->getProduct($freteproduto_id);
                if (isset($product_aux['special']) && ($product_aux['special'] > 0)) {
                    $product_aux['price'] = $product_aux['special'];
                }
                //Quando o produto vir sem a quantidade será considerado apenas um item (Tela do produto)...
                $product_aux['quantity'] = isset($this->request->post['qty']) ? $this->request->post['qty'] : 1;
                $product_aux['total'] = $product_aux['price'];

                $product_info[] = $product_aux;
            }

            foreach ($results as $result) {
                if ($this->config->get($result['code'] . '_status')) {
                    $this->load->model('shipping/' . $result['code']);
                    if (isset($freteproduto_id)) {
                        $quote = $this->{'model_shipping_' . $result['code']}->getQuote($address_data, $product_info);
                    } else {
                        $quote = $this->{'model_shipping_' . $result['code']}->getQuote($address_data);
                    }

                    if(!$quote){
                      continue;
                    }

                    if (!isset($quote[0])) {
                        $quote = array($quote);
                    }
                    foreach ($quote as $quotes) {
                        $quote_data[$quotes['code']] = array(
                            'title' => $quotes['title'],
                            'quote' => $quotes['quote'],
                            'cost' => isset($quotes['cost']) ? $quotes['cost'] : 'R$ 0,00',
                            'sort_order' => $quotes['sort_order'],
                            'error' => $quotes['error']
                        );
                    }
                }
            }

            $sort_order = array();

            foreach ($quote_data as $key => $value) {
                if($key == 'pickup'){
                    $sort_order[$key] = -1;
                }else{
                    $sort_order[$key] = $value['sort_order'];
                }
            }

            array_multisort($sort_order, SORT_ASC, $quote_data);

            $this->session->data['shipping_methods'] = $quote_data;

            if ($this->session->data['shipping_methods']) {
                $json['shipping_method'] = $this->session->data['shipping_methods'];
            } else {
                $json['error']['warning'] = sprintf($this->language->get('error_no_shipping'), $this->url->link('information/contact'));
            }
        }

        $this->response->setOutput(json_encode($json));
    }

    public function addListColor()
    {

        $json = array();

        if (!empty($this->request->post['object'])) {
            foreach ($this->request->post['object'] as $key => $object) {
                if ($object['quantity'] > 0) {
                    $add = $this->add($object);
                    if ($add['success']) {
                        $json['success'][$object['product_id']] = true;
                    } else {
                        $json['error'][$object['product_id']] = $add['message'];
                    }
                }
            }
            $json['total_qtd'] = $this->{$this->cartName}->countProducts();
        } else {
            $json['empty'] = 'Adicione quantidade nas variações abaixo para realizar a compra.';
        }


        $this->response->setOutput(json_encode($json));
    }

    public function loadScript()
    {

        $this->document->addScript(
            array(
                'public/js/postcode.js',
                'catalog/view/theme/vista/js/quote-shipping.js',
                'catalog/view/theme/vista/js/checkout-cart.js',
                'catalog/view/theme/vista/public/js/checkout/cart.js',
            )
        );

        if ($this->ftrgeralregistry->isApp()) {
            $this->document->addScriptApp(
                array(
                    'catalog/view/theme/appmobile/public/js/page.cart.js',
                    'catalog/view/theme/appmobile/public/js/jquery.mask.js',
                    'public/js/postcode.js'
                )
            );
        }
    }

    public function redirectAjax()
    {
        $args = $this->isAjax ? 'ajax=1' : '';
        $link = $this->url->link($this->referencePathFile, $args);

        $this->redirect($link);
    }

    public function quantity()
    {
        $qtdAtualizada = 0;
        $errUpdate = false;

        if (isset($this->session->data['cartxitem']) && ($this->config->get('listapresente_status'))) {
            $this->load->model('listapresente/listapresente');

            //valida caso o cliente queira adicionar uma quantidade maior que a desejada na lista de presentes
            $results = $this->model_listapresente_listapresente->getProdListListaId($this->session->data['cartxitem']['cliente']);
            foreach ($this->request->post['quantity'] as $key => $value) {
                if (array_key_exists((int) $key, $results) && ($value > $results[(int) $key])) {
                    $errUpdate = true;
                    $this->error['warning'] = 'Você esta adicionando uma quantidade maior que a desejada.';
                }
            }

            //valida caso o cliente	queira adicionar uma quantidade maior que a desejada na lista de presentes levando em conta o que já foi comprado.
            $results = $this->model_listapresente_listapresente->getProdCompListaId($this->session->data['cartxitem']['cliente']);

            foreach ($this->request->post['quantity'] as $key => $value) {
                if (array_key_exists((int) $key, $results) && (($results[(int) $key]['qtde_comprada'] + $value) > $results[(int) $key]['qtde_desejada'])) {
                    $errUpdate = true;
                    $this->error['warning'] = 'Você esta adicionando uma quantidade maior que a disponível para compra.';
                }
            }
        }

        if (($this->config->get('futuralimitaritem_status') == Type_Status::Tp_Habilitado) && (($this->config->get('tipopessoa') == Type_CadastroPessoa::Tp_Ambos) || ($this->config->get('tipopessoa') == $this->customer->getTipo_pessoa()))) {
            if ($this->config->get('tipolimite') == Type_LimitacaoItems::Tp_Qtdtotalitens) {
                foreach ($this->request->post['quantity'] as $key => $value) {
                    $qtdAtualizada += $value;
                }
                if (($qtdAtualizada) > ($this->config->get('qtd_maxitemcart'))) {
                    $errUpdate = true;
                    $this->error['warning'] = sprintf($this->language->get('text_limiteitens'), $this->config->get('qtd_maxitemcart'), $this->url->link('checkout/checkout'));
                }
            }
        }

        if ($this->config->get('config_fator_multiplicador')) {
            $isFator = $this->{$this->cartName}->isFatorMultiplicador($this->request->post['quantity']);
            if (!$isFator['status']) {
                $errUpdate = true;
                $this->error['warning'] = sprintf($this->language->get('error_fator_multiplicador'), $isFator['name'], $isFator['fator']);
            }
        }


        if ($errUpdate == false) {
            foreach ($this->request->post['quantity'] as $key => $value) {
                if ($this->config->get('config_stock_checkout')) {
                    $this->{$this->cartName}->update($key, $value);
                } else {
                    $result = $this->model_catalog_product->getProduct($key);
                    if ($result['qty'] >= $value) {
                        $this->{$this->cartName}->update($key, $value);
                        // $this->session->data['success'] = 'Quantidade alterada com sucesso!';
                    } else {
                        $this->session->data['warning'] = $this->language->get('error_stock_product');
                    }
                }
            }

            unset($this->session->data['shipping_method']);
            unset($this->session->data['shipping_methods']);
            unset($this->session->data['payment_method']);
            unset($this->session->data['payment_methods']);
            unset($this->session->data['reward']);

            $this->redirectAjax($this->isAjax);
        }
    }

    public function remove($cartList)
    {
        $this->{$this->cartName}->remove($this->request->get['remove']);

        unset($this->session->data['vouchers'][$this->request->get['remove']]);

        if ($cartList) {
            $this->session->data['success'] = $this->language->get('text_remove');
        }

        unset($this->session->data['shipping_method']);
        unset($this->session->data['shipping_methods']);
        unset($this->session->data['payment_method']);
        unset($this->session->data['payment_methods']);
        unset($this->session->data['reward']);

        if ($this->config->get('listapresente_status')) {
            if (isset($this->session->data['cartxitem'])) {
                $this->presente->remove((int) $this->request->get['remove']);
            }
        }

        $this->redirectAjax($this->isAjax);
    }

    public function extraActions()
    {
        // Coupon
        if (isset($this->request->post['coupon']) && $this->validateCoupon()) {
            $language = $this->language->load($this->referencePathFile);
            $this->session->data['coupon'] = $this->request->post['coupon'];
            $this->session->data['success'] = $this->language->get('text_coupon');

            $this->redirectAjax($this->isAjax);
        } else if (isset($this->request->post['coupon'])) {
            $this->session->data['warning'] = $this->error['warning'];
            $this->redirectAjax($this->isAjax);
        }

        // Reward
        if (isset($this->request->post['reward']) && $this->validateReward()) {
            $this->session->data['reward'] = abs($this->request->post['reward']);

            $this->session->data['success'] = $this->language->get('text_reward');

            $this->redirect($this->url->link($this->referencePathFile));
        }

        // Shipping
        if (isset($this->request->post['shipping_method']) && $this->validateShipping()) {
            $shipping = explode('.', $this->request->post['shipping_method']);
            $this->session->data['shipping_method'] = $this->session->data['shipping_methods'][$shipping[0]]['quote'][$shipping[1]];
            $this->session->data['shipping_checkout'] = $this->request->post['shipping_method']; //Só para carregar o modo de envio para a finalização do pedido
            $this->session->data['success'] = $this->language->get('text_shipping');

            $this->redirectAjax($this->isAjax);
        }
    }

    public function breadcrumbs()
    {
        $this->data['breadcrumbs'] = array();

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

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

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

    public function rewards()
    {
        $points = $this->customer->getRewardPoints();
        $points_total = 0;

        foreach ($this->{$this->cartName}->getProducts() as $product) {
            if ($product['points']) {
                $points_total += $product['points'];
            }
        }

        $this->data['text_use_reward'] = sprintf($this->language->get('text_use_reward'), $points);
        $this->data['entry_reward'] = sprintf($this->language->get('entry_reward'), $points_total);

        $this->data['languageApp'] = json_encode(
            array(
                'action' => $this->url->link($this->referencePathFile),
                'text_shipping_method' => $this->language->get('text_shipping_method'),
                'shipping_method' => $this->language->get('shipping_method'),
                'button_shipping' => $this->language->get('button_shipping'),
            )
        );

        $this->data['reward_status'] = ($points && $points_total && $this->config->get('reward_status'));
    }

    public function messages()
    {
        if (isset($this->error['warning'])) {
            $this->data['error_warning'] = $this->error['warning'];
        } elseif (!$this->{$this->cartName}->hasStock() && (!$this->config->get('config_stock_checkout') || $this->config->get('config_stock_warning'))) {
            $this->data['error_warning'] = $this->language->get('error_stock');
        } else {
            if (isset($this->session->data['warning'])) {
                $this->data['error_warning'] = addslashes($this->session->data['warning']);
                unset($this->session->data['warning']);
            } else {
                $this->data['error_warning'] = '';
            }
        }

        if ($this->config->get('config_customer_price') && !$this->customer->isLogged()) {
            $this->data['attention'] = addslashes(sprintf($this->language->get('text_login'), $this->url->link('account/login'), $this->url->link('account/register')));
        } else {
            $this->data['attention'] = '';
        }

        if (isset($this->session->data['success'])) {
            $this->data['success'] = addslashes($this->session->data['success']);

            unset($this->session->data['success']);
        } else {
            $this->data['success'] = '';
        }
    }

    public function getCartListAdditionalInfo($info)
    {
        extract($info);
        return [
            'href' => $this->url->link('product/product', 'product_id=' . $product['product_id']),
            'option' => $option_data,

            'fator_multiplicador' => $product['fator_multiplicador'],
            'reward' => ($product['reward'] ? sprintf($this->language->get('text_points'), $product['reward']) : ''),
            'price_not_discount' => $price_not_discount,
            'price' => $price,
            'price_value' => $product['price'],
            'recurring' => $product['recurring'],
            'profile_name' => $product['profile_name'],
            'ipi_valor' => $product['ipi_valor'] !== 'N' ? $this->currency->format($product['ipi_valor']) : 'N',
            'st_valor' => $product['st_valor'] !== 'N' ? $this->currency->format($product['st_valor']) : 'N',
            'fcpst_valor' => $product['fcpst_valor'] !== 'N' ? $this->currency->format($product['fcpst_valor']) : 'N',
            'ipi_valor_value' => str_replace(array('R$ ', ',', '.'), array('', '', ''), $product['ipi_valor']),
            'st_valor_value' => str_replace(array('R$ ', ',', '.'), array('', '', ''), $product['st_valor']),
            'fcpst_valor_value' => str_replace(array('R$ ', ',', '.'), array('', '', ''), $product['fcpst_valor']),
            'profile_description' => $profile_description,
            'brinde' => $brinde,
            'itens_kit' => $itens_kit
        ];
    }

    public function productExtraActions($info)
    {
        extract($info);

        $product_total = 0;

        foreach ($products as $product_2) {
            if ($product_2['product_id'] == $product['product_id']) {
                $product_total += $product_2['quantity'];
            }
        }

        if ($product['minimum'] > $product_total) {
            $this->data['error_warning'] = sprintf($this->language->get('error_minimum'), addslashes($product['name']), $product['minimum']);
        }

        $option_data = array();

        foreach ($product['option'] as $option) {
            if ($option['type'] != 'file') {
                $value = $option['option_value'];
            } else {
                $filename = $this->encryption->decrypt($option['option_value']);

                $value = utf8_substr($filename, 0, utf8_strrpos($filename, '.'));
            }

            $option_data[] = array(
                'name' => $option['name'],
                'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value)
            );
        }

        // Display prices
        if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) {
            $price = $this->currency->format($product['price']);
        } else {
            $price = false;
        }

        // Display prices
        if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) {
            $price_not_discount = $this->currency->format($product['price_not_discount']);
        } else {
            $price_not_discount = false;
        }

        // Display prices
        if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) {

            $total = $product['price'] * $product['quantity'];

            $modulostconf = $this->futuracalcularst->getconfiguracoes();
            if (count($modulostconf) > 0) {
                if (($this->customer->isLogged()) && ($this->customer->getTipo_pessoa() == 'J') && ($modulostconf['futuracalcularst_status'])) {
                    $arraySt = array(
                        'st_valor' => $product['st_valor'],
                        'ipi_valor' => $product['ipi_valor'],
                        'fcpst_valor' => $product['fcpst_valor'],
                    );

                    foreach ($arraySt as $key => $value) {
                        if (is_numeric($value)) {
                            $total += $value;
                        }
                    }
                }
            }
            $total = $this->currency->format($total);
        } else {
            $total = false;
        }

        $profile_description = '';

        if ($product['recurring']) {
            $frequencies = array(
                'day' => $this->language->get('text_day'),
                'week' => $this->language->get('text_week'),
                'semi_month' => $this->language->get('text_semi_month'),
                'month' => $this->language->get('text_month'),
                'year' => $this->language->get('text_year'),
            );

            if ($product['recurring_trial']) {
                $recurring_price = $this->currency->format($product['recurring_trial_price'] * $product['quantity']);
                $profile_description = sprintf($this->language->get('text_trial_description'), $recurring_price, $product['recurring_trial_cycle'], $frequencies[$product['recurring_trial_frequency']], $product['recurring_trial_duration']) . ' ';
            }

            $recurring_price = $this->currency->format($product['recurring_price'] * $product['quantity']);

            if ($product['recurring_duration']) {
                $profile_description .= sprintf($this->language->get('text_payment_description'), $recurring_price, $product['recurring_cycle'], $frequencies[$product['recurring_frequency']], $product['recurring_duration']);
            } else {
                $profile_description .= sprintf($this->language->get('text_payment_until_canceled_description'), $recurring_price, $product['recurring_cycle'], $frequencies[$product['recurring_frequency']], $product['recurring_duration']);
            }
        }

        if (isset($product['lista_escolar_id']) && $product['lista_escolar_id'] > 0) {
            $tipoLista = Type_ProductCart::Tp_ListaEscolar;
            $id_lista = $product['lista_escolar_id'];
            $this->data['cartlist'][$tipoLista][$id_lista]['escola'] = $product['lista_escolar_escola'];
            $this->data['cartlist'][$tipoLista][$id_lista]['serie'] = $product['lista_escolar_serie'];
            $this->data['cartlist'][$tipoLista][$id_lista]['observation'] = $product['observation'];
            $this->data['cartlist'][$tipoLista][$id_lista]['isListaEscolar'] = true;
        } else {
            $tipoLista = Type_ProductCart::Tp_Default;
            $id_lista = 0;
            $this->data['cartlist'][$tipoLista][$id_lista]['isListaEscolar'] = false;
        }

        //Brinde
        $produto_brinde = $this->dmodel_catalog_product->getProductBrinde($product['product_id'], !$this->config->get('config_stock_checkout'));

        $brinde = false;
        if ($produto_brinde) {
            $brinde['product_name'] = $produto_brinde['name'];
            $brinde['href'] = $this->url->link('product/product', 'product_id=' . $produto_brinde['product_brind_id']);
        }
        //Brinde

        //KIT
        $itens_kit = $this->dmodel_catalog_product->getProductKitItens($product['product_kit_id']);
        $this->data['starter_kit_status'] = (bool) $this->config->get('starter_kit_status');
        //KIT

        return [
            'product' => $product,
            'option_data' => $option_data,
            'price_not_discount' => $price_not_discount,
            'price' => $price,
            'profile_description' => $profile_description,
            'brinde' => $brinde,
            'itens_kit' => $itens_kit,
            'id_lista' => $id_lista,
            'tipoLista' => $tipoLista,
            'total' => $total
        ];
    }

    public function extraActionsEnd($products, $isAjax = false)
    {
        $this->data['products_recurring'] = array();

        $this->data['vouchers'] = array();

        if (!empty($this->session->data['vouchers'])) {
            foreach ($this->session->data['vouchers'] as $key => $voucher) {
                $this->data['vouchers'][] = array(
                    'key' => $key,
                    'description' => $voucher['description'],
                    'amount' => $this->currency->format($voucher['amount']),
                    'remove' => $this->url->link($this->referencePathFile, 'remove=' . $key)
                );
            }
        }

        if (isset($this->request->post['next'])) {
            $this->data['next'] = $this->request->post['next'];
        } else {
            $this->data['next'] = '';
        }

        $this->data['coupon_status'] = $this->config->get('coupon_status');

        if (isset($this->request->post['coupon'])) {
            $this->data['coupon'] = $this->request->post['coupon'];
        } elseif (isset($this->session->data['coupon'])) {
            $this->data['coupon'] = $this->session->data['coupon'];
        } else {
            $this->data['coupon'] = '';
        }

        $this->data['voucher_status'] = $this->config->get('voucher_status');

        if (isset($this->request->post['voucher'])) {
            $this->data['voucher'] = $this->request->post['voucher'];
        } elseif (isset($this->session->data['voucher'])) {
            $this->data['voucher'] = $this->session->data['voucher'];
        } else {
            $this->data['voucher'] = '';
        }

        if (isset($this->request->post['reward'])) {
            $this->data['reward'] = $this->request->post['reward'];
        } elseif (isset($this->session->data['reward'])) {
            $this->data['reward'] = $this->session->data['reward'];
        } else {
            $this->data['reward'] = '';
        }

        if (isset($this->request->post['zone_id'])) {
            $this->data['zone_id'] = $this->request->post['zone_id'];
        } elseif (isset($this->session->data['shipping_zone_id'])) {
            $this->data['zone_id'] = $this->session->data['shipping_zone_id'];
        } else {
            $this->data['zone_id'] = $this->config->get('config_zone_id');
        }

        if (isset($this->request->post['postcode'])) {
            $this->data['postcode'] = $this->request->post['postcode'];
        } elseif (isset($this->session->data['shipping_postcode'])) {
            $this->data['postcode'] = $this->session->data['shipping_postcode'];
        } else {

            if ($this->customer->isLogged()) {
                $this->load->model('account/address');
                $postcode = $this->model_account_address->getAddress($this->customer->getAddressId());
                $this->data['postcode'] = $postcode['postcode'];
            } else {
                $this->data['postcode'] = '';
            }
        }

        // Totals
        $this->load->model('setting/extension');

        $total_data = array();
        $total = 0;

        // Display prices
        if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) {
            $sort_order = array();

            $results = $this->model_setting_extension->getExtensions('total');

            foreach ($results as $key => $value) {
                $sort_order[$key] = $this->config->get($value['code'] . '_sort_order');
            }

            array_multisort($sort_order, SORT_ASC, $results);

            foreach ($results as $result) {
                if ($this->config->get($result['code'] . '_status')) {
                    $this->load->model('total/' . $result['code']);
                    $this->{'model_total_' . $result['code']}->getTotal($total_data, $total);
                }

                $sort_order = array();

                foreach ($total_data as $key => $value) {
                    $sort_order[$key] = $value['sort_order'];
                }

                array_multisort($sort_order, SORT_ASC, $total_data);
            }
        }

        $this->data['totals'] = $total_data;

        $modulostconf = $this->futuracalcularst->getconfiguracoes();

        $this->data['exibe_impostos'] = (count($modulostconf) > 0 && $this->customer->isLogged() && $this->customer->getTipo_pessoa() == 'J' && $modulostconf['futuracalcularst_status']) ? true : false;

        $this->data['continue'] = $this->url->link('common/home', '', 'NONSSL', 'false');

        if ($this->customer->isLogged() && count(array_filter($this->customer->getMandatoryInfo())) == 0) {
            $this->data['checkout'] = $this->url->link('checkout/information', '', 'SSL');
        } else {
            $this->data['checkout'] = $this->url->link('checkout/checkout', '', 'SSL');
        }

        $this->load->model('setting/extension');

        $this->data['checkout_buttons'] = array();

        /*habilita o não sei meu cep no app*/
        $this->data['dont_know_cep'] = $this->getChild('postcode/postcode');

        $this->data['displaySt'] = $this->customer->isLogged() && $this->customer->getTipo_pessoa() == 'J' && $modulostconf['futuracalcularst_status'];
        $this->data['displayFacebookTrack'] = $this->config->get('wg24_seo_fer_facebook_status') == 'enable' && !$this->config->get('wg24_seo_fer_facebook_pixel') == '';

        if ($this->data['displayFacebookTrack']) {
            $this->data['facebook_keys'] = json_encode(array_column($products, 'product_id'));
            $this->data['facebook_total'] = $this->{$this->cartName}->getSubTotal();
        }

        $this->data['modulostconf'] = $this->futuracalcularst->getconfiguracoes();

        if ($isAjax) {
            $this->load->controller('module/valor_minimo');
            $controllerValorMinimo = new ControllerModuleValorMinimo($this->registry);
            $this->data['valor_minimo'] = $controllerValorMinimo->index(true);
        } else {
            $this->children = $this->getChildren('module/valor_minimo');
        }
    }

    public function saveListCartObs()
    {
        $errors = [];

        if (isset($this->request->post['observations'])) {
            $observationsList = $this->request->post['observations'];

            foreach ($observationsList as $value) {
                $listID = substr($value, 0, strpos($value, '|'));
                $listObservation = trim(substr($value, strpos($value, '|') + 2, strlen($value)));

                $isRequired = $this->config->get('listaescolar_cart_obs_is_required');

                if($isRequired == Type_Status::Tp_Habilitado){
                    $error = $this->validate->execute([
                        $listID => [
                            'value' => trim($listObservation) ?? '',
                            'validates' => ['isEmpty'],
                        ]
                    ]);

                    if(count($error) != 0){
                        array_push($errors, $error);
                    }
                }

                $listProducts = array_filter($this->session->data['cart'], function ($products) use ($listID) {
                    if (isset($products['id_listaescolar'])) {
                        return $products['id_listaescolar'] == $listID;
                    }
                });

                foreach ($listProducts as $key => $product) {
                    $this->session->data['cart'][$key]['observation'] = $listObservation;
                }
            }
        }

        if(count($errors) != 0){
            $this->response->setOutput(json_encode($errors));
        }
    }
}