<?php
if (!defined('ABSPATH')){
    exit; // Exit if accessed directly
}
if ( class_exists('WPCARGO_API') ) :
    class WPCARGO_SHIPPING_RATE_API extends WPCARGO_API {
        //  Register route
        var $wpcargo_namespace      = 'wpcargo/v';
        var $wpcargo_api_version    = '1'; 
        
        public function rate_routes(){
            $namespace = $this->wpcargo_namespace . $this->wpcargo_api_version;
            $base      = 'api';
            // Find Rates
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rates/find/(?P<orig>[a-zA-Z0-9-]+)/(?P<dest>[a-zA-Z0-9-]+)/(?P<wgt>[0-9\.]+)/', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'find_rates' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rates/find/(?P<orig>[a-zA-Z0-9-]+)/(?P<dest>[a-zA-Z0-9-]+)/(?P<wgt>[0-9\.]+)/(?P<pkg>[a-zA-Z0-9-]+)/', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'find_rates' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            // Rate
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rates', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'get_all_rates' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rate/(?P<id>[0-9]+)/', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'get_rate' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            // Locations Route
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rate/locations/', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'get_all_locations' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rate/location/(?P<id>[0-9]+)/', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'get_location' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            // Zones
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rate/zones/', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'get_all_zones' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rate/zone/(?P<id>[0-9]+)/', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'get_zone' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            // Delivery Type
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rate/types', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'get_all_types' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rate/type/(?P<id>[0-9]+)/', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'get_type' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            // Pickup rate
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rate/pickups', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'get_all_pickups' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
            register_rest_route( $namespace, '/' . $base.'/(?P<apikey>[a-zA-Z0-9-]+)/rate/pickup/(?P<id>[0-9]+)/', array(
                array(
                    'methods'               => WP_REST_Server::READABLE,
                    'callback'              => array( $this, 'get_pickup' ),
                    'permission_callback'   => array( $this, 'wpcargo_api_premission' )
                    )
                ) 
            );
        }
        // Register our REST Server
        public function rate_restful_server(){
            add_action( 'rest_api_init', array( $this, 'rate_routes' ) );
        }
        // Route Callbacks
        /* 
         * Find Rates find_rates
         */
        public function find_rates( WP_REST_Request $request ){
            $orig       = $request->get_param( 'orig' );
            $dest       = $request->get_param( 'dest' );
            $pkg        = $request->get_param( 'pkg' );
            $orig       = (int)get_wpcsr_location_by_name($orig);
            $dest       = (int)get_wpcsr_location_by_name($dest);
            $wgt        = number_format( floatval( $request->get_param( 'wgt') ), 3, '.','' );
            $result     = array();
            $has_data   = $this->extract_rate($orig, $dest, $wgt, $pkg );
            if( !empty( $has_data ) ){
                $result = $has_data;
            }
            return $result;
        }
        /* 
         * Rates 
         */
        public function get_all_rates( WP_REST_Request $request ){
            global $wpdb;
            $table_rate  		= $wpdb->prefix.WPCSR_DB_RATE;
            $table_zone  		= $wpdb->prefix.WPCSR_DB_ZONE;
            $table_delivery  	= $wpdb->prefix.WPCSR_DB_DELIVERY;

            $rate_columns 		= $wpdb->get_col("DESC {$table_rate}", 0);
            $q_columns 			= array();
            foreach ( $rate_columns as $column ) {
                $column_name = 'rate.'.$column;
                if( $column == 'zone_id' ){
                    $column_name = 'zone.label AS zone';
                }elseif( $column == 'delivery_id' ){
                    $column_name = 'delivery.title AS delivery';
                }
                $q_columns[] = $column_name;
            }
            $q_columns = implode(', ', $q_columns);
            $sql = "SELECT 
                {$q_columns} 
                FROM `{$table_rate}` AS rate 
                LEFT JOIN {$table_zone} AS zone ON rate.zone_id = zone.zone_id 
                LEFT JOIN {$table_delivery} AS delivery ON rate.zone_id = delivery.id 
            ";
            return $wpdb->get_results( $sql );
        }
        
        public function get_rate( WP_REST_Request $request ){
            $rate_id = (int)$request->get_param( 'id' );
            $result = array();
            $has_data = get_wpcsr_rate_by_id( $rate_id );
            if( !empty( $has_data ) ){
                $result = $has_data;
            }
            return $result;
        }
        /*
         * Location
         */
        public function get_all_locations( WP_REST_Request $request ){
            $result = array();
            $has_data = get_wpcsr_location();
            if( !empty( $has_data ) ){
                $result = $has_data;
            }
            return $result;
        }
        public function get_location( WP_REST_Request $request ){
            $location = (int)$request->get_param( 'id' );
            $result = array();
            $has_data = get_wpcsr_location_by_id( $location );
            if( !empty( $has_data ) ){
                $result = $has_data;
            }
            return $result;
        }
        /*
         * Zones
         */
        public function get_all_zones( WP_REST_Request $request ){
            $result = array();
            $has_data = get_wpcsr_zone();
            if( !empty( $has_data ) ){
                $result = $has_data;
            }
            return $result;
        }
        public function get_zone( WP_REST_Request $request ){
            $zone = (int)$request->get_param( 'id' );
            $result = array();
            $has_data = get_wpcsr_zone_by_id( $zone );
            if( !empty( $has_data ) ){
                $result = $has_data;
            }
            return $result;
        }
        /*
         * Delivery Type
         */
        public function get_all_types( WP_REST_Request $request ){
            $result = array();
            $has_data = get_wpcsr_deliveries( );
            if( !empty( $has_data ) ){
                $result = $has_data;
            }
            return $result;
        }
        public function get_type( WP_REST_Request $request ){
            $type = (int)$request->get_param( 'id' );
            $result = array();
            $has_data = get_wpcsr_delivery_by_id( $type );
            if( !empty( $has_data ) ){
                $result = $has_data;
            }
            return $result;
        }
        /*
         * Pickup Rate 
         */
        public function get_all_pickups( WP_REST_Request $request ){
            $result = array();
            $has_data = get_wpcsr_pickup_rates( );
            if( !empty( $has_data ) ){
                $result = $has_data;
            }
            return $result;
        }
        public function get_pickup( WP_REST_Request $request ){
            $pickup = (int)$request->get_param( 'id' );
            $result = array();
            $has_data = get_wpcsr_pickup_rates_by_id( $pickup );
            if( !empty( $has_data ) ){
                $result = $has_data;
            }
            return $result;
        }
        // Helpers
        private function extract_rate( $orig, $dest, $wgt, $pkg ){
            $rate_container  = array();
            $rates           = wpcsr_find_rates( $orig, $dest, $wgt, $pkg );
            $categorize_rate = get_option('categorize_rate');
            $formatted_rates = array();

            if( $categorize_rate && !empty( $rates ) ){
                foreach ($rates as $arr_rate ) {
                    foreach ($arr_rate as $_rateID) {
                        $formatted_rates[] = $_rateID;
                    }
                }
                $rates = $formatted_rates;
            }

            if( !empty( $rates ) ){
                $counter = 0;
                foreach ( $rates as $rateID ){                    
                    $rate_details = array();
                    $rateInfo 		= get_wpcsr_rate_by_id( $rateID );
                    $deliveryInfo   = get_wpcsr_delivery_by_id($rateInfo->delivery_id);
                    $rate_type      = $rateInfo->rate_type == 0 ? esc_html__('Flat rate', 'wpcargo-shipment-rate' ) : esc_html__('Cost Weight', 'wpcargo-shipment-rate' );
                    $price          = $rateInfo->price;
                    if( $rateInfo->rate_type == 1){
                        $price = (float)$rateInfo->price + ((float)$rateInfo->weight_cost * ($wgt) );
                    }
                    
                    $rate_details['brand'] =  $rateInfo->brand;
                    $rate_details['service'] =  $rateInfo->service;
                    $rate_details['logo_url'] =  $rateInfo->logo_url;
                    $rate_details['description'] =  $rateInfo->description;
                    $rate_details['rate_type'] =  $rate_type;
                    $rate_details['min_weight'] =  $rateInfo->min_weight;
                    $rate_details['max_weight'] =  $rateInfo->max_weight;
                    $rate_details['price'] =  $price;
                    $rate_details['rate_protection'] =  $rateInfo->rate_protection;
                    $rate_details['coverage_protection'] =  $rateInfo->coverage;
                    $rate_details['zone'] =  $rateInfo->zone;
                    $rate_details['type'] =  $deliveryInfo->title;
                    $rate_container[$counter] = $rate_details;
                    $counter++; 
                }
            }

            if( empty( $rate_container ) ){
                return wp_send_json ( array(
                    'status' => '404',
                    'message' => 'No available rates found for the query.'
                ) );
            }
            return wp_send_json($rate_container);
        }
    }
    
    $wpcargoShippingRateAPI = new WPCARGO_SHIPPING_RATE_API();
    $wpcargoShippingRateAPI->rate_restful_server();
endif;