<?php
/**
 * Opencart Store's Common functionalities will be written here
 *
 * PHP version 5.6
 *
 * @category  Opencart
 * @package   Store
 * @author    Mukesh Pradhan <mukeshp@riaxe.com>
 * @copyright 2019-2020 Riaxe Systems
 * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
 * @link      http://inkxe-v10.inkxe.io/xetool/admin
 */
namespace ComponentStoreSpace\Controllers;

use App\Components\Controllers\Component;
use ComponentStoreSpace\Models\Cart as Cart;
use ComponentStoreSpace\Models\Product as Product;
use ComponentStoreSpace\Models\Customer as Customer;
use ComponentStoreSpace\Models\Order as Order;

/**
 * Asset Type Class
 *
 * @category Opencart
 * @package  Store
 * @author   Mukesh Pradhan <mukeshp@riaxe.com>
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @link     http://inkxe-v10.inkxe.io/xetool/admin
 */
class StoreComponent extends Component
{
    /**
     * Initialize Constructor
     */
    public function __construct()
    {
        $this->includeFile();
        $this->store = 0;
        $this->con = mysqli_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
        if (mysqli_connect_errno()) {
            $this->con = '';
        }
        mysqli_set_charset($this->con, "utf8");
        //get session path for opencart 3
        $pos = strrpos(session_save_path(), ';');
        if ($pos === false) {
            $this->directory = session_save_path();
        } else {
            $this->directory = substr(session_save_path(), $pos + 1);
        }
        // Color and Size Attributes
        $attributeName = $this->getAttributeName();
        $this->color = $attributeName['color'];
        $this->size = $attributeName['size'];

        // Product Model Object
        $this->productModelInit = new Product($this->con, $this->store, $this->color, $this->size);
        // Cart Model Object
        $this->cartModelInit = new Cart($this->con, $this->store, $this->color, $this->size);
        // Customer Model Object
        $this->customer = new Customer($this->con, $this->store);
        // Order Model Object
        $this->order = new Order($this->con, $this->store);
    }

    private function includeFile()
    {
        include_once dirname(dirname(dirname(RELATIVE_PATH))) . '/config.php';
    }

    public function getStoreCategories($filter)
    {
        $categoryData = $this->productModelInit->getCategories($filter);
        return $categoryData;
    }

    public function storeProducts($filter)
    {
        $productData = $this->productModelInit->getProducts((object) $filter);
        return $productData;
    }

    public function getProductById($id)
    {
        $singleProductData = $this->productModelInit->getProductById($id);
        return $singleProductData;
    }

    public function getAttributes()
    {
        $attributesData = $this->productModelInit->getAllOptions();
        return $attributesData;
    }

    public function getAttributeValuesById($attrId)
    {
        $attributesData = $this->productModelInit->getOptionValuesById($attrId);
        return $attributesData;
    }

    public function getExistingAttributeValue($id, $name)
    {
        $isOptionValueExist = $this->productModelInit->checkExistingOptionValue($id, $name);
        return $isOptionValueExist;
    }

    public function addAttributeValue($id, $name)
    {
        $optionValueData = $this->productModelInit->addOptionValue($id, $name);
        return $optionValueData;
    }

    public function getProductAttributes($productId, $isTool = 0)
    {
        $proAttributesData = $this->productModelInit->getProductAllOptionDetails($productId, $isTool);
        return $proAttributesData;
    }

    public function getProductStoreImages($productId)
    {
        $productImageData = $this->productModelInit->getProductImages($productId);
        return $productImageData;
    }

