<?php

final class DModelaccountorder extends Model
{

    public function getOrderProducts($order_id, $returnKit=false)
    {
        $fieldsOp =
        " op.`order_product_id`,
         op.`order_id`,
         op.`product_id`,
         op.`name`,
         op.`model`,
         op.`quantity`,
         op.`price`,
         op.`total`,
         op.`reward`,
         op.`fcpst_valor`,
         op.`mkt_comission`,
         op.`fcpst_base`,
         op.`st_base`,
         op.`ipi_percentual`,
         op.`id_futura`,
         op.`st_valor`,
         op.`ipi_valor`,
         op.`marketId`,
         op.`mkt_variation_id`,
         op.`lista_escolar_id`,
         op.`lista_escolar_descricao`,
         op.`brinde_product_id`,
         op.`pontos`,
         op.`total_pontos`,
         op.`brinde_tipo`,
         op.`product_kit_id`,
         op.`product_kit_qtd`,
         op.`acrescimo_valor`,
         op.`desconto_valor`,
         op.`frete_valor`,";

        if  ($returnKit){
            $fieldsUnion =
            "op.`order_product_id`,
            op.`order_id`,
            p.`product_id` ,
            pd.`name`,
            p.`model`,
            op.`product_kit_qtd` quantity,
            sum(op.`price`*op.`quantity`),
            sum(op.`total`),
            op.`reward`,
            sum(op.`fcpst_valor`),
            sum(op.`mkt_comission`),
            sum(op.`fcpst_base`),
            sum(op.`st_base`),
            sum(op.`ipi_percentual`),
            null,
            sum(op.`st_valor`),
            sum(op.`ipi_valor`),
            null,
            null,
            null,
            null,
            null,
            sum(op.`pontos`),
            sum(op.`total_pontos`),
            op.`brinde_tipo`,
            null,
            null,
            sum(op.`acrescimo_valor`),
            sum(op.`desconto_valor`),
            sum(op.`frete_valor`),";
        }

        if ($this->config->get('futuragrade_status')) {
            $language = $this->language->load('module/futuragrade');
            $title_specification = (ftr_geral::isIsset($this->config->get('futuragrade_title_specification')) && $this->config->get('futuragrade_title_specification') != "") ? $this->config->get('futuragrade_title_specification') : $this->language->get('heading_title_specification');
            $title_size = $this->language->get('heading_title_size');
            $title_cor = $this->language->get('heading_title_cor');
            $commonFields = " (p.image) image,"
                . "   (p.sku) sku,"
                . "   (p.codigo_barra)  codigo_barra,"
                . "   (pc.productcolor_id)  color_id,"
                . "   (ps.productsize_id)  size_id,"
                . "   (psp.productspecification_id) specification_id,"
                . "   (pc.description)  color_description,"
                . "   (ps.description)  size_description,"
                . "   (psp.description) specification_description,"
                . "   (COALESCE(pgt.descricao_cor,'$title_cor')) color_template_description,"
                . "   (COALESCE(pgt.descricao_tamanho,'$title_size')) size_template_description,"
                . "   (COALESCE(pgt.descricao_especificacao,'$title_specification')) specification_template_description,"
                . "   (p.id_futura) id_futura,"
                . "   (p.image)		  image,"
                . "   (p.weight)		weight,"
                . "   (p.data_atualizacao_replicacao)	data_atualizacao_replicacao";
            $gridJoins = "
                LEFT JOIN oc_product_color         pc  ON (pc.productcolor_id = p.product_color_id)
                LEFT JOIN oc_product_size          ps  ON (ps.productsize_id = p.product_size_id)
                LEFT JOIN oc_product_specification psp ON (psp.productspecification_id = p.product_specification_id)
                LEFT JOIN oc_product_grid_detail pgd ON pgd.product_id = p.product_id
                LEFT JOIN oc_product_grid pg ON pg.product_grid_id = pgd.product_grid_id
                LEFT JOIN oc_product_grid_template pgt ON pg.product_grid_template_id = pgt.product_grid_template_id ";

            $sql = "SELECT "
                    . $fieldsOp
                    . $commonFields
                    . " FROM " . DB_PREFIX . "order_product op"
                    . " LEFT JOIN " . DB_PREFIX . "product p   ON (p.product_id = op.product_id)"
                    . $gridJoins
                    . " WHERE order_id = '" . (int)$order_id . "' and brinde_product_id is null ";
            $sql .= $returnKit ? " AND product_kit_id IS null " : "";

            if  ($returnKit){
                $sql .= " UNION SELECT "
                .$fieldsUnion
                .$commonFields.
                " FROM oc_product_kit pkit
                    INNER JOIN oc_order_product op ON pkit.product_kit_id = op.product_kit_id
                    INNER JOIN oc_product               p   ON (p.product_id = pkit.product_id)
                    INNER JOIN oc_product_description   pd   ON (pd.product_id = p.product_id) "
                    .$gridJoins.
                " WHERE order_id = '" . (int)$order_id . "' and brinde_product_id is NULL AND not op.product_kit_id IS null
                GROUP BY p.product_id";
            }

            $query = $this->db->query($sql);
        } else {
            $commonFields = " p.image AS image,
                p.sku AS sku,
                p.weight,
                p.id_futura,
                (p.codigo_barra) codigo_barra,
                (p.data_atualizacao_replicacao) data_atualizacao_replicacao ";

            $sql = " SELECT "
            . $fieldsOp
            . $commonFields.
            " FROM " . DB_PREFIX . "order_product op
            left join " . DB_PREFIX . "product p ON (p.product_id = op.product_id)
            WHERE op.order_id = '" . (int)$order_id . "' and brinde_product_id is null GROUP BY p.product_id";
            $sql .= $returnKit ? " AND product_kit_id IS null " : "";


            if  ($returnKit){
                $sql .= " UNION SELECT "
                .$fieldsUnion
                .$commonFields.
                " FROM oc_product_kit pkit
                INNER JOIN oc_order_product op ON pkit.product_kit_id = op.product_kit_id
                INNER JOIN oc_product               p   ON (p.product_id = pkit.product_id)
                INNER JOIN oc_product_description   pd   ON (pd.product_id = p.product_id)
                WHERE order_id = '" . (int)$order_id . "' and brinde_product_id is NULL AND not op.product_kit_id IS null
                GROUP BY p.product_id";
            }

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

        return $query->rows;
    }

    public function getProductOrderBrinde($product_id, $order_id)
    {
        $data_language = $this->config->get('config_data_language');
        if (!isset($data_language) || $data_language == Type_DataLanguage::Tp_Portugues_Brasil) {
            unset($data_language);
        }
        $sql = "SELECT
              op.product_id,
              op.brinde_product_id,
              p.image,
              p.quantity estoque,
              p.price preco_unitario,
              p.model,
              op.quantity quantity_order,
              op.price price_order,
              op.total total_order,";
        $sql .= isset($data_language) ? "coalesce(pt.descricao_ecommerce, pd.name) as name" : "pd.name as name";
        $sql .= " FROM oc_order_product op
               INNER JOIN oc_product p ON p.product_id = op.product_id
               INNER JOIN oc_product_description pd ON pd.product_id = p.product_id";
        $sql .= isset($data_language) ? " LEFT JOIN oc_product_translate pt ON (p.product_id = pt.product_id and pt.linguagem = '" . $data_language . "')" : "";
        $sql .= " WHERE op.brinde_product_id = $product_id && op.order_id = $order_id";
        $query = $this->db->query($sql);
        if (count($query->row) > 0) {
            return $query->row;
        } else {
            return false;
        }
    }

    public function getOrdertKit($order_id, $product_kit_id)
    {
        $itens_kit = array();
        $this->load->dmodel('tool/image');

        $sql = "SELECT distinct
            op.order_product_id,
            pk.id_futura product_kit_id_futura,
            pk.product_id pkit_product_id,
            op.quantity quantidade,
            pd.name,
            op.product_kit_qtd,
            op.total op_total,
            op.pontos,
            op.product_kit_id,
            op.brinde_product_id,
            p.*
          FROM oc_order_product op
          INNER JOIN oc_product_kit pk ON pk.product_kit_id = op.product_kit_id
          INNER JOIN oc_product p ON p.product_id = op.product_id
          INNER JOIN oc_product_description pd ON p.product_id = pd.product_id
          Where op.product_kit_id = $product_kit_id AND order_id = $order_id";

        $itens_kit_model = $this->db->query($sql)->rows;

        if (!$itens_kit_model) {
            return [];
        }

        $total = 0;
        $pontos = 0;
        $produto_brinde= 0;
        $this->load->library('image_validate');
        $image_validate = new Image_validate();

        foreach ($itens_kit_model as $item_kit) {

            if($item_kit['brinde_product_id']){
                $produto_brinde = $this->getProductOrderBrinde($item_kit['brinde_product_id'],$order_id);
                $produto_brinde['href'] = $this->url->link('product/product', 'product_id=' . $produto_brinde['brinde_product_id']);
                $produto_brinde['product_name'] = $produto_brinde['name'];

                continue;
            }

            if ($item_kit['image'] && $image_validate->isValidate($item_kit)) {
                $watermark_config_date_number = $this->dmodel_tool_image->getWatermarkCacheNumber();
                $image_version_number = '?version=' . preg_replace("/[^0-9]/", "", $item_kit['data_atualizacao_replicacao']) . $watermark_config_date_number;
                $tumb_img_kit = $this->dmodel_tool_image->resizeWithWatermark($item_kit['image'], Type_MiniatureMedium::Tp_width, Type_MiniatureMedium::Tp_height) . $image_version_number;
            } else {
                $tumb_img_kit = $this->dmodel_tool_image->resize('data/sem-imagem.png', Type_MiniatureMedium::Tp_width, Type_MiniatureMedium::Tp_height);
            }

            $itens_kit[] = array(
                'thumb' => $tumb_img_kit,
                'quantidade' => $item_kit['quantidade'] / $item_kit['product_kit_qtd'],
                'descricao' => $item_kit['name'],
                'href' => $this->url->link('product/product', 'product_id=' . $item_kit['product_id']),
                'product_id' => $item_kit['product_id'],
                'product_kit_id' => $item_kit['product_kit_id'],
                'product_kit_id_futura' => $item_kit['product_kit_id_futura']

            );
            $total += $item_kit['op_total'];
            $quantidade_kit = $item_kit['product_kit_qtd'];
            $id_produto_pai = $item_kit['pkit_product_id'];
            $pontos += $item_kit['pontos'];

        }
        $this->load->model('catalog/product');
        $product = $this->model_catalog_product->getProduct($id_produto_pai);

        if ($product['image'] && $image_validate->isValidate($product)) {
            $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);
        }
        $produkt_kit = array(
            'id' => $product['product_id'],
            'name' => $product['name'],
            'model' => $product['model'],
            'image' => $image,
            'original_image' => $product['image'],
            'data_atualizacao_replicacao' => $product['data_atualizacao_replicacao'],
            'option' => array(),
            'quantity' => $quantidade_kit,
            'price' => ($total > 0 ) ? $this->currency->format($total / $quantidade_kit) : $total,
            'total' => $this->currency->format($total),
            'return' => $this->url->link('account/return/insert', 'order_id=' . $order_id . '&product_id=' . $product['product_id'], 'SSL'),
            'pontos' => ($pontos > 0) ? $pontos / $quantidade_kit : $pontos,
            'total_pontos' => $pontos,
            'brinde' => $produto_brinde,
            'itens_kit' => $itens_kit,
            'total_price' => $product['price'],
        );

        return $produkt_kit;
    }

