<?php

class ControllerAmazonOrder extends Controller {

    public function index() {
        if ($this->config->get('amazon_status') != '1') {
            return;
        }
        
        $this->load->library('log');
        $this->load->library('amazon');
        $this->load->model('checkout/order');
        $this->load->model('amazon/order');
        $this->language->load('amazon/order');
        
        $logger = new Log('amazon.log');
        $logger->write('amazon/order - started');
        
        $token = $this->config->get('openbay_amazon_token');
        
        $incomingToken = isset($this->request->post['token']) ? $this->request->post['token'] : '';
        
        if ($incomingToken !== $token) {
            $logger->write('amazon/order - Incorrect token: ' . $incomingToken);
            return;
        }
        
        $decrypted = $this->amazon->decryptArgs($this->request->post['data']);
        
        if (!$decrypted) {
            $logger->write('amazon/order Failed to decrypt data');
            return;
        }
        
        $orderXml = simplexml_load_string($decrypted);
        
        $amazonOrderStatus = trim(strtolower((string) $orderXml->Status));
        
        $amazonOrderId = (string)$orderXml->AmazonOrderId;
        $orderStatus = $this->model_amazon_order->getMappedStatus((string) $orderXml->Status);
        
        $logger->write('Received order ' . $amazonOrderId);
        
        $orderId = $this->model_amazon_order->getOrderId($amazonOrderId);
        
        // If the order already exists on opencart, ignore it.
        if ($orderId) {            
            $logger->write("Duplicate order $amazonOrderId. Terminating.");
            $this->response->setOutput('Ok');
            return;
        }
        
        /* Check if order comes from subscribed marketplace */
        
        $currencyTo = $this->config->get('config_currency');
        $orderCurrency = (string) $orderXml->Payment->CurrencyCode;

        $products = array();

        $productsTotal = 0;
        $productsShipping = 0;
        $productsTax = 0;
        $productsShippingTax = 0;
        $giftWrap = 0;
        $giftWrapTax = 0;
        
        $productCount = 0;

        $amazonOrderId = (string)$orderXml->AmazonOrderId;

        /* SKU => ORDER_ITEM_ID */
        $productMapping = array();
        
        foreach ($orderXml->Items->Item as $item) {
            
            $totalPrice = $this->currency->convert((double)$item->Totals->Price, $orderCurrency, $currencyTo);
            $taxTotal = (double) $item->Totals->Tax;
            
            if ($taxTotal == 0 && $this->config->get('openbay_amazon_order_tax') > 0) {
                $taxTotal = (double)$item->Totals->Price * ($this->config->get('openbay_amazon_order_tax') / 100) / (1 + $this->config->get('openbay_amazon_order_tax') / 100);
            }
            
            $taxTotal = $this->currency->convert($taxTotal, $orderCurrency, $currencyTo);

            $productsTotal += $totalPrice;
            $productsTax += $taxTotal;
            
            $productsShipping += $this->currency->convert((double) $item->Totals->Shipping, $orderCurrency, $currencyTo);
            
            $shippingTax = (double) $item->Totals->ShippingTax;
            
            if ($shippingTax == 0 && $this->config->get('openbay_amazon_order_tax') > 0) {
                $shippingTax = (double) $item->Totals->Shipping * ($this->config->get('openbay_amazon_order_tax') / 100) / (1 + $this->config->get('openbay_amazon_order_tax') / 100);
            }
            
            $productsShippingTax += $this->currency->convert($shippingTax, $orderCurrency, $currencyTo);
            
            $giftWrap += $this->currency->convert((double) $item->Totals->GiftWrap, $orderCurrency, $currencyTo);
            
            $itemGiftWrapTax = (double) $item->Totals->GiftWrapTax;
            
            if ($itemGiftWrapTax == 0 && $this->config->get('openbay_amazon_order_tax') > 0) {
                $itemGiftWrapTax = (double) $item->Totals->GiftWrap * ($this->config->get('openbay_amazon_order_tax') / 100) / (1 + $this->config->get('openbay_amazon_order_tax') / 100);
            }
            
            $giftWrapTax += $this->currency->convert($itemGiftWrapTax, $orderCurrency, $currencyTo);
            
            $productCount += (int) $item->Ordered;

            if ((int) $item->Ordered == 0) {
                continue;
            }
            
            $productId = $this->model_amazon_order->getProductId((string) $item->Sku);
            $productVar = $this->model_amazon_order->getProductVar((string) $item->Sku);
            
            $products[] = array(
                'product_id' => $productId,
                'var' => $productVar,
                'sku' => (string) $item->Sku,
                'asin' => (string) $item->Asin,
                'order_item_id' => (string) $item->OrderItemId, 
                'name' => (string) $item->Title,
                'model' => (string) $item->Sku,
                'quantity' => (int) $item->Ordered,
                'price' => sprintf('%.4f', ($totalPrice - $taxTotal) / (int) $item->Ordered),
                'total' => sprintf('%.4f', $totalPrice - $taxTotal),
                'tax' => $taxTotal / (int) $item->Ordered,
                'reward' => '0',
                'option' => $this->model_amazon_order->getProductOptionsByVar($productVar),
                'download' => array(),
            );
            
            $productMapping[(string) $item->Sku] = (string) $item->OrderItemId;
        }

        $total = sprintf('%.4f', $this->currency->convert((double) $orderXml->Payment->Amount, $orderCurrency, $currencyTo));

        $addressLine2 = (string) $orderXml->Shipping->AddressLine2;
        if ((string) $orderXml->Shipping->AddressLine3 != '') {
            $addressLine2 .= ', ' . (string) $orderXml->Shipping->AddressLine3;
        }
        
        $customer_info = $this->db->query("SELECT `customer_id` FROM " . DB_PREFIX . "customer WHERE email = '" . $this->db->escape((string) $orderXml->Payment->Email) . "'")->row;
        $customer_id = '0';
        
        if(isset($customer_info['customer_id'])) {
            $customer_id = $customer_info['customer_id'];
        } else {            
            /* Add a new customer */
            $customerData = array(
                'firstname' => (string) $orderXml->Shipping->Name,
                'lastname' => '',
                'email' => (string) $orderXml->Payment->Email,
                'telephone' => (string) $orderXml->Shipping->Phone,
                'fax' => '',
                'newsletter' => '0',
                'customer_group_id' => $this->config->get('openbay_amazon_order_customer_group'),
                'password' => '',
                'status' => '0',
            );
            
            $this->db->query("
                INSERT INTO " . DB_PREFIX . "customer 
                SET firstname = '" . $this->db->escape($customerData['firstname']) . "', 
                    lastname = '" . $this->db->escape($customerData['lastname']) . "', 
                    email = '" . $this->db->escape($customerData['email']) . "', 
                    telephone = '" . $this->db->escape($customerData['telephone']) . "', 
                    fax = '" . $this->db->escape($customerData['fax']) . "', 
                    newsletter = '" . (int)$customerData['newsletter'] . "', 
                    customer_group_id = '" . (int)$customerData['customer_group_id'] . "', 
                    password = '', 
                    status = '" . (int)$customerData['status'] . "', 
                    date_added = NOW()");
            
            $customer_id = $this->db->getLastId();
        }
        
        $shippingFirstName = (string) $orderXml->Shipping->FirstName;
        $shippingLastName = (string) $orderXml->Shipping->LastName;
        
        if (empty($shippingFirstName) || empty($shippingLastName)) {
            $shippingFirstName = (string) $orderXml->Shipping->Name;
            $shippingLastName = '';
        }
        
        $order = array(
            'invoice_prefix' => $this->config->get('config_invoice_prefix'),
            'store_id' => $this->config->get('config_store_id'),
            'store_name' => $this->config->get('config_name') . ' / Amazon',
            'store_url' => $this->config->get('config_url'),
            'customer_id' => (int) $customer_id,
            'customer_group_id' => $this->config->get('openbay_amazon_order_customer_group'),
            'firstname' => $shippingFirstName,
            'lastname' => $shippingLastName,
            'email' => (string) $orderXml->Payment->Email,
            'telephone' => (string) $orderXml->Shipping->Phone,
            'fax' => '',
            'shipping_firstname' => $shippingFirstName,
            'shipping_lastname' => $shippingLastName,
            'shipping_company' => '',
            'shipping_address_1' => (string) $orderXml->Shipping->AddressLine1,
            'shipping_address_2' => $addressLine2,
            'shipping_city' => (string) $orderXml->Shipping->City,
            'shipping_postcode' => (string) $orderXml->Shipping->PostCode,
            'shipping_country' => $this->model_amazon_order->getCountryName((string) $orderXml->Shipping->CountryCode),
            'shipping_country_id' => $this->model_amazon_order->getCountryId((string) $orderXml->Shipping->CountryCode),
            'shipping_zone' => (string) $orderXml->Shipping->State,
            'shipping_zone_id' => $this->model_amazon_order->getZoneId((string) $orderXml->Shipping->State),
            'shipping_address_format' => '',
            'shipping_method' => (string) $orderXml->Shipping->Type,
            'shipping_code' => 'amazon.' . (string) $orderXml->Shipping->Type,
            'payment_firstname' => $shippingFirstName,
            'payment_lastname' => $shippingLastName,
            'payment_company' => '',
            'payment_address_1' => (string) $orderXml->Shipping->AddressLine1,
            'payment_address_2' => $addressLine2,
            'payment_city' => (string) $orderXml->Shipping->City,
            'payment_postcode' => (string) $orderXml->Shipping->PostCode,
            'payment_country' => $this->model_amazon_order->getCountryName((string) $orderXml->Shipping->CountryCode),
            'payment_country_id' => $this->model_amazon_order->getCountryId((string) $orderXml->Shipping->CountryCode),
            'payment_zone' => (string) $orderXml->Shipping->State,
            'payment_zone_id' => $this->model_amazon_order->getZoneId((string) $orderXml->Shipping->State),
            'payment_address_format' => '',
            'payment_method' => $this->language->get('paid_on_amazon_text'),
            'payment_code' => 'amazon.amazon',
            'payment_company_id' => 0,
            'payment_tax_id' => 0,
            'comment' => '',
            'total' => $total,
            'affiliate_id' => '0',
            'commission' => '0.00',
            'language_id' => (int)$this->config->get('config_language_id'),
            'currency_id' => $this->currency->getId($orderCurrency),
            'currency_code' => (string) $orderCurrency,
            'currency_value' => $this->currency->getValue($orderCurrency),
            'ip' => '',
            'forwarded_ip' => '',
            'user_agent' => 'OpenBay Pro for Amazon',
            'accept_language' => '',
            'products' => $products,
            'vouchers' => array(),
            'totals' => array(
                array(
                    'code' => 'sub_total',
                    'title' => $this->language->get('sub_total_text'),
                    'text' => $this->currency->format($productsTotal, $orderCurrency),
                    'value' => sprintf('%.4f', $productsTotal),
                    'sort_order' => '1',
                ),
                array(
                    'code' => 'shipping',
                    'title' => $this->language->get('shipping_text'),
                    'text' => $this->currency->format($productsShipping, $orderCurrency),
                    'value' => sprintf('%.4f', $productsShipping),
                    'sort_order' => '3',
                ),
                array(
                    'code' => 'tax',
                    'title' => $this->language->get('tax_text'),
                    'text' => $this->currency->format($productsTax, $orderCurrency),
                    'value' => sprintf('%.4f', $productsTax),
                    'sort_order' => '4',
                ),
                array(
                    'code' => 'shipping_tax',
                    'title' => $this->language->get('shipping_tax_text'),
                    'text' => $this->currency->format($productsShippingTax, $orderCurrency),
                    'value' => sprintf('%.4f', $productsShippingTax),
                    'sort_order' => '6',
                ),
                array(
                    'code' => 'gift_wrap',
                    'title' => $this->language->get('gift_wrap_text'),
                    'text' => $this->currency->format($giftWrap, $orderCurrency),
                    'value' => sprintf('%.4f', $giftWrap),
                    'sort_order' => '2',
                ),
                array(
                    'code' => 'gift_wrap_tax',
                    'title' => $this->language->get('gift_wrap_tax_text'),
                    'text' => $this->currency->format($giftWrapTax, $orderCurrency),
                    'value' => sprintf('%.4f', $giftWrapTax),
                    'sort_order' => '5',
                ),
                array(
                    'code' => 'total',
                    'title' => $this->language->get('total_text'),
                    'text' => $this->currency->format($total, $orderCurrency),
                    'value' => sprintf('%.4f', $total),
                    'sort_order' => '7',
                ),
            ),
        );
        
        $addOrderMethod = 'addOrder';
        
        if (version_compare(VERSION, '1.5.1.3', '<=')) {
            $addOrderMethod = 'create';
        }
        
        $orderId = $this->model_checkout_order->$addOrderMethod($order);

        $this->model_amazon_order->updateOrderStatus($orderId, $orderStatus);
        $this->model_amazon_order->addAmazonOrder($orderId, $amazonOrderId);
        $this->model_amazon_order->addAmazonOrderProducts($orderId, $productMapping);
        
        foreach($products as $product) {
           if($product['product_id'] != 0) {
               $this->model_amazon_order->decreaseProductQuantity($product['product_id'], $product['quantity'], $product['var']);
           }
        }
        
        $logger->write('Order ' . $amazonOrderId . ' was added to the database (ID: ' . $orderId . ')');
        $logger->write("Finished processing the order");
        
        $logger->write("Notifying Openbay::orderNew($orderId)");
        $this->openbay->orderNew($orderId);
        $logger->write("Openbay notified");
        
        $this->model_amazon_order->acknowledgeOrder($orderId);

        //send an email to the administrator about the sale
        if($this->config->get('openbay_amazon_notify_admin') == 1){
            $this->openbay->newOrderAdminNotify($orderId, $orderStatus);
        }

        $logger->write("Ok");
        $this->response->setOutput('Ok');
    }

}