    public function storeProductShortDetails($request)
    {
        $response = [];
        $product_id = $request['product_id'];
        $variant_id = $request['variant_id'];
        $option_id = $request['option_id'];
        $details = $request['details'];
        $id = ($product_id != $variant_id) ? $variant_id : $product_id;
        // Get Product Images
        $response['images'] = $this->getProductStoreImages($id);
        $product = $this->getProductById($id);
        if ($details) {
            $response['name'] = htmlspecialchars_decode($product['name']);
            $response['price'] = $product['price'];
            $response['tax'] = $product['taxrate'];
            $response['tier_prices'] = $product['tier_prices'];
            $attribute = [];
            $optIdArr = explode(",", $option_id);
             // Fetch Attr val name
            foreach ($optIdArr as $key => $value) {
                $optionValName[$key] = $this->productModelInit->getProductOptionValueName($product_id, $value);
            }
            if ($product_id != $variant_id) {
                $attributes = $this->getProductAttributes($id, 1);
                foreach ($attributes as $key => $value) {
                    $attrName = $value['name'];
                    if ($attrName == $this->color) {
                        if (!empty($value['options'])) {
                            foreach ($value['options'] as $optKey => $optValue) {
                                $attribute[$attrName]['id'] = $optValue['id'];
                                $attribute[$attrName]['name'] = $optValue['name'];
                                $attribute[$attrName]['attribute_id'] = $value['id'];
                            }
                        }
                    } else {
                        if (!empty($value['options'])) {
                            foreach ($value['options'] as $optKey => $optValue) {
                                if ($option_id != "") {
                                    if (in_array($optValue['name'], $optionValName)) {
                                        $attribute[$attrName]['id'] = $optValue['id'];
                                        $attribute[$attrName]['name'] = $optValue['name'];
                                        $attribute[$attrName]['attribute_id'] = $value['id'];
                                        break;
                                    }
                                } else {
                                    $attribute[$attrName]['id'] = $optValue['id'];
                                    $attribute[$attrName]['name'] = $optValue['name'];
                                    $attribute[$attrName]['attribute_id'] = $value['id'];
                                    break;
                                }
                            }
                        }
                    }
                }
            } else {

                $attributes = $this->getProductAttributes($id, 1);
                foreach ($attributes as $key => $value) {
                    $attrName = $value['name'];
                    if ($attrName == $this->color) {
                        if (!empty($value['options'])) {
                            foreach ($value['options'] as $optKey => $optValue) {
                                if ($option_id != "") {
                                    if (in_array($optValue['name'], $optionValName)) {
                                        $attribute[$attrName]['id'] = $optValue['id'];
                                        $attribute[$attrName]['name'] = $optValue['name'];
                                        $attribute[$attrName]['attribute_id'] = $value['id'];
                                    }
                                } else {
                                    $attribute[$attrName]['id'] = $optValue['id'];
                                    $attribute[$attrName]['name'] = $optValue['name'];
                                    $attribute[$attrName]['attribute_id'] = $value['id'];
                                }
                            }
                        }
                    } else {
                        if (!empty($value['options'])) {
                            foreach ($value['options'] as $optKey => $optValue) {
                                if ($option_id != "") {
                                    if (in_array($optValue['name'], $optionValName)) {
                                        $attribute[$attrName]['id'] = $optValue['id'];
                                        $attribute[$attrName]['name'] = $optValue['name'];
                                        $attribute[$attrName]['attribute_id'] = $value['id'];
                                    }
                                } else {
                                    $attribute[$attrName]['id'] = $optValue['id'];
                                    $attribute[$attrName]['name'] = $optValue['name'];
                                    $attribute[$attrName]['attribute_id'] = $value['id'];
                                }
                            }
                        }
                    }
                }
            }
            // attributes sorting
            asort($attribute);
            $response['attributes'] = $attribute;
        }
        return $response;
    }

    public function storeAddToCart($cartData)
    {
        $response = $this->cartModelInit->customAddToCart($cartData);
        return $response;
    }

