<?php
namespace App\Library;
use App\Core\Service\Logger;
use App\Service\Api;

class Delhivery  
{   
    private $api = null;
    private $pincode_servicability_url;
    private $token;
    private $customer_id;
    private $login_id;
    private $api_create_awbno_url;
    public function __construct(Array $settings) {
        $this->api = new Api();
        $this->customer_id = !empty($settings['customer_id']) ? $settings['customer_id'] : '';
        $this->login_id = !empty($settings['login_id']) ? $settings['login_id'] : '';
        $this->token = !empty($settings['token']) ? $settings['token'] : '';
        $this->pincode_servicability_url = !empty($settings['pincode_servicability_url']) ? $settings['pincode_servicability_url'] : '';
        $this->api_create_awbno_url = !empty($settings['api_create_awbno_url']) ? trim($settings['api_create_awbno_url']) : '';
    }

    private function checkConfiguration() {
        try {
            if(empty($this->token)) {
                throw new \Exception("Delhivery configuration is incomplete. Provide all required settings.(token, pincode_servicability_url and so on.)");
            }
            return true;
        } catch(\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line'=>$e->getLine()]);
            return false;
        }
    }

    public function checkPincodeServiceability(String $pincode) {
        try {
            if(!$this->checkConfiguration()) {
                throw new \Exception("Delhivery configuration is incomplete. Provide all required settings.(token, pincode_servicability_url and so on.)");
            }
            if(empty($this->pincode_servicability_url)) {
                throw new \Exception("Pincode serviceability URL is not configured");
            }
            if(empty($pincode)) {
                throw new \Exception("Pincode cannot be empty");
            }

            $url = $this->pincode_servicability_url . "?token=" . $this->token . "&filter_codes=" . $pincode;
            $callrs = $this->api->call(trim($url), 'GET', [], '');
            if(empty($callrs['status'])) {
                throw new \Exception($callrs['error']);
            }
            if(empty($callrs['data'])) {
                throw new \Exception("No response from BlueDart check pincode serviceability API");
            }
            $response = json_decode($callrs['data'], true);
            if (!empty($response['delivery_codes'])) {
                return array('status' => true, 'serviceable' => true);
            } else {
                return array('status' => true, 'serviceable' => false);
            }
        } catch(\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line'=>$e->getLine()]);
            return array('status' => false, 'error' => $e->getMessage());
        }
    }

    function createDocketNo($order, $item, $data) {
        try {
            $resp = $this->prepareDataForDocketNo($order, $item, $data);
            if(empty($resp['status'])) {
                return ["status"=>false, "error"=>$resp['error']];
            }
            $payload = 'format=json&data=' . json_encode($resp['data']);
            $headers = [
                "Accept: */*", 
                "Content-Type: application/json", 
                "cache-control: no-cache",
                "authorization: Token ".$this->customer_id, 
            ];

            $callrs = $this->api->call($this->api_create_awbno_url, 'POST', $headers, $payload);
            if(empty($callrs['status'])) {
                throw new \Exception($callrs['error']);
            }
            if(empty($callrs['data'])) {
                throw new \Exception("No response from Delhivery Create Docket No. API");
            }
            $response = json_decode($callrs['data'], true);
            $doketNo = '';
            $message = '';
            if(!empty($response['success'])) {
                if(!empty($response['packages'])) {
                    if(!is_array($response['packages'])) {
                        if(!empty($response['packages'][0]['status']) && strtolower($response['packages'][0]['status']) == 'success'){
                            $doketNo = $response['packages'][0]['waybill'];
                        } else {
                            $message = isset($response['packages'][0]['remarks'][0]) ? ($response['packages'][0]['remarks'][0]) : '';
                        }
                    }
                }
            }
            if (empty($doketNo)) {
                return array('success' => FALSE, 'message' => $message . $response, 'data' => null);
            }
            return array('status' => true, 'data' => $doketNo);
        } catch(\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line'=>$e->getLine()]);
            return ["status"=>false, "error"=>$e->getMessage()];
        }
    }

    private function prepareDataForDocketNo($order, $item, $data) {
        try {
            $dt = [
                'pickup_location'=> [],
                'shipments'=>[]
            ];
            $dt['pickup_location']['pin'] = $order['branch_pincode'];
            $dt['pickup_location']['add'] = $order['branch_branch_address'];
            $dt['pickup_location']['phone'] = $order['phone'];
            $dt['pickup_location']['state'] = $order['branch_state_name'];
            $dt['pickup_location']['city'] = $order['branch_city_name'];
            $dt['pickup_location']['country'] = "India";
            $dt['pickup_location']['name'] = $this->login_id;

            $shipment['return_name'] = $order['company_name'];
            $shipment['return_pin'] = $order['branch_pincode'];
            $shipment['return_city'] = $order['branch_city_name'];
            $shipment['return_phone'] = $order['phone'];
            $shipment['return_add'] = $order['branch_branch_address'];
            $shipment['return_state'] = $order['branch_state_name'];
            $shipment['return_country'] = "India";
            $shipment['order'] = $order['customer_order_id'];
            
            $customer = json_decode($order['customer_detail'], true);
            
            $shipment['phone'] = !empty($customer['mobile_number'])?$customer['mobile_number']:'';
            $shipment['products_desc'] = isset($data['courier_product_name']) ? $data['courier_product_name'] : NULL;
            $shipment['cod_amount'] = sprintf("%.2f", ($data['courier_payment_mode'] == 'p') ? '0.00' : $order['net_amt']);
            $shipment['country'] = "India";

            $shipment['seller_inv_date'] = $data['invoice_date'];
            $shipment['order_date'] = $data['booking_time'];
            $shipment['total_amount'] = $data['net_amt'];

            $shipment['seller_add'] = $data['branch_branch_address'];
            $shipment['seller_cst'] = "";

            $shipment['seller_name'] = "seller name";
            $shipment['seller_inv'] = "15265";
            $shipment['seller_tin'] = "";

            $shipment['name'] = !empty($customer['customer_name'])?$customer['customer_name']:'';
            $shipment['add'] = !empty($order['customer_address_detail']['address'])?$order['customer_address_detail']['address']:'';

            $shipment['pin'] = !empty($order['customer_address_detail']['address_pincode'])?$order['customer_address_detail']['address_pincode']:'';
            $shipment['quantity'] = trim($order['total_item_qty']);
            $shipment['payment_mode'] = $data['courier_payment_mode'] == 'p' ? 'Prepaid' : 'COD';
            $shipment['state'] = !empty($order['customer_address_detail']['address_state_name'])?$order['customer_address_detail']['address_state_name']:'';
            $shipment['city'] = !empty($order['customer_address_detail']['address_city_name'])?$order['customer_address_detail']['address_city_name']:'';
            $shipment['shipping_mode'] = $data['shipping_mode'];

            $dt['shipments'] = array($shipment);
            return ["status"=>true, "data"=>$dt];
        } catch(\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line'=>$e->getLine()]);
            return ["status"=>false, "error"=>$e->getMessage()];
        }    
    }
}