<?php
if (version_compare(_PS_VERSION_, '1.7.0.0', '>=')) {
    include_once(dirname(__FILE__) . '/../../../../../config/config.inc.php');
    include_once(dirname(__FILE__) . '/../../../../../init.php');
}else
{
    define('PS_MBE_DIR', getcwd());

    include_once(dirname(__FILE__) . '/../../../../../config/config.inc.php');
    //include_once(dirname(__FILE__) . '/../../../../../init.php');
}

class Mbe_Shipping_Helper_Order
{
    public function addShipping($order, $service)
    {
        $errors = array();
        $helper = new Mbe_Shipping_Helper_Data();
        $logger = new Mbe_Shipping_Helper_Logger();

        $insurance = $helper->isShippingWithInsurance($service);
        if ($insurance) {
            $service = $helper->convertShippingCodeWithoutInsurance($service);
        }

        $isCod = false;
        if (version_compare(_PS_VERSION_, '1.5', '<')) {
            $orderTotal = $order->total_paid;
        }
        else {
            $orderTotal = $order->getTotalPaid();
        }

        $cashOnDeliveryModuleName = $helper->getCashOnDeliveryModuleName();
        if ($order->module == $cashOnDeliveryModuleName) {
            $isCod = true;
        }

        $shipmentConfigurationMode = $helper->getShipmentConfigurationMode();

        if ($shipmentConfigurationMode == Mbe_Shipping_Helper_Rates::SHIPMENT_CONFIGURATION_MODE_ONE_SHIPMENT_PER_ITEM) {

            $productsAmount = 0;
            foreach ($order->getProducts() as $item) {
                $productsAmount += $item['product_quantity'];
            }

            $codValue = $orderTotal / $productsAmount;

            foreach ($order->getProducts() as $item) {

                if (version_compare(_PS_VERSION_, '1.5', '<')) {
                    $itemWeight = $item['product_weight'];
                }
                else {
                    $itemWeight = $item['weight'];
                }
                $itemWeight = $helper->convertWeight($itemWeight);

                $boxesDimensionWeight = [];
                $boxesSingleParcelDimensionWeight = [];

                // Retrieve the product info using the new box structure
                $helper->getBoxesArray(
                    $boxesDimensionWeight,
                    $boxesSingleParcelDimensionWeight,
                    $itemWeight,
                    $helper->getPackageInfo($item['reference'])
                );

                $products = array();
                $product = new stdClass;
                $product->SKUCode = $item["product_reference"];
                $product->Description = $item["product_name"];
                $product->Quantity = 1;
                $product->Price = $item['product_price'];
                array_push($products, $product);

                //TODO: use the correct price with or without taxes
                $goodsValue = $item["product_price"];

                if (Configuration::get('mbe_shipments_ins_mode') == Mbe_Shipping_Helper_Data::MBE_INSURANCE_WITH_TAXES) {
                    $insuranceValue = $item["product_price_wt"];
                }
                else {
                    $insuranceValue = $item["product_price"];
                }

                for ($i = 1; $i <= $item['product_quantity']; $i++) {
                    $logger->logDebug($item['product_price'], "Goods Value");
                    $errors = $this->createSingleShipment($order, $service, $boxesDimensionWeight, $products, 1, array(), $goodsValue, $isCod, $codValue, $insurance, $insuranceValue);
                }
            }
        }
        elseif ($shipmentConfigurationMode == Mbe_Shipping_Helper_Rates::SHIPMENT_CONFIGURATION_MODE_ONE_SHIPMENT_PER_SHOPPING_CART_SINGLE_PARCEL) {
            $boxesDimensionWeight = [];
            $boxesSingleParcelDimensionWeight = [];

            $boxesWeights = array();
            $products = array();
            $goodsValue = 0.0;
            $insuranceValue = 0.0;
            $codValue = $orderTotal;
            foreach ($order->getProducts() as $item) {
                $product = new stdClass;
                $product->SKUCode = $item["product_reference"];
                $product->Description = $item["product_name"];
                $product->Quantity = $item["product_quantity"];
                $product->Price = $item['product_price'];
                array_push($products, $product);

                $itemQty = $item['product_quantity'];
                for ($i = 1; $i <= $itemQty; $i++) {
                        $packageInfo =  $helper->getPackageInfo($item['reference']);
                        $boxesDimensionWeight = $helper->getBoxesArray(
                            $boxesDimensionWeight,
                            $boxesSingleParcelDimensionWeight,
                            $helper->convertWeight($item['weight']),
                            $packageInfo
                        );
                }
                $goodsValue += $item['total_price'];
                $insuranceValue += $this->getSubtotalForInsurance($item);
            }
            $boxesDimensionWeight = $helper->mergeBoxesArray(
                $boxesDimensionWeight,
                $boxesSingleParcelDimensionWeight
            );

            $numBoxes = $helper->countBoxesArray($boxesDimensionWeight);
            $logger->logDebug($numBoxes, "boxes amount");
            $logger->logDebug($boxesWeights, "boxes weights");
            $errors = $this->createSingleShipment($order, $service, $boxesDimensionWeight, $products, $numBoxes, array(), $goodsValue, $isCod, $codValue, $insurance, $insuranceValue);
        }
        elseif ($shipmentConfigurationMode == Mbe_Shipping_Helper_Rates::SHIPMENT_CONFIGURATION_MODE_ONE_SHIPMENT_PER_SHOPPING_CART_MULTI_PARCEL) {
            $boxesWeights = array();
            $products = array();
            $numBoxes = 0;
            $goodsValue = 0.0;
            $insuranceValue = 0.0;
            $codValue = $orderTotal;
            foreach ($order->getProducts() as $item) {
                $product = new stdClass;
                $product->SKUCode = $item["product_reference"];
                $product->Description = $item["product_name"];
                $product->Quantity = $item["product_quantity"];
                $product->Price = $item['product_price'];
                array_push($products, $product);

                $insuranceValue += $this->getSubtotalForInsurance($item);
                $goodsValue += $item['total_price'];

                $numBoxes += $item['product_quantity'];
                for ($i = 1; $i <= $item['product_quantity']; $i++) {
                    $helper->getBoxesArray(
                        $boxesDimensionWeight,
                        $boxesSingleParcelDimensionWeight,
                        $helper->convertWeight($item['weight']),
                        $helper->getPackageInfo($item['reference'], true)
                    );
                }
            }
            $logger->logDebug($numBoxes, "boxes amount");
            $logger->logDebug($boxesWeights, "boxes weights");
            $errors = $this->createSingleShipment($order, $service, $boxesSingleParcelDimensionWeight, $products, $numBoxes, array(), $goodsValue, $isCod, $codValue, $insurance, $insuranceValue);
        }
        return $errors;
    }

