<?php
//ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL);
/**
  * Copyright (c) Facebook, Inc. and its affiliates.
  * All rights reserved.
  *
  * This source code is licensed under the license found in the
  * LICENSE file in the root directory of this source tree.
  */


require_once(DIR_SYSTEM . 'library/facebook_business/vendor/autoload.php');

use FacebookAds\Api;
use FacebookAds\Logger\CurlLogger;
use FacebookAds\Object\ServerSide\ActionSource;
use FacebookAds\Object\ServerSide\AdsPixelSettings;
use FacebookAds\Object\ServerSide\CustomData;
use FacebookAds\Object\ServerSide\EventResponse;
use FacebookAds\Object\ServerSide\Content;
use FacebookAds\Object\ServerSide\DeliveryCategory;
use FacebookAds\Object\ServerSide\Event;
use FacebookAds\Object\ServerSide\EventRequest;
use FacebookAds\Object\ServerSide\EventRequestAsync;
use FacebookAds\Object\ServerSide\UserData;
use FacebookAds\Object\ServerSide\Util;


class ControllerExtensionModuleFacebookEvents extends Controller {
    
   private $pluginVersion = '4.0.3';
    
    public function index() {
        $this->getEventParameters();
            
    }
    

    public function getEventParameters() {
        $route = (array_key_exists('route', $this->request->get)) ? $this->request->get['route'] : null;

        $facebook_conversion_event_params = null;
    
        // This grabs events stored on redirects
        if (array_key_exists('facebook_pixel_event_params', $this->session->data)) {
            $facebook_conversion_event_params = $this->session->data['facebook_pixel_event_params'];
        }

        $event_name = 'ViewContent';
        $event_id = $this->generateEventId();
    
        // checking the route and handling the event firing accordingly
        switch ($route) {
            case 'checkout/success':
                $event_name = 'Purchase';

                $this->load->language('checkout/success');

                $contents = array();
                $content_ids = array();
                $value = 0;
                $num_items = 0;
                $currency = $this->session->data['currency'];

                if (isset($this->session->data['fb_conversion_order_id'])) {
                    $order_id = $this->session->data['fb_conversion_order_id'];
                    unset($this->session->data['fb_conversion_order_id']);

                    $this->load->model('account/order');

                    $order_info = $this->model_account_order->getOrder($order_id);

                    if ($order_info) {
                        $order_products = $this->model_account_order->getOrderProducts($order_id);

                        foreach ($order_products as $product) {
                            $content_ids[] = (string)$product['product_id'];
                            $num_items += $product['quantity'];
                            $contents[] = array(
                                'id'       => $product['product_id'],
                                'quantity' => $product['quantity']
                            );
                        }

                        $value = $this->currency->format($order_info['total'], $order_info['currency_code'], $order_info['currency_value'], false);
                        $currency = $order_info['currency_code'];
                    }
                } 

                $facebook_conversion_event_params = array(
                    'event_name'    => $event_name,
                    'content_ids'   => $content_ids,
                    'content_name'  => $this->formatString($this->language->get('heading_title')),
                    'content_type'  => 'product',
                    'contents'      => $contents,
                    'currency'      => strtoupper($currency),
                    'num_items'     => $num_items,
                    'value'         => $value,
                    'event_id'      => $event_id
                );
//                var_dump($facebook_conversion_event_params);
//                die('Product ');
                break;

            case 'product/product':
                $event_name = 'ViewContent';

                $this->load->model('catalog/product');

                $product_id = isset($this->request->get['product_id']) ? (int)$this->request->get['product_id'] : 0;

                $product_info = $this->model_catalog_product->getProduct($product_id);
//                var_dump($product_info);
//                die('Product ');
                if ($product_info) {
                    if ((float)$product_info['special']) {
                        $price = $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                    } else {
                        $price = $this->currency->format($this->tax->calculate($product_info['price'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                    }
                    

                    $facebook_conversion_event_params = array(
                        'event_name'       => $event_name,
                        'content_ids'      => array((string)$product_id),
                        'content_name'     => $this->formatString($product_info['name']),
                        'content_type'     => 'product',
                        'currency'         => strtoupper($this->session->data['currency']),
                        'value'            => $price,
                        'num_items'        => 1,
                        'event_id'         => $event_id
                    );
                }
                break;

            case 'checkout/cart':
                $event_name = 'AddToCart';
                $this->load->language('checkout/cart');
    
                $contents = array();
                $content_ids = array();
                $value = 0.0;
                $num_items = 0;

                foreach ($this->cart->getProducts() as $product) {
                    $content_ids[] = (string)$product['product_id'];
                    $value += $this->currency->format($this->tax->calculate($product['total'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                    $num_items += $product['quantity'];
                    $contents[] = array(
                        'id'       => $product['product_id'],
                        'quantity' => $product['quantity']
                    );
                }

                $facebook_conversion_event_params = array(
                    'event_name'    => $event_name,
                    'content_ids'   => $content_ids,
                    'content_name'  => $this->formatString($this->language->get('heading_title')),
                    'content_type'  => 'product',
                    'contents'      => $contents,
                    'currency'      => strtoupper($this->session->data['currency']),
                    'value'         => $value,
                    'num_items'     => $num_items,
                    'event_id'      => $event_id
                );
                break;

            case 'account/order/reorder':
                $event_name = 'AddToCart';

                if (isset($this->request->get['order_id'])) {
                    $order_id = $this->request->get['order_id'];
                } else {
                    $order_id = 0;
                }

                $this->load->model('account/order');

                $order_info = $this->model_account_order->getOrder($order_id);

                if ($order_info) {
                    if (isset($this->request->get['order_product_id'])) {
                        $order_product_id = $this->request->get['order_product_id'];
                    } else {
                        $order_product_id = 0;
                    }
              
                    $order_product_info = $this->model_account_order->getOrderProduct($order_id, $order_product_id);

                    if ($order_product_info) {
                        $this->load->model('catalog/product');
                
                        $product_info = $this->model_catalog_product->getProduct($order_product_info['product_id']);
                
                        if ($product_info) {
                            if ((float)$product_info['special']) {
                                $price = $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                            } else {
                                $price = $this->currency->format($this->tax->calculate($product_info['price'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                            }

                            $price = $price * $order_product_info['quantity'];

                            $contents = array(
                                'id'       => $product_info['product_id'],
                                'quantity' => $order_product_info['quantity']
                            );

                            $facebook_conversion_event_params = array(
                                'event_name'    => $event_name,
                                'content_ids'   => array((string)$product_info['product_id']),
                                'content_name'  => $this->formatString($product_info['name']),
                                'content_type'  => 'product',
                                'contents'      => $contents,
                                'currency'      => strtoupper($this->session->data['currency']),
                                'value'         => $this->currency->format($this->tax->calculate($price, $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false),
                                'event_id'      => $event_id
                            );
                        }
                    }
                }

                break;

            case 'checkout/checkout':
                 $event_name = 'InitiateCheckout';

                $this->load->language('checkout/checkout');

                $contents = array();
                $content_ids = array();
                $value = 0;
                $num_items = 0;

                foreach ($this->cart->getProducts() as $product) {
                    $content_ids[] = (string)$product['product_id'];
                    $value += $this->currency->format($this->tax->calculate($product['total'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                    $num_items += $product['quantity'];
                    $contents[] = array(
                        'id'       => $product['product_id'],
                        'quantity' => $product['quantity']
                    );
                }

                $facebook_pixel_event_params = array(
                    'event_name'    => $event_name,
                    'content_name'  => $this->formatString($this->language->get('heading_title')),
                    'content_ids'   => $content_ids,
                    'content_type'  => 'product',
                    'contents'      => $contents,
                    'currency'      => strtoupper($this->session->data['currency']),
                    'num_items'     => $num_items,
                    'value'         => $value,
                    'event_id'      => $event_id
                );

                break;
    
            case 'product/search':
                $event_name = 'Search';

                $this->load->model('catalog/product');
                $this->load->language('product/search');

                if (isset($this->request->get['search'])) {
                    $search = $this->request->get['search'];
                } else {
                    $search = '';
                }

                if (isset($this->request->get['tag'])) {
                    $tag = $this->request->get['tag'];
                } elseif (isset($this->request->get['search'])) {
                    $tag = $this->request->get['search'];
                } else {
                    $tag = '';
                }

                if (isset($this->request->get['description'])) {
                    $description = $this->request->get['description'];
                } else {
                    $description = '';
                }
            
                if (isset($this->request->get['category_id'])) {
                    $category_id = $this->request->get['category_id'];
                } else {
                    $category_id = 0;
                }
            
                if (isset($this->request->get['sub_category'])) {
                    $sub_category = $this->request->get['sub_category'];
                } else {
                    $sub_category = '';
                }

                $page_filter_data = array(
                    'filter_name'         => $search,
                    'filter_tag'          => $tag,
                    'filter_description'  => $description,
                    'filter_category_id'  => $category_id,
                    'filter_sub_category' => $sub_category
                );

                $filter_data = $this->getFilterData($page_filter_data);

                $products = $this->model_catalog_product->getProducts($filter_data);

                $contents = array();
                $content_ids = array();
                $value = 0.0;
                $num_items = 0;

                foreach ($products as $product) {
                    $content_ids[] = $product['product_id'];

                    if ((float)$product['special']) {
                        $value += $this->currency->format($this->tax->calculate($product['special'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                    } else {
                        $value += $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                    }

                    $num_items++;
                    $contents[] = array(
                        'id'        => $product['product_id'],
                        'quantity'  => 1
                    );
                }

                if (isset($this->request->get['search'])) {
                    $search_string = $this->request->get['search'];
                } elseif (isset($this->request->get['tag'])) {
                    $search_string = $this->request->get['tag'];
                } else {
                    $search_string = '';
                }

                $facebook_conversion_event_params = array(
                    'event_name'    => $event_name,
                    'content_ids'   => $content_ids,
                    'content_name'  => $this->formatString($this->language->get('heading_title')),
                    'content_type'  => 'product',
                    'contents'      => $contents,
                    'currency'      => strtoupper($this->session->data['currency']),
                    'search_string' => $search_string,
                    'value'         => $value,
                    'num_items'     => $num_items,
                    'event_id'      => $event_id
                );

                break;

            case 'product/category':
                $event_name = 'ViewCategory';

                $this->load->model('catalog/category');

                if (isset($this->request->get['path'])) {
                    $category_id = $this->request->get['path'];
                } else {
                    $category_id = 0;
                }

                $category_info = $this->model_catalog_category->getCategory($category_id);

                if ($category_info) {
                    if (isset($this->request->get['filter'])) {
                        $filter = $this->request->get['filter'];
                    } else {
                        $filter = '';
                    }

                    $page_filter_data = array(
                        'filter_category_id'     => $category_id,
                        'filter_filter'          => $filter,
                    );

                    $filter_data = $this->getFilterData($page_filter_data);

                    $products = $this->model_catalog_product->getProducts($filter_data);

                    $contents = array();
                    $content_ids = array();
                    $value = 0.0;
                    $num_items = 0;
    
                    foreach ($products as $product) {
                        $content_ids[] = $product['product_id'];
    
                        if ((float)$product['special']) {
                            $value += $this->currency->format($this->tax->calculate($product['special'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                        } else {
                            $value += $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                        }
    
                        $num_items++;
                        $contents[] = array(
                            'id'       => $product['product_id'],
                            'quantity' => 1,
                        );
                    }

                    $facebook_conversion_event_params = array(
                        'event_name'        => $event_name,
                        'content_name'      => $this->formatString($category_info['name']),
                        'content_category'  => $this->formatString($category_info['name']),
                        'content_ids'       => $content_ids,
                        'content_type'      => 'product',
                        'contents'          => $contents,
                        'currency'          => strtoupper($this->session->data['currency']),
                        'value'             => $value,
                        'num_items'         => $num_items,
                        'event_id'          => $event_id
                    );
                } else {
                    $facebook_conversion_event_params = array(
                        'event_name'        => $event_name,
                        'event_id'          => $event_id
                    );
                }
              
                break;

            case 'account/wishlist':
                $event_name = 'AddToWishlist';

                $this->load->language('account/wishlist');

                if (version_compare(VERSION, '2.0.3.1') <= 0) {
                    if (isset($this->session->data['wishlist'])) {
                        $wishlist = array_map(
                            function($product_id) {
                                return array('product_id' => $product_id);
                            },
                            $this->session->data['wishlist']
                        );
                    } else {
                        $wishlist = array();
                    }
                } else {
                    $this->load->model('account/wishlist');

                    $wishlist = $this->model_account_wishlist->getWishlist();
                }

                $this->load->model('catalog/product');

                $contents = array();
                $content_ids = array();
                $value = 0.0;
                $num_items = 0;

                foreach ($wishlist as $data) {
                    $product_info = $this->model_catalog_product->getProduct($data['product_id']);

                    if ($product_info) {
                        $content_ids[] = $product_info['product_id'];
                        
                        if ((float)$product_info['special']) {
                            $value += $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                        } else {
                            $value += $this->currency->format($this->tax->calculate($product_info['price'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                        }

                        $num_items++;

                        $contents[] = array(
                            'id'       => $product_info['product_id'],
                            'quantity' => 1
                        );
                    }
                }

                $facebook_conversion_event_params = array(
                    'event_name'    => $event_name,
                    'content_name'  => $this->formatString($this->language->get('heading_title')),
                    'content_ids'   => $content_ids,
                    'content_type'  => 'product',
                    'contents'      => $contents,
                    'currency'      => strtoupper($this->session->data['currency']),
                    'value'         => $value,
                    'num_items'     => $num_items,
                    'event_id'      => $event_id
                );

                break;

            case 'account/success':
                $event_name = 'CompleteRegistration';

                if ($this->customer->isLogged()) {
                    $this->language->load('account/success');

                    $facebook_conversion_event_params = array(
                        'event_name'   => $event_name,
                        'content_name' => $this->formatString($this->language->get('heading_title')),
                        'currency'     => strtoupper($this->session->data['currency']),
                        'status'       => true,
                        'event_id'     => $event_id
                    );
                }

                break;
    
            case 'information/contact/success':
                $event_name = 'Contact';

                $facebook_conversion_event_params = array(
                    'event_name' => $event_name,
                    'event_id'   => $event_id
                );

                break;
            
            case 'product/manufacturer/info':
                $event_name = 'ViewBrand';

                if (isset($this->request->get['manufacturer_id'])) {
                    $manufacturer_id = $this->request->get['manufacturer_id'];
                } else {
                    $manufacturer_id = 0;
                }

                if ($manufacturer_id) {
                    $this->load->model('catalog/manufacturer');

                    $manufacturer_info = $this->model_catalog_manufacturer->getManufacturer($manufacturer_id);

                    if ($manufacturer_info) {
                        $this->load->model('catalog/product');

                        $page_filter_data = array(
                            'filter_manufacturer_id'     => $manufacturer_id
                        );
    
                        $filter_data = $this->getFilterData($page_filter_data);
                        
                        $products = $this->model_catalog_product->getProducts($filter_data);

                        $contents = array();
                        $content_ids = array();
                        $value = 0.0;
                        $num_items = 0;
        
                        foreach ($products as $product) {
                            $content_ids[] = $product['product_id'];
        
                            if ((float)$product['special']) {
                                $value += $this->currency->format($this->tax->calculate($product['special'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                            } else {
                                $value += $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], '', false);
                            }
        
                            $num_items++;
                            $contents[] = array(
                                'id'       => $product['product_id'],
                                'quantity' => 1,
                            );
                        }

                        $facebook_conversion_event_params = array(
                            'event_name'        => $event_name,
                            'content_name'      => $this->formatString($manufacturer_info['name']),
                            'content_category'  => $this->formatString($manufacturer_info['name']),
                            'content_ids'       => $content_ids,
                            'content_type'      => 'product',
                            'contents'          => $contents,
                            'currency'          => strtoupper($this->session->data['currency']),
                            'value'             => $value,
                            'num_items'         => $num_items,
                            'event_id'          => $event_id
                        );
                    } else {
                        $facebook_conversion_event_params = array(
                            'event_name'        => $event_name,
                            'event_id'          => $event_id
                        );
                    }
                }

                break;
										 $this->trackConversion($facebook_conversion_event_params, $event_name, $event_id);
        }
    
       

    }
    
    
    public function getPii() {
        $facebook_pixel_pii = array();

            if ($this->customer->isLogged()) {
                $customer_id = $this->customer->getId();
                $email = $this->customer->getEmail();
                $firstname = $this->customer->getFirstName();
                $lastname = $this->customer->getLastName();
                $telephone = $this->customer->getTelephone();
            } elseif (isset($this->session->data['guest'])) {
                $customer_id = '';
                $email = isset($this->session->data['guest']['email']) ? $this->session->data['guest']['email'] : '';
//                $firstname = isset($this->session->data['guest']['firstname']) ? $this->session->data['guest']['firstname'] : '';
//                $lastname = isset($this->session->data['guest']['lastname']) ? $this->session->data['guest']['lastname'] : '';
                $telephone = isset($this->session->data['guest']['telephone']) ? $this->session->data['guest']['telephone'] : '';
            } else {
                $customer_id = '';
                $email = '';
                $firstname = '';
                $lastname = '';
                $telephone = '';
            }
          

            if ($this->customer->isLogged()) {
                if ($email) {
                    $facebook_pixel_pii['em'] = htmlspecialchars($email, ENT_QUOTES, 'UTF-8');
                }

//                if ($firstname) {
//                    $facebook_pixel_pii['fn'] = htmlspecialchars($firstname, ENT_QUOTES, 'UTF-8');
//                }
//
//                if ($lastname) {
//                    $facebook_pixel_pii['ln'] = htmlspecialchars($lastname, ENT_QUOTES, 'UTF-8');
//                }

                if ($telephone) {
                    $facebook_pixel_pii['ph'] = htmlspecialchars($telephone, ENT_QUOTES, 'UTF-8');
                }

            }

        return $facebook_pixel_pii;
    }
    
    public function trackConversion($server_event_params, $event_name, $event_id) {

        if ($event_name == 'Purchase' && empty($server_event_params['content_ids'])) {
            return;
        }
        $pixel_id = '2763076770394844';
        $access_token = 'EAAVx5SgMs88BAF6fdQw2sa0ZCyNVoKQLiMeLxlp4wPSgwueJTNPq0rzTgazX6caToCBL9M1LPPmApHWvRLJ3paHEFDc9RBeBlsm5AhF6no9VVDmU64EqAF4mg1WLcFzuIfuB5m1Yc68Rz3PuH8Sni1pjIH4X6tHwcwjOaG2YYDEHTmdqppdouCgtIWlkZD';
       
        $agent_data = json_decode($this->getAgentParameters(), true); 
        $agent = $agent_data['agent'];
        $user_pii_data = $this->getPii();
 

        try {
            $user_data = (new UserData())
                ->setClientIpAddress(Util::getIpAddress())
                ->setClientUserAgent(Util::getHttpUserAgent())
                ->setFbp(Util::getFbp())
                ->setFbc(Util::getFbc());

            if ($user_pii_data) {
                if (!empty($user_pii_data['em'])) {
                    $user_data->setEmail(hash('sha256', $user_pii_data['em']));
                }

//                if (!empty($user_pii_data['fn'])) {
//                    $user_data->setFirstName(hash('sha256', $user_pii_data['fn']));
//                }
//
//                if (!empty($user_pii_data['ln'])) {
//                    $user_data->setLastName(hash('sha256', $user_pii_data['ln']));
//                }

                if (!empty($user_pii_data['ph'])) {
                    $user_data->setPhone(hash('sha256', $user_pii_data['ph']));
                }

            }

            $event = (new Event())
                ->setEventName($event_name)
                ->setEventTime(time())
                ->setEventId($event_id)
                ->setEventSourceUrl(Util::getRequestUri())
                ->setActionSource(ActionSource::WEBSITE)
                ->setUserData($user_data)
                ->setDataProcessingOptions(array())
                ->setDataProcessingOptionsCountry(0)
                ->setDataProcessingOptionsState(0)
                ->setCustomData(new CustomData());

            $custom_data = $event->getCustomData();

            if (!empty($server_event_params['currency'])) {
                $custom_data->setCurrency($server_event_params['currency']);
            }

            if (!empty($server_event_params['value'])) {
                $custom_data->setValue($server_event_params['value']);
            }

            if (!empty($server_event_params['content_ids'])) {
                $custom_data->setContentIds($server_event_params['content_ids']);
            }

            if (!empty($server_event_params['content_type'])) {
                $custom_data->setContentType($server_event_params['content_type']);
            }

            if (!empty($server_event_params['event_name'])) {
                $custom_data->setContentType($server_event_params['event_name']);
            }

            if (!empty($server_event_params['content_name'])) {
                $custom_data->setContentType($server_event_params['content_name']);
            }
  

        } catch (Exception $ex) {
            die('Fail to create server event');
            $this->log->write('Facebook Business Extension :: Fail to create server event!');
            return false;
        }

        $api = Api::init(null, null, $access_token, false);

//        $events = array();
//        array_push($events, $event);
//        var_dump($events);
//        die;
//        $request = (new EventRequest($pixel_id))
//            ->setEvents(array($event))
//            ->setTestEventCode('TEST38540');
//            $response = $request->execute();
    
       $async_request = (new EventRequestAsync($pixel_id))
                  ->setEvents(array($event))
                  ->setPartnerAgent($agent);

            return $async_request->execute()
              ->then(
                null,
                function(\Exception $ex) {
                  $this->log->write('Facebook Business Extension :: Fail to send server event! Error Message: ' . $ex->getMessage());
                }
              );
        
    }
    
    private function formatAndTrimString($text, $length = false) {
        if ($text) {
            $text = trim(strip_tags(html_entity_decode(html_entity_decode($text), ENT_QUOTES | ENT_COMPAT, 'UTF-8')));

            if ($length && strlen($text) > $length) {
                $text = substr($text, 0, $length);
            }

            $text = '"' . str_replace('"', '""', $text) . '"';

            return $text;
        } else {
            return '""';
        }
    }

    private function getStoreBaseUrl() {
        if ($this->config->get('config_ssl')) {
            return HTTP_SERVER;
        } else {
            return HTTPS_SERVER;
        }
    }
  
    private function formatProductDetails($product_info) {
        $special_info = $this->model_extension_module_facebook_events->getProductSpecials($product_info['product_id']);

        if ($special_info) {
            $product_info = array_merge($product_info, $special_info);
        }

        $formatted_product_details = array(
            'retailer_id'                 => $product_info['product_id'],
            'name'                        => $this->getName($product_info),
            'description'                 => $this->getDescription($product_info),
            'image_url'                   => $this->formatAndTrimString($this->getImageUrl($product_info['image'])),
            'product_url'                 => $this->getProductUrl($product_info['product_id']),
            'category'                    => $this->getCategory($product_info),
            'brand'                       => $this->getBrand($product_info),
            'price'                       => $this->getPrice($product_info),
            'availability'                => $this->getAvailability($product_info),
            'retailer_product_group_id'   => $product_info['product_id'],
            'additional_image_urls'       => $this->getAdditionalImageUrls($product_info['product_id']),
            'special'                     => $this->getSpecialPrice($product_info),
            'special_period'              => $this->getSpecialPricePeriod($product_info),
            'condition'                   => $this->getCondition($product_info['product_id'])
        );

        $additional_details = $this->getAdditionalDetails($product_info['product_id']);
        $formatted_product_details = array_merge($formatted_product_details, $additional_details);

        // Ensure that the product checks all requirements for the product feed
        if (in_array(false, $formatted_product_details, true) === true) {
            return false;
        } else {
            return $formatted_product_details;
        }
    }

    private function getName($product_info) {
        return $this->formatAndTrimString($product_info['name'], 150);
    }

    private function getDescription($product_info) {
        $description = $this->formatAndTrimString($product_info['description'], 5000);

        // Fallback to Meta Description if description is not available
        if (!$description) {
            $description = $this->formatAndTrimString($product_info['meta_description'], 5000);
        }

        // Fallback to Product Name if Description and Meta Description are not available
        if (!$description) {
            $description = $this->formatAndTrimString($product_info['name'], 5000);
        }

        // Check if description length is less than 30 characters
        if (strlen($description) < 30) {
            return false;
        }

        // If description doesn't contain non-English characters, check if all Uppercase
        if (strlen($description) == strlen(utf8_decode($description))) {
            if (strtoupper($description) == $description) {
                $description = ucfirst(strtolower($description));
            }
        }

        return $description;
    }

    private function getImageUrl($image) {
        // Cater for cases where the image is an external URL
        if (filter_var($image, FILTER_VALIDATE_URL)) {
            return $image;
        } else {
            return $this->getStoreBaseUrl() . 'image/' . $image;
        }
    }

    private function getAdditionalImageUrls($product_id) {
        $formatted_images = '';

        $product_images = $this->model_catalog_product->getProductImages($product_id);

        // Limit of up to 20 images
        $product_images = array_slice($product_images, 0, 20);

        foreach ($product_images as $product_image) {
            $image_url = $this->getImageUrl($product_image['image']);

            // Limit of up to 2000 characters
            if (strlen($formatted_images . $image_url) < 2000) {
                if ($formatted_images) {
                    $formatted_images .= ',' . $image_url;
                } else {
                    $formatted_images .= $image_url;
                }
            } else {
                break;
            }
        }

        return $this->formatAndTrimString($formatted_images);
    }

    private function getProductUrl($product_id) {
        $product_url = $this->url->link('product/product', 'product_id=' . (int)$product_id, true);

        return $this->formatAndTrimString($product_url);
    }

    private function getCategory($product_info) {
        $product_to_facebook = $this->model_extension_module_facebook_events->getProductToFacebook($product_info['product_id']);

        if ($product_to_facebook['google_product_category']) {
            return $product_to_facebook['google_product_category'];
        } else {
            $category = $product_info['category_name'];

            if (!$category) {
                $category = $this->config->get('config_name');
            }
    
            return $this->formatAndTrimString($category);
        }
    }

    private function getBrand($product_info) {
        if ($product_info['manufacturer_name']) {
            $brand = $product_info['manufacturer_name'];
        } else {
            $brand = $this->config->get('config_name');
        }

        return $this->formatAndTrimString($brand);
    }

    private function getPrice($product_info) {
        if ($product_info['tax_class_id']) {
            $price = $this->tax->calculate($product_info['price'], $product_info['tax_class_id'], $this->config->get('config_tax'));
        } else {
            $price = $product_info['price'];
        }

        $price = number_format(round((float)$price, 2), 2, '.', '');
        $price = $price . ' ' . strtoupper($this->config->get('config_currency'));

        return $price;
    }

    private function getSpecialPrice($product_info) {
        if (!empty($product_info['special']) && $this->config->get('facebook_events_sync_specials_status')) {
            if ($product_info['tax_class_id']) {
                $special = $this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax'));
            } else {
                $special = $product_info['special'];
            }

            $special = number_format(round((float)$special, 2), 2, '.', '');
            $special = $special . ' ' . strtoupper($this->config->get('config_currency'));
        } else {
            $special = '""';
        }

        return $special;
    }

    private function getSpecialPricePeriod($product_info) {
        if (!empty($product_info['special']) && $this->config->get('facebook_events_sync_specials_status') && !empty($product_info['special_date_start']) && !empty($product_info['special_date_end'])
          && $product_info['special_date_start'] != '0000-00-00' && $product_info['special_date_end'] !='0000-00-00') {
            $datetime_start = new DateTime($product_info['special_date_start']);
            $datetime_end = new DateTime($product_info['special_date_end']);
            $special_date_start = $datetime_start->format('Y-m-d') . 'T00:00+00:00';
            $special_date_end = $datetime_end->format('Y-m-d') . 'T23:59+00:00';

            $special_price_period = $special_date_start . '/' . $special_date_end;

            return $this->formatAndTrimString($special_price_period);
        } else {
            return '""';
        }
    }

    public function getAvailability($product_info) {
        if ($product_info['quantity'] <= 0 && $product_info['subtract']) {
            $availability = 'out of stock';
        } else {
            $availability = 'in stock';
        }
    
        return $availability;
    }

    private function getCondition($product_id) {
        $product_to_facebook = $this->model_extension_module_facebook_events->getProductToFacebook($product_id);

        if ($product_to_facebook) {
            if ($product_to_facebook['condition']) {
                return $product_to_facebook['condition'];
            }
        }

        return 'new';
    }

    private function getAdditionalDetails($product_id) {
        $additional_details = array();

        $product_to_facebook = $this->model_extension_module_facebook_events->getProductToFacebook($product_id);

        if ($product_to_facebook) {
            foreach ($product_to_facebook as $key => $value) {
                if ($key == 'google_product_category' || $key == 'condition') {
                    continue;
                } else {
                    if ($value) {
                        $additional_details[$key] = $this->formatAndTrimString($value);
                    } else {
                        $additional_details[$key] = '';
                    }
                }
            }
        }

        return $additional_details;
    }

    public function getAgentParameters() {
        $plugin_agent_name = 'exopencart';
        $opencart_version = VERSION;
        $plugin_version = $this->getPluginVersion();
    
        $agent_string = sprintf('%s-%s-%s', $plugin_agent_name, $opencart_version, $plugin_version);

        $facebook_pixel_params = array('agent' => $agent_string);

        return json_encode($facebook_pixel_params, JSON_PRETTY_PRINT | JSON_FORCE_OBJECT);
    }

    public function getPluginVersion() {
        return $this->pluginVersion;
    }

    public function formatString($string) {
        return trim(strip_tags(html_entity_decode(html_entity_decode($string), ENT_QUOTES | ENT_COMPAT, 'UTF-8')));
    }

    private function getFilterData($page_filter_data = array()) {
        if (isset($this->request->get['sort'])) {
            $sort = $this->request->get['sort'];
        } else {
            $sort = 'p.sort_order';
        }

        if (isset($this->request->get['order'])) {
            $order = $this->request->get['order'];
        } else {
            $order = 'ASC';
        }

        if (isset($this->request->get['page'])) {
            $page = $this->request->get['page'];
        } else {
            $page = 1;
        }

        if (isset($this->request->get['limit'])) {
            $limit = (int)$this->request->get['limit'];
        } else {
            $limit = $this->config->get($this->config->get('config_theme') . '_product_limit');
        }

        $general_filter_data = array(
            'sort'                => $sort,
            'order'               => $order,
            'start'               => ($page - 1) * $limit,
            'limit'               => $limit
        );

        if ($page_filter_data) {
            $filter_data = array_merge($page_filter_data, $general_filter_data);
        } else {
            $filter_data = $general_filter_data;
        }

        return $filter_data;
    }

    public function generateEventId() {
        $data = openssl_random_pseudo_bytes(16);

        $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10

        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
    }
    

}