<?php

class GaleriaPageUtils extends WebServiceMktp
{
    protected $accessToken = null;
    protected $tokenExpire;
    protected $idClient;
    protected $keyAccess;
    public  $header;

    const domain_app      = 'https://apiseller.galeriapage.com.br';
    const domain_app_test = 'http://hom.api.seller.galeriapage.com.br';

    public function __construct($registry)
    {
        parent::__construct($registry);
    
        $producao = ($this->config->get('galeriapage_environment') && ($this->config->get('galeriapage_environment') == Type_Environment::Tp_Production));
    
        $this->API_DOMAIN = $producao ? $this::domain_app : $this::domain_app_test;
    
        $this->header = array(
            'Accept: application/json;charset=UTF-8',
            'Content-Type: application/json'
        );
    
        if ($this->config->get('galeriapage_email')) {
            $this->appId = trim($this->config->get('galeriapage_email') ?? '');
        }
    
        if ($this->config->get('galeriapage_password')) {
            $this->appSecret = trim($this->config->get('galeriapage_password') ?? '');
        }
    
        $this->accessToken = trim($this->config->get('galeriapage_access_token') ?? '');
        $this->tokenExpire = trim($this->config->get('galeriapage_token_expire') ?? '');
        $this->idClient    = trim($this->config->get('galeriapage_id_client') ?? '');
        $this->keyAccess   = trim($this->config->get('galeriapage_key_access') ?? '');
    }

    public function callAPI($url, $method = 'GET', $dataSend = false, $header = array(), $file = false, &$httpcode = false, $dataType = Type_DadosSend::TpDados_Identificar, $returnFile = false)
    {
        $httpcode = 0;

        $data = parent::callAPI($url, $method, $dataSend, $header, $file, $httpcode, $dataType, $returnFile);

        if ($httpcode == 0) {
            $this->setErrorGP($this->error, $url, $method, $dataSend, $data);
            $this->error = ' Connection Error';
        } elseif ($httpcode == 400 || $httpcode == 401 || $httpcode == 403 || $httpcode == 404 || $httpcode == 405 || $httpcode == 406 || $httpcode == 407 || $httpcode == 409 || $httpcode == 410 || $httpcode == 500 || $httpcode == 501 || $httpcode == 502) {
            $this->error = $data->error ?? $data->data->messageError ?? $data;
        } elseif(!property_exists($data,'sucess') && !property_exists($data, 'status')) {
            $this->error = $data->message;
        }else {
            return $data;
        }
    }

    public function setErrorGP($error, $url = '', $method = '', $data = '', $body = '')
    {
        if ($this->config->get('galeriapage_debug')) {
            $error_msg = 'Error =>' . $error . PHP_EOL;
            $error_msg .= (!empty($url)) ? 'Url => ' . $url . PHP_EOL : '';
            $error_msg .= (!empty($method)) ? 'Metodo => ' . $method . PHP_EOL : '';
            $error_msg .= (!empty($data)) ? 'Data => ' . print_r($data, true) . PHP_EOL : '';
            $error_msg .= (!empty($body)) ? 'Body => ' . print_r($body, true) . PHP_EOL : '';
            $error_msg .= '-----------------------------------------------------------------------------------------------';
            $this->loggp->write($error_msg);
        }
    }

    public function convertPicturesObject($picturesobj)
    {
        $pictures = $picturesobj->getImagens();
        $retorno = array();

        if (count($pictures) <= 0) {
            return $retorno;
        };

        foreach ($pictures as $img) {
            $retorno[] = $img->getLink();
        }
        return $retorno;

    }

    public function getAccess()
    {
        if($this->config->get('galeriapage_status') == Type_Status::Tp_Habilitado){
            if ((!$this->accessToken) || ($this->tokenExpire < time() + 1)) {
                $this->getAuth();
                $this->accessToken = trim($this->config->get('galeriapage_access_token'));
                $this->tokenExpire = trim($this->config->get('galeriapage_token_expire'));
                $this->idClient    = trim($this->config->get('galeriapage_id_client'));
                $this->keyAccess   = trim($this->config->get('galeriapage_key_access'));
            }
        }
    }