    public function createSingleShipment($order, $service, $weight, $products, $boxes, $qty = array(), $goodsValue = 0.0, $isCod = false, $codValue = 0.0, $insurance, $insuranceValue)
    {
        $errors = array();
        $logger = new Mbe_Shipping_Helper_Logger();

        try {
            $ws = new Mbe_Shipping_Model_Ws();

            $shippingAddress = new Address((int)$order->id_address_delivery);
            $notes = $order->getFirstMessage();
            if ($notes) {
                $notes .= " ";
            }
            $notes .= $shippingAddress->other;

            $firstName = $shippingAddress->firstname;
            $lastName = $shippingAddress->lastname;
            $companyName = $shippingAddress->company;
            $addressArray = array($shippingAddress->address1, $shippingAddress->address2);
            $address = implode(" ", $addressArray);
            $phone = strlen($shippingAddress->phone) > 0 ? $shippingAddress->phone : $shippingAddress->phone_mobile;
            $city = $shippingAddress->city;
            $country = new Country(intval($shippingAddress->id_country));;
            $countryId = $country->iso_code;
            $uap=false;
            $uapID=-1;
            if($shippingAddress->other==='UAP')
            {
                $uap=true;
                $uapID = explode("-", $shippingAddress->alias)[1];
            }

            $region = $shippingAddress->id_state;
            if ($region == 0) {
                $region = null;
            }
            else {
                $state = new State(intval($shippingAddress->id_state));;
                $region = $state->iso_code;
            }

            $postCode = $shippingAddress->postcode;
            $customer = new Customer($shippingAddress->id_customer);
            $email = $customer->email;

            if (version_compare(_PS_VERSION_, '1.5', '<')) {
                $reference = $order->id;
            }
            else {
                $reference = $order->reference;
            }

            $mbeShipment = $ws->createShipping($countryId, $region, $postCode, $weight, $boxes, $products, $service, $notes, $firstName, $lastName, $companyName, $address, $phone, $city, $email, $goodsValue, $reference, $isCod, $codValue, $insurance, $insuranceValue, $uap, $uapID);
            $logger->logDebug("MBE SHIPMENT", $mbeShipment);

            if ($mbeShipment) {
                $trackingNumber = $mbeShipment->MasterTrackingMBE;
                $fileName = $this->getFilename($order, $trackingNumber);
                $label = $mbeShipment->Labels->Label;

                if (is_array($label)) {
                    $i = 1;
                    foreach ($label as $l) {
                        $this->saveShipmentDocument($l->Type, $l->Stream, $fileName . '_' . $i);
                        $i++;
                    }
                }
                else {
                    $this->saveShipmentDocument($label->Type, $label->Stream, $fileName);
                }


                $this->setWsShippingNumber($order, $trackingNumber);

                $shipperType = $ws->getShipperType();
                if ($shipperType==="COURIERLDV") {
                    $this->setOrderShipped($order);
                }
            }
            else {
                //$order->_errors[] = Tools::displayError('Error creating tracking number.');
                $errors[] = 'Error creating tracking number.';
            }

        }
        catch (Exception $e) {
            $logger->logDebug($e->getMessage());
        }
        return $errors;
    }