    public function vinculateOrderProductKit($orderId, $mktID, $productKitId){
        //Troca o produto kit da order product pelos itens desse kit
        $this->load->dmodel('catalog/product');
        $this->load->dmodel('marketplace/mktpedido');
        $this->load->dmodel('checkout/order');
        $this->language->load('total/descontoacrescimokit');

        $orderProduct = $this->db->query("SELECT * FROM oc_order_product WHERE order_id = $orderId AND marketId = '$mktID' limit 1")->row;
        $orderProductId = $orderProduct['order_product_id'];
        $itensKit = $this->dmodel_catalog_product->getProductKitItens($productKitId, $orderProduct['price']);
        $oldSubtotal = $this->db->query("SELECT `value` FROM oc_order_total  WHERE `code` = 'sub_total' AND order_id = $orderId")->row;

        foreach ($itensKit as $itemKit) {
            $dadosProd[] = array(
              'product_id'        => $itemKit['product_id'],
              'name'              => $itemKit['descricao'],
              'model'             => $itemKit['model'],
              'quantity'          => $itemKit['quantidade']*$orderProduct['quantity'],
              'price'             => $itemKit['price'],
              'total'             => ($itemKit['price'] * $itemKit['quantidade']) * $orderProduct['quantity'],
              'marketId'          => "",
              'mkt_comission'     => 0,
              'mkt_variation_id'  => "",
              'product_kit_id'    => $productKitId,
              'product_kit_qtd'   => $orderProduct['quantity'],
              'id_futura'         => $itemKit['product_id_futura'],
              'discount'          => ($itemKit['acerto'])<0 ? ($itemKit['acerto'] *-1)*$orderProduct['quantity'] : 0,
              'increase'          => ($itemKit['acerto'])>0 ? $itemKit['acerto']*$orderProduct['quantity'] : 0,
              'shipping'          => 0
            );
        }
        $dicountKit  = array_sum(array_column($dadosProd,'discount'));
        $increaseKit = array_sum(array_column($dadosProd,'increase'));
        $subtotalKit = array_sum(array_column($dadosProd,'total'));

        $inc = 0;
        $countItem = count($dadosProd);

        $accDiscont  = 0;
        $accIncrease = 0;
        $accShipping = 0;
        $accComission = 0;
        foreach ($dadosProd as $key => $item){
            if ($orderProduct['desconto_valor']==0 && $orderProduct['acrescimo_valor']==0 && $orderProduct['frete_valor']==0 && $orderProduct['mkt_comission']==0){
                break;
            }

            $inc += 1;
            $newDiscount = 0;
            $newIncrease = 0;
            $newShipping = 0;
            $newComission = 0;

            $baseproduto  = (($item['quantity'] * $item['price']) * 100) / $subtotalKit;

            if ($orderProduct['desconto_valor']>0) {
                $newDiscount = round(  ((($baseproduto  / 100) * $orderProduct['desconto_valor']) + $item['discount']), 2, PHP_ROUND_HALF_DOWN);
                $accDiscont += $newDiscount;
                if (($accDiscont <> ($dicountKit+$orderProduct['desconto_valor']) ) && ($countItem == $inc)) {
                    $newDiscount += ($dicountKit+$orderProduct['desconto_valor']) - round($accDiscont, 2, PHP_ROUND_HALF_DOWN);
                }
                $dadosProd[$key]['discount'] = $newDiscount;
            }

            if ($orderProduct['acrescimo_valor']>0) {
                $newIncrease = round(  ((($baseproduto  / 100) * $orderProduct['acrescimo_valor']) + $item['increase']), 2, PHP_ROUND_HALF_DOWN);
                $accIncrease += $newIncrease;
                if (($accIncrease <> ($increaseKit+$orderProduct['acrescimo_valor']) ) && ($countItem == $inc)) {
                    $newIncrease += ($increaseKit+$orderProduct['acrescimo_valor']) - round($accIncrease, 2, PHP_ROUND_HALF_DOWN);
                }
                $dadosProd[$key]['increase'] = $newIncrease;
            }

            if ($orderProduct['frete_valor']>0) {
                $newShipping = round(  (($baseproduto  / 100)  * $orderProduct['frete_valor']), 2, PHP_ROUND_HALF_DOWN);
                $accShipping += $newShipping;
                if (($accShipping <> ($orderProduct['frete_valor']) ) && ($countItem == $inc)) {
                    $newShipping += ($orderProduct['frete_valor']) - round($accShipping, 2, PHP_ROUND_HALF_DOWN);
                }
                $dadosProd[$key]['shipping'] = $newShipping;
            }

            if ($orderProduct['mkt_comission']>0) {
                $newComission = round(  (($baseproduto  / 100)  * $orderProduct['mkt_comission']), 2, PHP_ROUND_HALF_DOWN);
                $accComission += $newComission;
                if (($accShipping <> ($orderProduct['mkt_comission']) ) && ($countItem == $inc)) {
                    $newComission += ($orderProduct['mkt_comission']) - round($accComission, 2, PHP_ROUND_HALF_DOWN);
                }
                $dadosProd[$key]['mkt_comission'] = $newComission;
            }

        }


        $newSubtotal = $oldSubtotal['value'] - $orderProduct['total'] + $subtotalKit;

        if($increaseKit > 0){
          $totalKitData[] = array(
                'code'       => 'descontoacrescimokit',
                'title'      => $this->language->get('acrescimo_kit'),
                'text'       => $this->currency->format($increaseKit),
                'value'      => $increaseKit,
                'sort_order' => $this->config->get('sub_total_sort_order')+1
          );
        }
        if($dicountKit > 0){
            $totalKitData[] = array(
                'code'       => 'descontoacrescimokit',
                'title'      => $this->language->get('desconto_kit'),
                'text'       => $this->currency->format($dicountKit*-1),
                'value'      => $dicountKit*-1,
                'sort_order' => $this->config->get('sub_total_sort_order')+1
            );
        }

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

        try{
            $this->db->startTransaction();

            foreach($dadosProd as $prod){
                $extraFields = array("product_kit_id","product_kit_qtd","desconto_valor","acrescimo_valor","frete_valor");
                $extraValues = array($prod["product_kit_id"],$prod["product_kit_qtd"],$prod["discount"],$prod["increase"],$prod["shipping"]);
                $this->dmodel_marketplace_mktpedido->addOrderProduct($orderId, $prod,$extraFields,$extraValues);
            }

            $this->db->query("DELETE FROM oc_order_product WHERE order_product_id = $orderProductId" );
            $this->dmodel_marketplace_mktpedido->addOrderTotal($orderId, $totalKitData);
            $this->dmodel_marketplace_mktpedido->updateOrderTotal($orderId, $newSubtotalData);

            $this->db->commit();
        } catch (Exception $e) {
            $this->db->rollback();
            throw new exception('Erro vincular kit ao produto.'.$e->getMessage());
        }
    }
}