    // Auth
    public function getAuth($email = false, $password = false, $environment = false){
        if ($environment){
            $domain = $environment == Type_Environment::Tp_Production ? $this::domain_app : $this::domain_app_test;
        } else {
            $domain = $this->API_DOMAIN;
        }
        $url = $domain . '/api/Auth/Login';

        $param = array(
            "email" =>    $email    ? $email    : $this->appId,
            "password" => $password ? $password : $this->appSecret
        );

        $param = json_encode($param);

        $data = $this->callAPI($url, 'POST', $param, $this->header);

        if ($this->error) {
            return $this->error;
        } else {
            if (is_object($data) && property_exists($data, 'token')) {
                $this->load->model('setting/setting');
                $dateTime = date_create($data->expiration);
                $dateTime = date_timestamp_get($dateTime);
                $tokenInfo = array(
                    'galeriapage_access_token' => $data->token,
                    'galeriapage_token_expire' => $dateTime,
                    'galeriapage_id_client' => $data->idClient,
                    'galeriapage_key_access' => $data->keyAcess,
                );

                $this->model_setting_setting->editSettingForKey('galeriapage', $tokenInfo);
            }
            return $data;
        }
    }

    // Status
    public function getStatusAPI($environment = false)
    {
        if ($environment){
            $domain = $environment == Type_Environment::Tp_Production ? $this::domain_app : $this::domain_app_test;
        } else {
            $domain = $this->API_DOMAIN;
        }
        $url = $domain . '/api/Status/All';

        $data = $this->callAPI($url, 'GET');
        if ($this->error) {
            return false;
        } else {
            return $data;
        }
    }

    // Carrier
    public function getTrackingCode($orderId)
    {
        $this->getAccess();
        $param = array();
        $header = array(
          'Authorization: Bearer ' . $this->accessToken,
          'Content-Type: application/json'
        );
        $url = $this->API_DOMAIN . '/api/Carrier/GetTrackingNumber';
        $product_data = $this->callAPI($url, 'GET', $param, $header);

        return $product_data;
    }

    // Sku
    public function addProduct($param)
    {
        $this->getAccess();
        $url = $this->API_DOMAIN . '/api/Sku';
        $header = array(
          'Authorization: Bearer ' . $this->accessToken,
          'Content-Type: application/json'
        );

        $param = json_encode($param, JSON_UNESCAPED_SLASHES);

        $data = $this->callAPI($url, 'POST', $param, $header);
        return $data;
    }

    public function updateProductStock($productID, $stock)
    {
        $this->getAccess();
        $url = $this->API_DOMAIN . '/api/Sku/UpdateStock';

        $header = array(
          'Authorization: Bearer ' . $this->accessToken,
          'Content-Type: application/json'
        );

        $param = array(
          "codeStore"  => $productID,
          "valueStock" => $stock,
          "idClient"   => $this->idClient,
          "keyAPI"     => $this->keyAccess,
        );
        $param = json_encode($param);

        $data = $this->callAPI($url, 'PUT', $param, $header);
        return $data;
    }

    public function updateProductPrice($productID, $pricePer, $priceOf)
    {
        $this->getAccess();
        $url = $this->API_DOMAIN . '/api/Sku/UpdatePrice';

        $header = array(
          'Authorization: Bearer ' . $this->accessToken,
          'Content-Type: application/json'
        );

        $param = array(
          "idClient"   => $this->idClient,
          "keyApi"     => $this->keyAccess,
          "codeStore"  => $productID,
          "pricePer"   => $pricePer,
          "priceOf"    => $priceOf,
        );
        $param = json_encode($param);

        $data = $this->callAPI($url, 'PUT', $param, $header);
        return $data;
    }

