<?php

class Fidelitycart
{
  private $config;
  private $customer;
  private $session;
  private $weight;
  private $ftrgeralregistry;
  private $db;
  private $data = array();
  private $data_recurring = array();
  private $flag = true;
  private $load;
  private $registry;

  public function __construct($registry)
  {
    $this->config = $registry->get('config');
    $this->customer = $registry->get('customer');
    $this->session = $registry->get('session');
    $this->db = $registry->get('db');
    $this->weight = $registry->get('weight');
    $this->ftrgeralregistry = new Ftr_geral_registry($registry);
    $this->load = $registry->get('load');
    $this->registry = $registry;


    if (!isset($this->session->data['fidelitycart']) || !is_array($this->session->data['fidelitycart'])) {
      $this->session->data['fidelitycart'] = array();
    }
  }

  public function __get($name)
  {
    return $this->registry->get($name);
  }

  public function getProducts()
  {
    if (!$this->data) {
      $data_language = $this->config->get('config_data_language');
      if (!isset($data_language) || $data_language == Type_DataLanguage::Tp_Portugues_Brasil) {
        unset($data_language);
      }
      $this->load->type('tipocomum');
      $this->load->helper('ftr_geral');
      foreach ($this->session->data['fidelitycart'] as $key => $product_session_cart) {
        $quantity = $product_session_cart['quantity'];
        $product = explode(':', $key);
        $product_id = $product[0];
        $stock = true;

        if (!empty($product[1])) {
          $options = unserialize(base64_decode($product[1]));
        } else {
          $options = array();
        }

        if (!empty($product[2])) {
          $profile_id = $product[2];
        } else {
          $profile_id = 0;
        }

        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');
          $sql =
            "SELECT"
            . " p.*,"
            . " pd.*,";
          $sql .= isset($data_language) ? "coalesce(pt.descricao_ecommerce, pd.name) as name," : "pd.name as name,";
          $sql .= " (fp.pontos) as pontos,"
            . " (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"
            . " FROM " . DB_PREFIX . "product p"
            . " LEFT JOIN " . DB_PREFIX . "fidelity_present fp ON(p.product_id = fp.product_id)";
            $sql .= " LEFT JOIN " . DB_PREFIX . "product_description   pd  ON (p.product_id = pd.product_id)";
            $sql .= isset($data_language) ? " LEFT JOIN " . DB_PREFIX . "product_translate pt ON (p.product_id = pt.product_id and pt.linguagem = '" . $data_language . "')" : "";
            $sql .= " LEFT JOIN " . DB_PREFIX . "product_color         pc  ON (pc.productcolor_id = p.product_color_id)"
            . " LEFT JOIN " . DB_PREFIX . "product_size          ps  ON (ps.productsize_id = p.product_size_id)"
            . " LEFT JOIN " . DB_PREFIX . "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"
            . " WHERE p.product_id = '" . (int)$product_id . "' AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.date_available <= NOW() AND p.status = '1'";
          $product_query = $this->db->query($sql);
        } else {
          $sql = "SELECT p.*, pd.*, fp.*,";
          $sql .= isset($data_language) ? "coalesce(pt.descricao_ecommerce, pd.name) as name" : "pd.name as name";
          $sql .= " FROM " . DB_PREFIX . "product p
                  LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id)";
          $sql .= isset($data_language) ? " LEFT JOIN " . DB_PREFIX . "product_translate pt ON (p.product_id = pt.product_id and pt.linguagem = '" . $data_language . "')" : "";
          $sql .= " LEFT JOIN " . DB_PREFIX . "fidelity_present fp ON (fp.product_id = p.product_id)
                  WHERE p.product_id = '" . (int)$product_id . "'
                  AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "'
                  AND p.date_available <= NOW() AND p.status = '1'";
          $product_query = $this->db->query($sql);
        }


        if ($product_query->num_rows) {
          $option_weight = 0;

          foreach ($options as $product_option_id => $option_value) {
            $option_query = $this->db->query("SELECT po.product_option_id, po.option_id, od.name, o.type FROM " . DB_PREFIX . "product_option po LEFT JOIN `" . DB_PREFIX . "option` o ON (po.option_id = o.option_id) LEFT JOIN " . DB_PREFIX . "option_description od ON (o.option_id = od.option_id) WHERE po.product_option_id = '" . (int)$product_option_id . "' AND po.product_id = '" . (int)$product_id . "' AND od.language_id = '" . (int)$this->config->get('config_language_id') . "'");

            if ($option_query->num_rows) {
              if ($option_query->row['type'] == 'select' || $option_query->row['type'] == 'radio' || $option_query->row['type'] == 'image') {
                $option_value_query = $this->db->query("SELECT pov.option_value_id, ovd.name, pov.quantity, pov.subtract, pov.price, pov.price_prefix, pov.points, pov.points_prefix, pov.weight, pov.weight_prefix FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "option_value ov ON (pov.option_value_id = ov.option_value_id) LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE pov.product_option_value_id = '" . (int)$option_value . "' AND pov.product_option_id = '" . (int)$product_option_id . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "'");
                if ($option_value_query->num_rows) {

                  if ($option_value_query->row['weight_prefix'] == '+') {
                    $option_weight += $option_value_query->row['weight'];
                  } elseif ($option_value_query->row['weight_prefix'] == '-') {
                    $option_weight -= $option_value_query->row['weight'];
                  }
                  if ( $option_value_query->row['subtract'] && (!$option_value_query->row['quantity'] || ($option_value_query->row['quantity'] < $quantity)) ) {
                    $stock = false;
                  }

                }
              } elseif ($option_query->row['type'] == 'checkbox' && is_array($option_value)) {
                foreach ($option_value as $product_option_value_id) {
                  $option_value_query = $this->db->query("SELECT pov.option_value_id, ovd.name, pov.quantity, pov.subtract, pov.price, pov.price_prefix, pov.points, pov.points_prefix, pov.weight, pov.weight_prefix FROM " . DB_PREFIX . "product_option_value pov LEFT JOIN " . DB_PREFIX . "option_value ov ON (pov.option_value_id = ov.option_value_id) LEFT JOIN " . DB_PREFIX . "option_value_description ovd ON (ov.option_value_id = ovd.option_value_id) WHERE pov.product_option_value_id = '" . (int)$product_option_value_id . "' AND pov.product_option_id = '" . (int)$product_option_id . "' AND ovd.language_id = '" . (int)$this->config->get('config_language_id') . "'");

                  if ($option_value_query->num_rows) {

                    if ($option_value_query->row['weight_prefix'] == '+') {
                      $option_weight += $option_value_query->row['weight'];
                    } elseif ($option_value_query->row['weight_prefix'] == '-') {
                      $option_weight -= $option_value_query->row['weight'];
                    }

                    if ($option_value_query->row['subtract'] && (!$option_value_query->row['quantity'] || ($option_value_query->row['quantity'] < $quantity))) {
                      $stock = false;
                    }

                  }
                }
              }
            }
          }

          // Stock
          if (!$product_query->row['qty'] || ($product_query->row['qty'] < $quantity)) {
            $stock = false;
          }

          $type = ftr_geral::isIsset($this->config->get('config_product_code')) ? $this->config->get('config_product_code') : Type_ListCodProduct::Tp_CodReferencia;
          switch ($type) {
            case Type_ListCodProduct::Tp_CodReferencia:
              $model = $product_query->row['model'];
              break;
            case Type_ListCodProduct::Tp_CodProdEcommerce:
              $model = $product_query->row['product_id'];
              break;
            case Type_ListCodProduct::Tp_CodProdFuturaServer:
              $model = $product_query->row['id_futura'];
              break;
            case Type_ListCodProduct::Tp_CodBarras:
              $model = $product_query->row['codigo_barra'];
              break;
            default:
              $model = $product_query->row['model'];
          }


          if ($this->config->get('futuragrade_status') && in_array($product_query->row['tipo'], [Type_ProdutoGrade::Tp_MercadoriaRevenda, Type_ProdutoGrade::Tp_ProdutoAcabado])) {
            $this->load->model('catalog/product');
            $gridhave = $this->model_catalog_product->getGridHave($product_id);
            $gridhaveid = ($gridhave['grid_id']) ? $gridhave['grid_id'] : false;
          } else {
            $gridhaveid = false;
          }

          $this->data[$key] = array(
            'grid_id' => $gridhaveid,
            'key' => $key,
            'product_id' => $product_query->row['product_id'],
            'id_futura' => $product_query->row['id_futura'],
            'name' => $product_query->row['name'],
            'model' => $model,
            'shipping' => $product_query->row['shipping'],
            'image' => $product_query->row['image'],
            'data_atualizacao_replicacao' => $product_query->row['data_atualizacao_replicacao'],
            'pontos' => $product_query->row['pontos'],
            'quantity' => $quantity,
            'minimum' => $product_query->row['minimum'],
            'subtract' => $product_query->row['subtract'],
            'stock' => $stock,
            'price' => $product_query->row['price'],
            'total' => $product_query->row['price'] * $product_query->row['quantity'],
            'color_description' => ($this->config->get('futuragrade_status')) ? $product_query->row['color_description'] : '',
            'size_description' => ($this->config->get('futuragrade_status')) ? $product_query->row['size_description'] : '',
            'specification_description' => ($this->config->get('futuragrade_status')) ? $product_query->row['specification_description'] : '',
            'color_template_description' => ($this->config->get('futuragrade_status')) ? $product_query->row['color_template_description'] : '',
            'size_template_description' => ($this->config->get('futuragrade_status')) ? $product_query->row['size_template_description'] : '',
            'specification_template_description' => ($this->config->get('futuragrade_status')) ? $product_query->row['specification_template_description'] : '',
            'total' => ($product_query->row['pontos']) * (int)$quantity,
            'total_price' => ($product_query->row['price']) * (int)$quantity,
            'weight' => ($product_query->row['weight'] + $option_weight) * (int)$quantity,
            'net_weight' => $product_query->row['net_weight'] * (int)$quantity,
            'weight_class_id' => $product_query->row['weight_class_id'],
            'weight_unit' => $product_query->row['weight'],
            'net_weight_unit' => $product_query->row['net_weight'],
            'length' => $product_query->row['length'],
            'width' => $product_query->row['width'],
            'height' => $product_query->row['height'],
            'comp_progressiva' => $product_query->row['comp_progressiva'],
            'larg_progressiva' => $product_query->row['larg_progressiva'],
            'alt_progressiva' => $product_query->row['alt_progressiva'],
            'length_class_id' => $product_query->row['length_class_id'],
            'profile_id' => $profile_id,
            'sku' => $product_query->row['sku'],
          );
        } else {
          $this->remove($key);
        }
      }
    }

