<?php

if (!class_exists( 'Chilexpress_Oficial_API')) {
    
    class Chilexpress_Oficial_API // NOSONAR
    {
        
        
        private function get_local_file_contents( $file_path ) { // NOSONAR
            ob_start();
            include_once $file_path; // NOSONAR
            return ob_get_clean();
        }

        /**
         *
         * @access public
         * @return void
         */
        public function __construct() {
            $this->id  = 'chilexpress_oficial';
            $this->init();
            
            $this->api_staging_base_url = 'https://qaservices.wschilexpress.com/';
            $this->api_production_base_url = 'https://services.wschilexpress.com/';

            $module_options["ambiente"] = Configuration::get('ambiente');
            $module_options["api_key_georeferencia_enabled"] = Configuration::get('api_key_georeferencia_enabled');
            $module_options["api_key_generacion_ot_enabled"] = Configuration::get('api_key_generacion_ot_enabled');

            if ($module_options['ambiente'] == 'production') {
                $this->api_base_url = $this->api_production_base_url;
            } else {
                $this->api_base_url = $this->api_staging_base_url;
            }

            $this->api_key_georeferencia = Configuration::get('api_key_georeferencia_value');
            $this->api_key_cobertura = Configuration::get('api_key_cotizador_value');
            $this->api_key_ot = Configuration::get('api_key_generacion_ot_value');

            $this->api_geo_enabled = false;
            if (isset($module_options['api_key_georeferencia_enabled'])) {
                $this->api_geo_enabled = $module_options['api_key_georeferencia_enabled'];
            }
            $this->api_ot_enabled = false;
            if (isset($module_options['api_key_generacion_ot_enabled'])) {
                $this->api_ot_enabled = $module_options['api_key_generacion_ot_enabled'];
            }

            $this->content_type_json = 'Content-Type: application/json';
            $this->api_key_header = 'Ocp-Apim-Subscription-Key: ';
        }

        /**
         * Validar dia habil
         */
        public function validar_dia_habil(){

            date_default_timezone_set("America/Santiago");
            $date = new DateTime();
            $fecha_actual = $date->format('Y-m-d');

            $data = $this->internalApiCallGET(
                'https://services.wschilexpress.com/agendadigital/api/v4/Utilitarios/DiaHabil?fecha='.$fecha_actual,
                '9c853753ce314c81934c4f966dad7755'
            );
            $respuesta = array();
            foreach ($data["DiaHabil"] as $entry) {
                $respuesta = $entry;
            }
            return $respuesta;
        }

        /**
         * Obtiene Categorias de Art'iculos
         */
        public function obtener_categorias_articulos(){

            $data = $this->internalApiCallGET(
                "https://services.wschilexpress.com/agendadigital/api/v4/Cotizador/GetArticulos",
                "9c853753ce314c81934c4f966dad7755"
            );
            $descripciones = array();
            foreach ($data["ListArticulos"] as $entry) {
                $descripciones[$entry["Codigo"]] = $entry["Glosa"];
            }
            return $descripciones;
        }

        /**
         * Obtiene las regiones de cobertura desde la API de cobertura
         * Si no las encuentra ah'i, entonces utiliza un archivo local de respaldo
         */
        public function obtener_regiones() {
            $url = $this->api_base_url . 'georeference/v2/api/v2.0/regions';
            $regiones = array();
           
            // se pregunta al servicio
            $data = $this->internalApiCallGET( $url, $this->api_key_georeferencia );
            // Si el servicio no responde o es un array sin datos
            if( !isset( $data["regions"] ) || !$data )
            {
                $directory =  dirname( __FILE__ )  . '/data/regiones/' ;
                $file_path = $directory . 'regiones.json';
                if (file_exists($file_path)) {
                    $data = $this->get_local_file_contents( $file_path );
                    $data = json_decode($data, true);
                }
            }
            if ($data) {
                foreach ( $data["regions"] as $region ) 
                {
                    $key = $region['regionId'];
                    $regiones[$key] = $region['regionName'];
                }
            }
            return $regiones;
        }

        /**
         * Ontiene las comunas de cobertura de una regi'on, si no encuentra la respuesta
         * o hay un error en la llamada a la API, se lee el archivo local de comunas
         */
        public function obtener_comunas_desde_region($codigo_region = "R1") {
            $url = $this->api_base_url . 'georeference/v2/api/V1.0/coverage-areas?RegionCode='.$codigo_region.'&type=1';
            $comunas = array();
            // se pregunta al servicio
            $data = $this->internalApiCallGET( $url, $this->api_key_georeferencia );
            if( !isset($data["coverageAreas"]) || !$data )
            {
                $directory =  dirname( __FILE__ )  . '/data/comunas/' ;
                $file_path = $directory . $codigo_region .'.json';
                if (file_exists($file_path)) {
                    $data = $this->get_local_file_contents( $file_path );
                    if($data) {
                        $data = json_decode($data, true);
                    }
                }
            }
            if ($data) {
                foreach ($data["coverageAreas"] as $comuna) 
                {
                    $key = $comuna['countyCode'];
                    $comunas[$key] = $comuna['coverageName'];
                }
            }

            unset($comunas["SCOB"]); // eliminar comuna "Sin Cobertura"
            
            return $comunas;
        }

        public function obtener_cotizacion(
                                            $comuna_origen,
                                            $comuna_destino,
                                            $weight = 1,
                                            $height = 1,
                                            $width = 1,
                                            $depth = 1,
                                            $declaredWorth = 1000
                                        ) {

            $payload = array(
                "originCountyCode"      => $comuna_origen,
                "destinationCountyCode" => $comuna_destino,
                "package" => array(
                    "weight" =>	$weight,
                    "height" =>	$height,
                    "width"  =>	$width,
                    "length" =>	$depth
                ),
                "productType"        => 3,
                "contentType"        => 1,
                "declaredWorth"      => $declaredWorth,
                "deliveryTime"       => Configuration::get('prioridad_servicios'),
                "customerCardNumber" => Configuration::get('numero_tcc_origen')
            );
            
            require_once _PS_MODULE_DIR_ . 'chilexpress_oficial/chilexpress_oficial_utils.php';
			$util = new Chilexpress_Oficial_Utils();
            $util->write_log( '[Cotizacion] Payload: ' . json_encode($payload));
            $md5_payload = md5(json_encode($payload));
			$cached_response = $util->get_cached_cotizacion($md5_payload);
			if ($cached_response) {
				$util->write_log( '[Cotizacion] Respuesta cacheada: '.json_encode($cached_response) );
				return $cached_response;
			}	

            $json_result = $this->internalApiCallPOST(
                    json_encode($payload),
                    "rating/api/v1.0/rates/business",
                    $this->api_key_cobertura
                );
            
                $util->write_log( '[Cotizacion] Respuesta API: ' . json_encode($json_result) );
			$util->set_cached_cotizacion($md5_payload, $json_result);

            return $json_result;
            
        }
        public function obtener_etiqueta(
                                           $trackingId,
                                           $labelType 
                                        ) {
            $payload = array(
				"labelType" => $labelType,
				"transportOrderNumber" => $trackingId
			);

            $json_result = $this->internalApiCallPOST(
                    json_encode($payload),
                    "transport-orders/api/v1.0/transport-orders-labels",
                    $this->api_key_ot
            );
            return $json_result;
        }

        public function generar_ot($payload_str) {
            $json_result = $this->internalApiCallPOST(
                    $payload_str,
                    "transport-orders/api/v1.0/transport-orders",
                    $this->api_key_ot //"5a77a19b76a24297ba01c158286641b7"
                );

            return $json_result;
        }



        public function obtener_estado_ot($trackingId, $reference, $rut ) {
            
            $payload = array(
                "reference"=> $reference,
                "transportOrderNumber"=> $trackingId,
                "rut"=> $rut,
                "showTrackingEvents" => 1
            );
            
            $json_result = $this->internalApiCallPOST(
                    json_encode($payload),
                    "transport-orders/api/v1.0/tracking",
                    $this->api_key_ot
                );

            return $json_result;
        }


        public function cerrar_certificado($payload_str) {

            $json_result = $this->internalApiCallPUT(
                    $payload_str,
                    "transport-orders/api/v1.0/transport-order-certificates",
                    $this->api_key_ot
                );

            return $json_result;
        }

        /**
         * Ejecuta la llamada a un servicio POST
         */
        private function internalApiCallPOST($payload_str, $url_ws, $apiKey) {
            $url_ws = $this->api_base_url.$url_ws;
            $curl = curl_init();
            $headers = array();
            $headers[] = $this->content_type_json;
            $headers[] = $this->api_key_header.$apiKey;
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); // NOSONAR
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // NOSONAR
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_URL, $url_ws);
            curl_setopt($curl, CURLOPT_FAILONERROR, 1);
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $payload_str);

            $result = curl_exec($curl);
            curl_close($curl);

            if (!$result){
                return false;
            } else { 
                $jresult = json_decode($result,true);
                return $jresult;
            }
        }

        /**
         * Ejecuta la ejecuci'on de un servicio GET
         */
        private function internalApiCallGET( $url, $apiKey ) {
            $url_ws = $url;
            $curl = curl_init();
            $headers = array();
            $headers[] = $this->content_type_json;
            $headers[] = $this->api_key_header.$apiKey;
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); // NOSONAR
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // NOSONAR
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_URL, $url_ws);
            curl_setopt($curl, CURLOPT_FAILONERROR, 1);
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

            $result = curl_exec($curl);
            curl_close($curl);

            if (!$result){
                return false;
            } else { 
                $jresult = json_decode( $result, true );
                return $jresult;
            }
        }

        /**
         * Ejecuta la llamada a un servicio PUT
         */
        private function internalApiCallPUT($payload_str, $url_ws, $apiKey) {
            $url_ws = $this->api_base_url.$url_ws;
            $curl = curl_init();
            $headers = array();
            $headers[] = $this->content_type_json;
            $headers[] = $this->api_key_header.$apiKey;
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); // NOSONAR
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // NOSONAR
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_URL, $url_ws);
            curl_setopt($curl, CURLOPT_FAILONERROR, 1);
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $payload_str);

            $result = curl_exec($curl);
            curl_close($curl);

            if (!$result){
                return false;
            } else { 
                $jresult = json_decode($result,true);
                return $jresult;
            }
        }


        /**
         * Init your settings
         *
         * @access public
         * @return void
         */
        public function init() {
            
        }

    }
}