    public function updateProduct($productID, $param)
    {
      $this->getAccess();
      $url = $this->API_DOMAIN . '/api/Sku/UpdateAllSkuDataByEan';

      $header = array(
        'Authorization: Bearer ' . $this->accessToken,
        'Content-Type: application/json'
      );

      $param = json_encode($param);

      $data = $this->callAPI($url, 'PUT', $param, $header);
      return $data;
    }

    public function getProduct($itemId)
    {
        $this->getAccess();
        $header = array(
            'Authorization: Bearer ' . $this->accessToken
        );
        $url = $this->API_DOMAIN . '/api/Sku?keyApi=' . $this->keyAccess . '&idClient=' . $this->idClient . '&codeStore=' . $itemId;
        $product_data = $this->callAPI($url, 'GET', false, $header);

        return $product_data;
    }

    public function updateProductEnable($productID, $enabled = false)
    {
        $this->getAccess();
        $urlAdditional = ($enabled ? 'True' : ''); // se for pra ativar o produto tem que por um true na frente da url   ¯\_(ツ)_/¯
        $url = $this->API_DOMAIN . '/api/Sku/UpdateEnable'.$urlAdditional;

        $header = array(
            'Authorization: Bearer ' . $this->accessToken,
            'Content-Type: application/json'
        );

        $param = array(
            "keyAPI"     => $this->keyAccess,
            "idClient"   => $this->idClient,
            "codeStore"  => $productID,
        );
        $param = json_encode($param);

        $data = $this->callAPI($url, 'PUT', $param, $header);

        return $data;
    }

    // Order
    public function getOrder($orderId)
    {
        $this->getAccess();
        $param = array();
        $url = $this->API_DOMAIN . '/api/Order/Code';
        $order_data = $this->callAPI($url, 'GET', $param);

        if (!$order_data) {
            throw new exception($this->error);
        }

        return $order_data;
    }

    public function getOrders($data = array(), $pageNumber = 1, $rowsPerPage = 20)
    {
        $this->getAccess();
        $header = array(
            'Authorization: Bearer ' . $this->accessToken
        );
        $url = $this->API_DOMAIN . '/api/Order?keyApi=' . $this->keyAccess . '&idClient=' . $this->idClient . '&statusId=' . $data['statusId'] . '&pageNumber=' . $pageNumber . '&rowsPerPage=' . $rowsPerPage;
        $metodo = 'GET';
        $order_data = $this->callAPI($url, $metodo, false, $header);

        if (isset($order_data)) {
          if ($order_data->sucess) {
            foreach ($order_data->data as $key => $value) {
              $this->marketplace->logArray[] = array('tipoEnviado' => Type_LogEnviado::Tp_LogRecebido, 'tipoIntegracao' => Type_MarketPlace::Tp_Galeriapage,
                'origem' => __METHOD__, 'tipoLog' => Type_Log::Tp_LogPedido, 'tipoId' => Type_LogId::Tp_LogIdMktPedido, 'entidadeId' => $value->code,
                'url' => $url, 'metodo' => $metodo, 'httpCode' => $this->httpcode, 'retorno' => $value, 'dataHora' => $this->db->dataAtual());
            }
          }
          return $order_data;
        } else {
            return $this->error;
        }
    }

    public function orderJsonToObject($jsonOrder)
    {
        $this->load->helper('ftr_validacao');
        $buyer = new MktBuyer();
        $buyerSendAdd = new MktAddress();
        $pedido = new MktPedido();

        if (ftr_validacao::isCpf($jsonOrder->user->documentNumber)) {
            $tipo_doc = Type_Pessoa::TpPess_fisica;
        } elseif (ftr_validacao::isCnpj($jsonOrder->user->documentNumber)) {
            $tipo_doc = Type_Pessoa::TpPess_Juridica;
        } else {
            $tipo_doc = Type_Pessoa::TpPess_naoInformado;
        }

        $splitName = explode(' ', $jsonOrder->user->name);
        $firstname = $splitName[0];

        if (isset($splitName[1])) {
            $lastName = substr($jsonOrder->user->name, strlen($firstname) + 1, strlen($jsonOrder->user->name) - strlen($firstname) + 1);
        } else {
            $lastName = '';
        }

        $phone   = "";
        $celular = "";

        if (isset($jsonOrder->user->phone)) {
            $phoneNumber = $jsonOrder->user->phone;
            $phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);

            if (strlen($phoneNumber) <= 10) {
                $phone = $phoneNumber;
            } else {
                $celular = $phoneNumber;
            }
        }

