<?php
/**
 * Created by PhpStorm.
 * User: steven
 * Date: 7/29/19
 * Time: 9:46 AM
 */

namespace Hilco\RateShopHelper;


use Hilco\GuzzleWrappers\APIGuzzleWrapper;
use Hilco\XMLBuilder\RateShopUtility;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use RocketShipIt\Rate;
use RocketShipIt\TimeInTransit;

class RateShop_v2
{
    function getHandlingFee() {
        return config('processweaver.handling_fee');
    }

    function rateShopUSAWithAccount($carrierCodes, $weight, $volume, $toState, $toCode, $fromCode, $rates)
    {
        $data = [];
        $dbResult = DB::connection()
            ->table('RateShopAPIDetails')
            ->join('Carriers', 'Carriers.carrier_code', '=', 'RateShopAPIDetails.hilco_carrier_code')
            ->whereIn('RateShopAPIDetails.hilco_carrier_code', $carrierCodes)
            ->select(['RateShopAPIDetails.*', 'Carriers.carrier_desc'])
            ->get();
        $dbResult = json_decode(json_encode($dbResult), true);
        foreach ($dbResult as $row) {
            $data[$row['api_carrier']][$row['residential']][] = $row;
        }


        $returnData = $this->rateShopUSAWithData($data, $weight, $volume, $toCode, $fromCode, $rates);

        foreach ($returnData as $hilco_carrier_code => $data) {
            if (isset($data['rate'])) {
                $returnData[$hilco_carrier_code]['rate'] += self::getHandlingFee();
            }
        }
        return $returnData;
    }

    function retrieveRateShopAPIDetailsForGroupCode($hilcoCarrierGroupCode, $eligibleMethods = null){
        $data = [];

        $dbResult = DB::connection()
            ->table('RateShopAPIDetails')
            ->join('RateShopGroups', 'RateShopAPIDetails.delivery_method', '=', 'RateShopGroups.delivery_method')
            ->join('DeliveryMethods', 'DeliveryMethods.delivery_method_code', '=', 'RateShopAPIDetails.delivery_method')
            ->where('group_code', '=', $hilcoCarrierGroupCode);

        if(!is_null($eligibleMethods)){
            $dbResult = $dbResult->orWhereIn('RateShopAPIDetails.delivery_method', $eligibleMethods);
        }

        $dbResult = $dbResult->groupBy('RateShopAPIDetails.deliverymethod_id', 'RateShopAPIDetails.transit_code')  //TODO: Undo this past the demo stage when we figure out how rate shop codes should be retrieved.
            ->select(['RateShopAPIDetails.*', 'DeliveryMethods.description'])
            ->get();
        $dbResult = json_decode(json_encode($dbResult), true);
        foreach ($dbResult as $row) {
            $data[$row['api_carrier']][$row['residential']][] = $row;
        }

        return $data;
    }

    function rateShopUSA($hilcoCarrierGroupCode, $weight, $volume, $toCode, $fromCode)
    {
        $data = [];
        $dbResult = DB::connection()
            ->table('RateShopAPIDetails')
            ->join('RateShopGroups', 'RateShopAPIDetails.delivery_method', '=', 'RateShopGroups.delivery_method')
            ->join('DeliveryMethods', 'DeliveryMethods.delivery_method_code', '=', 'RateShopAPIDetails.delivery_method')
            ->where('group_code', '=', $hilcoCarrierGroupCode)
            ->select(['RateShopAPIDetails.*', 'DeliveryMethods.description'])
            ->get();
        $dbResult = json_decode(json_encode($dbResult), true);
        foreach ($dbResult as $row) {
            $data[$row['api_carrier']][$row['residential']][] = $row;
        }

        $returnData = RateShop_v2::rateShopUSAWithData($data, $weight, $volume, $toCode, $fromCode);
        foreach ($returnData as $hilco_carrier_code=>$data) {
            if (isset($data['rate'])) {
                $returnData[$hilco_carrier_code]['rate'] += self::getHandlingFee();
            }
        }

        return $returnData;
    }
    public function mapToCarrierCodes($rates){

    }