    /**
     * Check the controller path
     *
     * @param   nothing
     * @return  the extension url
     */
    public function getExtensionURL()
    {
        $url = '';
        $ext_path = '';
        if (file_exists(DIR_APPLICATION . "controller" . DIRECTORY_SEPARATOR . "extension")) {
            $ext_path = 'extension/';
        }
        $protocol = strtolower(substr($_SERVER["SERVER_PROTOCOL"], 0, 5)) == 'https' ? 'https' : 'http';
        if ($protocol == "http") {
            $url = HTTP_SERVER . '?route=' . $ext_path . 'feed/web_api/';
        } else {
            $url = HTTPS_SERVER . '?route=' . $ext_path . 'feed/web_api/';

        }
        return $url;
    }

    public function getColorVariantsByProduct($filter)
    {
        $productVariantsData = $this->productModelInit->getOptions($filter);
        return $productVariantsData;
    }

    public function storeTotalProductCount()
    {
        $result['total'] = $this->productModelInit->totalProduct();
        return $result;
    }

    public function checkDuplicateNameAndSku($filters)
    {
        $result = $this->productModelInit->getProductIdByNameAndSku($filters);
        return $result;
    }

    public function getProductRelatedOptions($product_id)
    {
        $result = $this->productModelInit->getProductRelatedOptions($product_id);
        return $result;
    }

    public function getProductOptions($product_id)
    {
        $result = $this->productModelInit->getProductOptions($product_id);
        return $result;
    }

    public function getProductOptionValue($option, $id)
    {
        $result = $this->productModelInit->getProductOptionValue($option, $id);
        return $result;
    }

    public function getStoreProductVariant($filter)
    {
        $productData = $this->productModelInit->getStoreProductVariant($filter);
        return $productData;
    }

    public function getStoreOrderStatus()
    {
        $orderStatus = $this->productModelInit->getStoreOrderStatus();
        return $orderStatus;
    }

    public function modifyStoreOrderStatus($orderId,$status)
    {
        $orderStatus = $this->productModelInit->modifyStoreOrderStatus($orderId,$status);
        return $orderStatus;
    }

    public function getProductIdByVariantID($variantId)
    {
        $parentProductId = $this->productModelInit->getProductIdByVariantID($variantId);
        return $parentProductId;
    }

    public function createPredecoratedProduct($productData)
    {
        $productData = $this->productModelInit->addTemplateProducts($productData);
        return $productData;
    }

    public function deleteCartItem($cartId)
    {
        $this->cartModelInit->removeCartItem($cartId);
    }

    public function getTierPrice($productId,$price)
    {
        $tierPriceData =$this->productModelInit->getTierPrice($productId,$price);
        return $tierPriceData;
    }

    public function addCatalogProductToStore($data)
    {
        $returnData = $this->productModelInit->addCatalogProductToStore($data);
        return $returnData;
    }

    public function getStoreCustomers($filter)
    {
        $countriesData = $this->customer->getAllCustomers($filter);
        return $countriesData;
    }

    public function getStatesByCountry($name)
    {
        $statesData = $this->customer->getStatesByCountry($name);
        return $statesData;
    }

    public function getStoreCustomer($customerId)
    {
        $customerData = $this->customer->getCustomer($customerId);
        return $customerData;
    }

    public function getCustomerShippingAddress($customerId)
    {
        $addressData = $this->customer->getShippingAddress($customerId);
        return $addressData;
    }

    public function totalCustomer()
    {
        $total = $this->customer->customerCount();
        return $total;
    }

    public function getStoreCountries()
    {
        $countriesData = $this->customer->getCountries();
        return $countriesData;
    }

    public function addShippingAddress($data)
    {
        $status = $this->customer->addShippingAddress($data);
        return $status;
    }

    public function updateStoreShippingAddress($id,$data)
    {
        $status = $this->customer->updateShippingAddress($id,$data);
        return $status;
    }

    public function deleteStoreCustomer($ids)
    {
        $status = $this->customer->deleteStoreCustomer($ids);
        return $status;
    }

    public function createStoreCustomer($data)
    {
        $status = $this->customer->createCustomer($data);
        return $status;
    }