        $gender = null;
        if (strtoupper($jsonOrder->user->gender) == "M") {
            $gender = Type_Genero::TpGen_Masc;
        } elseif (strtoupper($jsonOrder->user->gender) == "F") {
            $gender = Type_Genero::TpGen_Fem;
        }

        $buyer
            ->setEmail($jsonOrder->user->email)
            ->setDocumento($jsonOrder->user->documentNumber)
            ->setTipoPessoa($tipo_doc)
            ->setFirstName($firstname)
            ->setLastName($lastName)
            ->setGenero($gender)
            ->setPhone($phone)
            ->setCelular($celular);

        $dataNasc = DateTime::createFromFormat('Y-m-d\TH:i:s', $jsonOrder->user->birthday);

        if (!is_null($jsonOrder->user->birthday)) {
            $buyer->setDateBirth($dataNasc);
        }

        $buyerSendAdd
            ->setUf($jsonOrder->orderAddress->uf)
            ->setPostCode($jsonOrder->orderAddress->zipCode)
            ->setPais('BR')
            ->setBairro($jsonOrder->orderAddress->neighborhood)
            ->setCidade($jsonOrder->orderAddress->city)
            ->setComplemento($jsonOrder->orderAddress->complement)
            ->setLogradouroTipo('')
            ->setLogradouro($jsonOrder->orderAddress->address);

        //se tiver virgula ele tira e trata igual era antes.
        $addressNumber = $jsonOrder->orderAddress->number;
        if(strpos($addressNumber, ',') !== false){
            $addressNumber = str_replace(',','', $addressNumber);
        }

        if (is_numeric($addressNumber)) {
            $buyerSendAdd->setNumero($addressNumber);
        } else if (strtoupper($addressNumber) == 'S/N') {
            $buyerSendAdd->setNumero(0);
        } else {
            $complemento = substr($jsonOrder->orderAddress->number . ' ' . $jsonOrder->orderAddress->complement, 0, 60);

            $buyerSendAdd
                ->setNumero(0)
                ->setComplemento($complemento);
        }

        $buyer->setSendAddress($buyerSendAdd);
        $buyer->setBillingAddress($buyerSendAdd);

        $acrescimo = 0;
        if (property_exists($jsonOrder, 'interest')) {
            $acrescimo = $jsonOrder->interest;
        }

        $discount = 0;
        if (property_exists($jsonOrder, 'discount')) {
            $discount = $jsonOrder->discount;
        }

        $pedido
            ->setMktId($jsonOrder->code)
            ->setDateCreated($jsonOrder->createdAt)
            ->setShippingCost($jsonOrder->freight)
            ->setShippingName($jsonOrder->carrier)
            ->setmktIntegration(Type_MarketPlace::Tp_Galeriapage)
            ->setMkTipo(Type_MarketplaceInt::Tp_GaleriaPage)
            ->setAddressCombinar(false)
            ->setAcres($acrescimo)
            ->setDiscount($discount)
            ->setBuyer($buyer)
            ->setParam('status', $jsonOrder->statusId);

        $subTotal = 0;
        foreach ($jsonOrder->orderItem as $item) {
            $itemObj = new MktPedidoItem();

            $variation = null;

            $itemObj
                ->setMktId($item->skuId)
                ->setPrice($item->value)
                ->setProductName($item->name)
                ->setQuantity($item->quantity)
                ->setMktVariationId($variation)
                ->setMktIdOrderItem($item->id);

            $pedido->addItens($itemObj);
            $subTotal += ($item->value * $item->quantity);
        }