    return $this->data;
  }

  public function getRecurringProducts()
  {
    $recurring_products = array();

    foreach ($this->getProducts() as $key => $value) {
      if ($value['recurring']) {
        $recurring_products[$key] = $value;
      }
    }

    return $recurring_products;
  }

  public function add($product_id, $qty = 1, $option = '', $profile_id = '')
  {
    $key = (int)$product_id . ':';

    if ($option) {
      $key .= base64_encode(serialize($option)) . ':';
    } else {
      $key .= ':';
    }

    if ($profile_id) {
      $key .= (int)$profile_id;
    }

    if ((int)$qty && ((int)$qty > 0)) {
      if (!isset($this->session->data['fidelitycart'][$key])) {
        $this->session->data['fidelitycart'][$key] =
          array(
            'quantity' => (int)$qty
          );
      } else {
        $this->session->data['fidelitycart'][$key]['quantity'] += (int)$qty;
      }
    }

    $this->data = array();
  }


  public function update($key, $qty)
  {
    if ((int)$qty && ((int)$qty > 0)) {
      $this->session->data['fidelitycart'][$key]['quantity'] = (int)$qty;
    } else {
      $this->remove($key);
    }

    $this->data = array();
  }

  public function remove($key)
  {
    if (isset($this->session->data['fidelitycart'][$key])) {
      unset($this->session->data['fidelitycart'][$key]);
    }

    $this->data = array();
  }

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

    $this->data = array();
  }

  public function getWeight()
  {
    $weight = 0;

    foreach ($this->getProducts() as $product) {
      if ($product['shipping']) {
        $weight += $this->weight->convert($product['weight'], $product['weight_class_id'], $this->config->get('select_peso'));
      }
    }

    return $weight;
  }

  public function getNetWeight() {
    $weight = 0;

    foreach ($this->getProducts() as $product) {
      if ($product['shipping']) {
        $weight += $this->weight->convert($product['net_weight'], $product['weight_class_id'], $this->config->get('select_peso'));
      }
    }

    return $weight;
  }

  public function getTotal()
  {
    $total = 0;

    foreach ($this->getProducts() as $product) {
      $total += $product['pontos'] * $product['quantity'];
    }

    return $total;
  }

  public function getTotalPrice()
  {
    $total = 0;

    foreach ($this->getProducts() as $product) {
      $total += $product['price'] * $product['quantity'];
    }

    return $total;
  }

  public function getSubTotal() {
    $total = 0;

    foreach ($this->getProducts() as $product) {
      $total += $product['total'];
    }

    return $total;
  }

  public function getSubTotalPrice() {
    $total = 0;

    foreach ($this->getProducts() as $product) {
      $total += $product['total_price'];
    }

    return $total;
  }

  public function countProducts()
  {
    $product_total = 0;

    $products = $this->getProducts();

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

    return $product_total;
  }

  public function countVariedadeProducts($idProduto = 0)
  {
    //O $idProduto serve para verificar se já existe o produto na lista
    //Caso ele não exista soma mais um no retorno pois o produto está sendo adicionado.
    $product_total = 0;
    $products = $this->getProducts();

    if (count($products) > 0) {
      $produtoListado = false;
      foreach ($products as $product) {
        $product_total += 1;
        if ($product ['product_id'] == $idProduto) {
          $produtoListado = true;
        }
      }

      if ((!$produtoListado) && ($idProduto > 0)) {
        $product_total += 1;
      }
    }

    return $product_total;
  }


  public function hasProducts()
  {
    return count($this->session->data['fidelitycart']);
  }

  public function hasRecurringProducts()
  {
    return count($this->getRecurringProducts());
  }

  public function hasStock()
  {
    $stock = true;

    foreach ($this->getProducts() as $product) {
      if (!$product['stock']) {
        $stock = false;
      }
    }

    return $stock;
  }

  public function hasShipping()
  {
    $shipping = false;

    foreach ($this->getProducts() as $product) {
      if ($product['shipping']) {
        $shipping = true;

        break;
      }
    }

    return $shipping;
  }

  public function hasDownload()
  {
    $download = false;

    foreach ($this->getProducts() as $product) {
      if ($product['download']) {
        $download = true;

        break;
      }
    }

    return $download;
  }

  public function getItemQuantity($product_id)
  {
    return isset($this->getProducts()[$product_id . '::']['quantity']) ? $this->getProducts()[$product_id . '::']['quantity'] : 0;
  }

  public function hasGridId()
  {

    $grid_id = false;
    foreach ($this->getProducts() as $product) {
      if ($product['grid_id']) {
        $grid_id[] = $product['grid_id'];
      }
    }

    return $grid_id;
  }


}