    public function getProductOptionValDetails($productId,$optName,$optVal)
    {
        $result = $this->productModelInit->getProductOptionValDetails($productId,$optName,$optVal);
        return $result;
    }

    public function placeOrderFromQuotation($queryArray)
    {
        $data = [];
        $customerId = $queryArray['customer_id'];
        $designTotal = $queryArray['design_total'] ? $queryArray['design_total'] : 0;
        $quoteTotal = $queryArray['quote_total'] ? $queryArray['quote_total'] : 0;
        $shippingId = $queryArray['shipping_id'] ? $queryArray['shipping_id'] : 0;

        $customerDetails = $this->getStoreCustomer($customerId);
        $billingAddress = $this->customer->getAddress($customerDetails[0]['address_id']);
        $country = $this->customer->getCountry($billingAddress[0]['country_id']);
        $zone = $this->customer->getZone($billingAddress[0]['zone_id']);
        $addrFormat = $country[0]['address_format'];
        $countryName = $country[0]['name'];
        $zoneName = $zone[0]['name'];

        $shippingAddress = $this->customer->getAddress($shippingId);
        $shippingcountry = $this->customer->getCountry($shippingAddress[0]['country_id']);
        $shippingZone = $this->customer->getZone($shippingAddress[0]['zone_id']);
        $shippCountryName = $shippingcountry[0]['name'];
        $shippZoneName = $shippingZone[0]['name'];

        $data['billing']['firstname'] = $billingAddress[0]['firstname'];
        $data['billing']['lastname'] = $billingAddress[0]['lastname'];
        $data['billing']['company'] = $billingAddress[0]['company'];
        $data['billing']['address_1'] = $billingAddress[0]['address_1'];
        $data['billing']['address_2'] = $billingAddress[0]['address_2'];
        $data['billing']['city'] = $billingAddress[0]['city'];
        $data['billing']['postcode'] = $billingAddress[0]['postcode'];
        $data['billing']['country_id'] = $billingAddress[0]['country_id'];
        $data['billing']['zone_id'] = $billingAddress[0]['zone_id'];
        $data['billing']['country'] = $countryName;
        $data['billing']['zone'] = $zoneName;
        $data['billing']['address_format'] = $addrFormat;
        $data['shipping']['firstname'] = $shippingAddress[0]['firstname'];
        $data['shipping']['lastname'] = $shippingAddress[0]['lastname'];
        $data['shipping']['company'] = $shippingAddress[0]['company'];
        $data['shipping']['address_1'] = $shippingAddress[0]['address_1'];
        $data['shipping']['address_2'] = $shippingAddress[0]['address_2'];
        $data['shipping']['city'] = $shippingAddress[0]['city'];
        $data['shipping']['postcode'] = $shippingAddress[0]['postcode'];
        $data['shipping']['country_id'] = $shippingAddress[0]['country_id'];
        $data['shipping']['zone_id'] = $shippingAddress[0]['zone_id'];
        $data['shipping']['country'] = $shippCountryName;
        $data['shipping']['zone'] = $shippZoneName;
        $data['customer']['customer_id'] = $customerDetails[0]['customer_id'];
        $data['customer']['customer_group_id'] = $customerDetails[0]['customer_group_id'];
        $data['customer']['firstname'] = $customerDetails[0]['firstname'];
        $data['customer']['lastname'] = $customerDetails[0]['lastname'];
        $data['customer']['email'] = $customerDetails[0]['email'];
        $data['customer']['telephone'] = $customerDetails[0]['telephone'];
        // product data

        $productData = $queryArray['product_data'];
        
        // Line items
        $i = 0;
        foreach( $productData as $line_item ) {
            $price = $line_item['design_cost'] + $line_item['unit_price'];
            $total = $price * $line_item['quantity'];
            $data['products'][$i]['product_id'] = $line_item['variant_id'];
            $data['products'][$i]['name'] = $line_item['product_name'];
            $data['products'][$i]['quantity'] = $line_item['quantity'];
            $data['products'][$i]['price'] = $price;
            $data['products'][$i]['total'] = $total;
            $data['products'][$i]['tax'] = '';
            $data['products'][$i]['reward'] = '';
            $j = 0;
            foreach ($line_item['product_attributes'] as $attrKey => $attrValue) {
                $options = $this->getProductOptionValDetails($line_item['variant_id'],$attrKey,$attrValue['name']);
                $data['products'][$i]['option'][$j]['product_option_id'] = $options['product_option_id'];
                $data['products'][$i]['option'][$j]['product_option_value_id'] = $options['product_option_value_id'];
                $data['products'][$i]['option'][$j]['name'] = $attrKey;
                $data['products'][$i]['option'][$j]['value'] = $attrValue['name'];
                $data['products'][$i]['option'][$j]['type'] = $options['type'];
                $j++;
            }
            $options = $this->getProductOptionValDetails($line_item['variant_id'],'refid','');
            $data['products'][$i]['option'][$j]['product_option_id'] = $options['product_option_id'];
            $data['products'][$i]['option'][$j]['product_option_value_id'] = 0;
            $data['products'][$i]['option'][$j]['name'] = "refid";
            $data['products'][$i]['option'][$j]['value'] = $line_item['custom_design_id'];
            $data['products'][$i]['option'][$j]['type'] = $options['type'];
            $i++;     
        }
        
        // Fee items
        $fees = array('shipping','tax','discount');
        $data['totals'] = [];
        $k=0;
        foreach($fees as $fee) {
            if( isset($queryArray[$fee.'_amount']) && $queryArray[$fee.'_amount'] != ''  && $queryArray[$fee.'_amount'] > 0){
                $lable = $queryArray[$fee.'_type'] . " ". ucwords($fee);
                $data['totals'][$k]['code'] = $fee;
                $data['totals'][$k]['title'] = $lable;
                $amount = ($fee == 'tax') ? ($designTotal * $queryArray[$fee.'_amount']) / 100 : $queryArray[$fee.'_amount'];
                if ($fee == 'discount') {
                    if ($queryArray[$fee.'_type'] == "percentage") {
                        $data['totals'][$k]['value'] = ($designTotal * $amount)/100;
                    } else {
                        $data['totals'][$k]['value'] = $amount;
                    }
                } else {
                    $data['totals'][$k]['value'] = $amount;
                }
                $k++;
            }
        }

        $data['totals'][$k]['code'] = 'sub_total';
        $data['totals'][$k]['title'] = 'Sub-Total';
        $data['totals'][$k]['value'] = $designTotal;
        $k++;
        $data['totals'][$k]['code'] = 'total';
        $data['totals'][$k]['title'] = 'Total';
        $data['totals'][$k]['value'] = $quoteTotal;
        $data['total'] = $quoteTotal;
        $orderId = $this->order->addOrder($data);

        return $orderId;
    }
    
    public function getStoreProductOptionValDetails($productOptValId)
    {
        $data = $this->productModelInit->getOptionDetailsByProductOptValId($productOptValId);
        return $data;
    }

    public function getStoreCustomerIds($filter)
    {
        $result = $this->customer->getAllCustomerIds($filter);
        return $result;
    }

    public function getTotalOrders($customerId)
    {
        $result = $this->order->getTotalOrdersByCustomer($customerId);
        return $result;
    }

    public function getPriceByVariantId($productId)
    {
        $price = $this->productModelInit->getPriceById($productId);
        return $price;
    }

    public function updateProductQty($productId,$qty)
    {
        return $this->productModelInit->updateProductQty($productId,$qty);
    }

    public function getWeightDetailsByProduct($productId)
    {
        return $this->productModelInit->getWeightDetailsByProduct($productId);
    }
}