    function getRatesByDimensions($weight, $volume, $toCode, $fromCode, $additionalAttributes = []){
        $apiGuzzleWrapper = new APIGuzzleWrapper();
        $response = $apiGuzzleWrapper->get('v4/getRates',  [
            'query' => [
                'weight' => $weight,
                'volume' => $volume,
                'toCode' => $toCode,
                'fromCode' => $fromCode
            ],
            'headers' => ['Accept' => 'application/json']
        ]);
        $jsonRateContents = $response->getBody()->getContents();
        $rates = json_decode($jsonRateContents, true);
        $rates = $rates['details'];
/*        $string = substr($response, strpos($response, "<?xml version=\"1.0\"?>"), strpos($response, '</RateResponse>') + 1);*/
//        $simpleXML = simplexml_load_string($string, "SimpleXMLElement", LIBXML_NOWARNING);
//        $rateShopUtility = new RateShopUtility(['simpleXML' => $simpleXML]);
//        $rates  = $rateShopUtility->getRates();
        return $rates;
    }
    // Now indexes by Delivery Methods.
    function indexRatesByCarrierCodes($rates, $data){
        $carrierCodeRateArray = [];
        $carrierTransitCodeArray = [];
        // Create an array indexed by carrier-transit to match.
        // Also api_code = transit_code for some reason
        foreach($rates as $rate){
            $rateType = Arr::get($rate, 'rate_type', false);
            if ($rateType && $rateType !== "CONTRACT_RATES") continue; // if rate obj has rate_type then only add the rate info if rate_type is contract
            $rate['rate'] += self::getHandlingFee(); // add Hilco handling fee before returning
            $rate['discounted_rate'] += self::getHandlingFee(); // add Hilco handling fee before returning
            $carrierName = $rate['carrier_name'];
            $apiCode = $rate['api_code'];
            $deliveryDateTime = $rate['delivery_datetime'];
            if (is_null($deliveryDateTime) || $deliveryDateTime == '') {
                $rate['delivery_datetime'] = '0000-00-00T00:00:00';
            }
            if(!isset($carrierTransitCodeArray[$carrierName])){
                $carrierTransitCodeArray[$carrierName] = [
                    $apiCode => $rate
                ];
            }else{
                $carrierTransitCodeArray[$carrierName][$apiCode] = $rate;
            }
        }
        foreach($data as $apiCarrier => $array1){
            foreach($array1 as $residential => $carrierCodeArray){
                foreach($carrierCodeArray as $carrierCode){
                    $apiCarrier = $carrierCode['api_carrier'];
                    $apiCode = $carrierCode['api_code'];
                    if(in_array($apiCarrier, array_keys($carrierTransitCodeArray))){
                        $carrierRateArray = $carrierTransitCodeArray[$apiCarrier];
                        if(in_array($apiCode, array_keys($carrierRateArray))){
                            $rate = $carrierRateArray[$apiCode];
                            $rate['delivery_method'] = $carrierCode['delivery_method'];
                            $carrierCodeRateArray[$carrierCode['delivery_method']] = $rate;
                        }
                    }
                }
            }
        }

//        $newCarrierCodeRateArray = $this->convertDateTimeToDateAndTime($carrierCodeRateArray);
//        dd($newCarrierCodeRateArray);

        // For each delivery_datetime stamp, get delivery_dates
        return $carrierCodeRateArray;
    }

//    public function convertDateTimeToDateAndTime($carrierCodeRateArray){
//        $newCarrierCodeRateArray = [];
//        foreach($carrierCodeRateArray as $carrierCode => $carrierCodeRate){
//            $delivery_datetime = $carrierCodeRate['delivery_datetime'];
//            $delivery_date = date('d-m-Y', $delivery_datetime);
//            $delivery_time = date('Gi.s', $delivery_datetime);
//            $carrierCodeRate['delivery_date'] = $delivery_date;
//            $carrierCodeRate['delivery_time'] = $delivery_time;
//            $newCarrierCodeRateArray[$carrierCode] = $carrierCodeRate;
//        }
//        return $newCarrierCodeRateArray;
//
//    }



    function rateShopUSAWithData($data, $weight, $volume, $toCode, $fromCode, $rates) {
//        $rates = $this->getRatesByDimensions($weight, $volume, $toCode, $fromCode);
        $returnData = $this->indexRatesByCarrierCodes($rates, $data);

        return $returnData;
    }
}