        $pedido
            ->setSubTotal($subTotal);

        return $pedido;
    }

    public function updateOrderStatus($orderID, $status, $data = array())
    {
        $this->getAccess();
        $header = array(
            'Authorization: Bearer ' . $this->accessToken,
            'Content-Type: application/json'
        );
        $url = $this->API_DOMAIN . '/api/Order/' . $status;
        $metodo = 'PUT';

        $param = array(
            "code"     => $orderID,
            "idClient" => $this->idClient,
            "keyAPI"   => $this->keyAccess,
        );

        if ($status == TypeGaleriaPageOrder_ApiStatus::Tp_invoiced) {
            $param['nfiscal'] = $data['numero_nfe'] ?? '';
            $param['keyNumber'] = $data['keyNumber'] ?? '';
        }

        if ($status == TypeGaleriaPageOrder_ApiStatus::Tp_sent) {
            $param['trackingNumber'] = $data['tracking_code'] ?? '';
            $param['trackingUrl'] = $data['tracking_url'] ?? '';
        }

        $param = json_encode($param);

        $retorno = $this->callAPI($url, $metodo, $param, $header);

        $this->marketplace->logArray[] = array('tipoEnviado' => Type_LogEnviado::Tp_LogEnviado, 'tipoIntegracao' => Type_MarketPlace::Tp_Galeriapage,
          'origem' => __METHOD__, 'tipoLog' => Type_Log::Tp_LogPedido, 'tipoId' => Type_LogId::Tp_LogIdMktPedido, 'entidadeId' => $orderID,
          'url' => $url, 'metodo' => $metodo, 'httpCode' => $this->httpcode, 'retorno' => ($this->error) ? $this->error : $retorno, 'enviado' => $param, 'dataHora' => $this->db->dataAtual());

        if ($this->error){
            return $this->error;
        } else {
            return $retorno;
        }
    }

    // Categorias
    public function getAllDepartments($pageNumber = 1, $rowsPerPage = 1000)
    {
      $dep_data = $this->cache->get('page_get_department');

      if (!$dep_data) {
        $this->getAccess();
        $url = $this->API_DOMAIN . "/api/Categorization/Department/All?keyAPI=" . $this->keyAccess . "&idClient=" . $this->idClient . "&pageNumber=" . $pageNumber . "&rowsPerPage=" . $rowsPerPage;

        $dep_data = $this->callAPI($url, 'GET');

        $this->cache->set('page_get_department', $dep_data, 2592000 /* valor em segundos(30 dias) */);
      }

      return $dep_data;
    }

    public function getCategoriesByDeptId($department_id)
    {
      $cat_data = $this->cache->get('page_get_category.' . $department_id);

      if (!$cat_data) {
        $this->getAccess();
        $url = $this->API_DOMAIN . "/api/Categorization/Category/Get?keyAPI=" . $this->keyAccess . "&idClient=" . $this->idClient . "&deptoId=" . $department_id;

        $cat_data = $this->callAPI($url, 'GET');

        $this->cache->set('page_get_category.' . $department_id, $cat_data, 2592000 /* valor em segundos(30 dias) */);
      }

      return $cat_data;
    }

  public function getSubCategoriesByCatId($category_id)
  {
    $subcat_data = $this->cache->get('page_get_subcategory.' . $category_id);

    if (!$subcat_data) {
      $this->getAccess();
      $url = $this->API_DOMAIN . "/api/Categorization/SubCategory/Get?keyAPI=" . $this->keyAccess . "&idClient=" . $this->idClient . "&idCategory=" . $category_id;

      $subcat_data = $this->callAPI($url, 'GET');

      $this->cache->set('page_get_subcategory.' . $category_id, $subcat_data, 2592000 /* valor em segundos(30 dias) */);
    }

    return $subcat_data;
  }
}