    public function saveShipmentDocument($type, $content, $filename)
    {
        $helper = new Mbe_Shipping_Helper_Data();
        $logger = new Mbe_Shipping_Helper_Logger();

        $ext = "txt";
        if ($type == "HTML") {
            $ext = "html";
        }
        elseif ($type == "PDF") {
            $ext = "pdf";
        }
        elseif ($type == "GIF") {
            $ext = "gif";
        }
        $filePath = $helper->getShipmentFilePath($filename, $ext);

        $saveResult = file_put_contents($filePath, $content);

        $message = "Saving shipping document :" . $filePath;

        if ($saveResult) {
            $message .= " OK";
        }
        else {
            $message .= " FAILURE";
        }

        $logger->logDebug($message);
    }

    public function getFileName($order, $trackingNumber)
    {
        return 'MBE_' . $order->id . '_' . $trackingNumber;
    }

    public function setWsShippingNumber($order, $shipping_number)
    {
        $id_order_carrier = Db::getInstance()->getValue('
			SELECT `id_order_carrier`
			FROM `' . _DB_PREFIX_ . 'order_carrier`
			WHERE `id_order` = ' . (int)$order->id);
        if ($id_order_carrier) {
            $order_carrier = new OrderCarrier($id_order_carrier);
            $old = $order_carrier->tracking_number;
            if ($old) {
                $order_carrier->tracking_number = trim($old . Mbe_Shipping_Helper_Data::MBE_SHIPPING_TRACKING_SEPARATOR . $shipping_number);
            }
            else {
                $order_carrier->tracking_number = trim($shipping_number);
            }
            $order_carrier->update();
        }
        else {
            $old = $order->shipping_number;
            if ($old) {
                $order->shipping_number = trim($old . Mbe_Shipping_Helper_Data::MBE_SHIPPING_TRACKING_SEPARATOR . $shipping_number);
            }
            else {
                $order->shipping_number = trim($shipping_number);
            }
            $order->update();
        }
        return true;
    }

    public static function getCarrierName($value)
    {
        $carrier = new Carrier($value);
        return $carrier->name;
    }

    public static function checkClose($value)
    {
        $helper = new Mbe_Shipping_Helper_Data();
        return $helper->isShippingOpen($value) ? 'Opened' : 'Closed';
    }

    public static function printPDFIconsButton($id_order, $tr)
    {
        $order = new Order($id_order);
        $orderState = OrderHistory::getLastOrderState($id_order);
        if (!Validate::isLoadedObject($orderState) OR !Validate::isLoadedObject($order)) {
            echo '&nbsp;';
            return false;
        }
        echo '<span style="width:20px; margin-right:5px;">';
        if ($order->shipping_number && str_replace(' ', '', $order->shipping_number) != '') {
            $shipLink = 'index.php?tab=AdminMbeShipping&submitAction=generateDelivery&id_order=' . $order->id;
            echo '<a target="_blank" href="' . $shipLink . '"><img src="../img/admin/delivery.gif" alt="delivery" /></a>';
        }
        echo '</span>';

        $ws = new Mbe_Shipping_Model_Ws();
        $mustClose = $ws->mustCloseShipments();
        if ($mustClose) {
            $helper = new Mbe_Shipping_Helper_Data();

            if (ltrim($order->shipping_number) != '') {
                $arr = explode(' ', ltrim($order->shipping_number));
                $t = end($arr);
                if (!$helper->isShippingOpen($id_order)) {
                    if ($helper->getTrackingStatus($t)) {
                        $href = __PS_BASE_URI__ . 'modules/mbeshipping/pdf.php?files[]=' . $helper->getTrackingFilePath($t);
                        echo '<span style="width:20px;">';
                        echo '<a target="_blank" href="' . $href . '"><img src="../img/admin/tab-invoice.gif" alt="delivery" /></a>';
                        echo '</span>';
                    }
                }
            }
        }
    }

    public function setOrderShipped($order)
    {
        try {
            $helper = new Mbe_Shipping_Helper_Data();
            if ($helper->getAutoChangeOrderStatus()) {
                //Cambio lo stato solo se l'ordine è nello stato pagamento accettato (2)
                if ($order->current_state == 2) {
                    $history = new OrderHistory();
                    $history->id_order = (int)$order->id;
                    $history->changeIdOrderState(4, $order);
                    $history->addWithemail();
                }
            }
        }
        catch (Exception $e) {
            $logger = new Mbe_Shipping_Helper_Logger();
            $logger->logDebug("SET ORDER SHIPPED ERROR: " . $e->getMessage());
        }
    }

    protected function getSubtotalForInsurance($item) {
        $insuranceValue = 0;
        if (Configuration::get('mbe_shipments_ins_mode') == Mbe_Shipping_Helper_Data::MBE_INSURANCE_WITH_TAXES) {
            $insuranceValue += $item["product_price_wt"] * $item['product_quantity'];
        }
        else {
            $insuranceValue += $item["product_price"] * $item['product_quantity'];
        }
        return $insuranceValue;
    }

    public function addReturnShipping($order, $trackings)
    {
        $errors = array();

        $ts = explode(Mbe_Shipping_Helper_Data::MBE_SHIPPING_TRACKING_SEPARATOR, $trackings);

        $errors = $this->createReturnShipment($order, $ts[0]);

        return $errors;
    }

    public function createReturnShipment($order, $tracking)
    {
        $errors = array();
        $logger = new Mbe_Shipping_Helper_Logger();

        try {
            $ws = new Mbe_Shipping_Model_Ws();
            $mbeShipment = $ws->createReturnShipping($tracking);
            $logger->logDebug("MBE RETURN SHIPMENT", $mbeShipment);
            if ($mbeShipment) {
                $trackingNumber = "RETURN " . $mbeShipment->MasterTrackingMBE;
                $this->setWsShippingNumber($order, $trackingNumber);

            }
            else {
                $errors[] = 'Error creating return tracking number.';
            }

        }
        catch (Exception $e) {
            $logger->logDebug($e->getMessage());
        }
        return $errors;
    }
}