<?php
class ModelExtensionModulePromotion extends Model {

	public function getManufacIDbyProdID($product_id){
		$query = $this->db->query('SELECT manufacturer_id FROM ps_product WHERE product_id='.$product_id)->row;

		return $query['manufacturer_id']; //
	}

	public function getPromotion($promotion_id) {
		$query = $this->db->query("SELECT setting FROM " . DB_PREFIX . "module WHERE code = 'promotion' AND module_id = '".$this->db->escape($promotion_id)."' LIMIT 1");
		$data = array();

		if($query->num_rows > 0) {
			if(version_compare(VERSION, '2.1.0.0', '<')) {
        		$settings = unserialize($query->row['setting']);
        	} else {
        		$settings = json_decode($query->row['setting'], true);
        	}

        	if($settings['status'] == 'yes' && isset($settings['information_page']['status']) && $settings['information_page']['status'] == 'yes') {
        		$data = $settings;
        	}

        	if(isset($settings['general_settings']['name'][(int)$this->config->get('config_language_id')])) {
    			$data[$key]['name'] = $settings['general_settings']['name'][(int)$this->config->get('config_language_id')];
    		}

        	$data['included_products'] = $this->getAllProductsFromPromotion($settings);

		}

		return $data;
	}

	public function getTotalPromotions() {
		$query = $this->db->query("SELECT count(*) as counter FROM " . DB_PREFIX . "module WHERE code = 'promotion'");

		return $query->row ? $query->row['counter'] : 0;
	}

	public function getAllPromotions($page, $limit){

		$this->load->model('tool/image');

		$this->config->load('isenselabs/promotion');
		$modulePath = $this->config->get('promotion_modulePath');
		
		$start = ($page - 1) * $limit;

		$sql = "SELECT setting,module_id FROM " . DB_PREFIX . "module WHERE code = 'promotion' ORDER BY module_id LIMIT ".$this->db->escape($start).",".$this->db->escape($limit);

		$query = $this->db->query($sql);

		$data = array();

		foreach ($query->rows as $key => $value) {

			if(version_compare(VERSION, '2.1.0.0', '<')) {
        		$settings = unserialize($value['setting']);
        	} else {
        		$settings = json_decode($value['setting'], true);
        	}

        	//STARTDATE
			if(isset($settings['general_settings']['StartDate']) && !empty($settings['general_settings']['StartDate'])){
				if(strtotime($settings['general_settings']['StartDate']) > strtotime(date('Y-m-d'))){
					continue;
				}
			}
			//ENDDATE
			if(isset($settings['general_settings']['EndDate']) && !empty($settings['general_settings']['EndDate'])){
				if(strtotime($settings['general_settings']['EndDate']) < strtotime(date('Y-m-d'))){
					continue;
				}
			}

        	if($settings['status'] == 'yes' && isset($settings['information_page']['status']) && $settings['information_page']['status'] == 'yes') {
        		$data[$key] = $settings;
        		$data[$key]['module_id'] = $value['module_id'];
        		$data[$key]['page_link'] = $this->url->link($modulePath.'/view', 'promotion_id='.$value['module_id'], 'SSL');

        		if(isset($settings['general_settings']['name'][(int)$this->config->get('config_language_id')])) {
        			$data[$key]['name'] = $settings['general_settings']['name'][(int)$this->config->get('config_language_id')];
        		}

        		$image_width = 268; $image_height = 180;
        		if(isset($settings['information_page']['small_image_width'])) {
					$image_width = $settings['information_page']['small_image_width'];
				}

				if(isset($settings['information_page']['small_image_height'])) {
					$image_height = $settings['information_page']['small_image_height'];
				}

        		if(isset($settings['information_page']['image']) && !empty($settings['information_page']['image'])){
        			$data[$key]['image'] = $this->model_tool_image->resize($settings['information_page']['image'], $image_width, $image_height);
        		} else {
        			$data[$key]['image'] = $this->model_tool_image->resize('no_image.png', $image_width, $image_height);
        		}
        		
        	}
		}

		return $data;

	}

	public function getPromotions(){

		$query = $this->db->query("SELECT setting,module_id FROM ps_module WHERE code = 'promotion' ");

		$data = array();
		foreach ($query->rows as $key => $value) {


		    $data[$key] = json_decode($value['setting'], true);

			$data[$key]['module_id'] = $value['module_id'];
		}
		
		usort($data, function($a, $b) {
			if ($a['general_settings']['sort_order'] == $b['general_settings']['sort_order']) {
	            return 0;
	        }
	        return ($a['general_settings']['sort_order'] > $b['general_settings']['sort_order']) ? +1 : -1;
		});

		usort($data, function($a, $b) {
			$var1 = ($a['general_settings']['stackable'] == 'no') ? 15000 :  $a['general_settings']['sort_order'];
			$var2 = ($b['general_settings']['stackable'] == 'no') ? 15000 :  $b['general_settings']['sort_order'];

			if ($var1 == $var2) {
				if ($a['general_settings']['sort_order'] == $b['general_settings']['sort_order']) {
	            	return 0;
	        	}
	        	return ($a['general_settings']['sort_order'] > $b['general_settings']['sort_order']) ? +1 : -1;
	        }

	        if($var1 == 15000 || $var2 == 15000) {
	        	return ($var1 < $var2) ? +1 : -1;
	        } else {
	        	return ($var1 > $var2) ? +1 : -1;
	        }

		});

		return $data;

	}

	public function getImageConfigs($name) {
		if(version_compare(VERSION, '2.2.0.0', '<')) {
			return $this->config->get($name);
		} else {
			if(strpos($name, 'config_image') !== false){
				$name = str_replace('config', '', $name);
				return $this->config->get($this->config->get('config_theme') . $name);
			}
		}	
	}

	public function getPromotionsFromProductID($product_id) {

		$data = $this->getPromotions();
		$promotions = array();
		$button = false;

		$modulePath = 'extension/module/promotion';
		$this->load->model('tool/image');
		$this->load->model('extension/module/promotion');

		$image_width = $this->getImageConfigs('config_image_related_width');
		$image_height = $this->getImageConfigs('config_image_related_height');

		foreach ($data as $promo) {
			$promo_data = array();
			$promo_data['module_id'] 	= $promo['module_id'];
			$promo_data['name'] 		= $promo['name'];

			if($promo['status'] == 'no' || !isset($promo['information_page']['status']) || $promo['information_page']['status'] == 'no') continue;

			if(!isset($promo['information_page']['link_promotion']) || $promo['information_page']['link_promotion'] == 'no') continue;

			if(isset($promo['information_page']['small_image_width'])) {
				$image_width = $promo['information_page']['small_image_width'];
			}

			if(isset($promo['information_page']['small_image_height'])) {
				$image_height = $promo['information_page']['small_image_height'];
			}

			if(!isset($promo['information_page']['button_link']) || $promo['information_page']['button_link'] == 'yes') {
				$button = true;
			}

			$promo_data['link']			= $this->url->link($modulePath.'/view', 'promotion_id='.$promo['module_id'], 'SSL');
			$promo_data['image'] 		= $this->model_tool_image->resize($promo['information_page']['image'] , $image_width, $image_height);

			$promo_data['description'] 	= $promo['information_page']['description'][$this->config->get('config_language')];

			foreach ($promo['actions'] as $promo_action) {
				switch ($promo_action['mainSelect']) {
					case 'discount_all_products':
						$promotions[] = $promo_data; break 2; continue 2;
				}
			}

			foreach ($promo['conditions'] as $promo_cond) {
				switch ($promo_cond['condSelect']) {
					case 'product_name': 
						if($promo_cond['product_id'] == $product_id) {
							$promotions[] = $promo_data;
							break 2;
						} 
						break;
					case 'category_name': 
						$this->load->model('catalog/product');
						$this->load->model('catalog/category');
						$cats = $this->model_catalog_product->getCategories($product_id);
						$categories_ids = array();
						foreach ($cats as $key => $category) {
							$categories_ids[] = $category['category_id'];
							$parent_cats = $this->model_catalog_category->getCategories($category['category_id']);
							foreach ($parent_cats as $more_cats) {
								$categories_ids[] = $more_cats['category_id'];
							}		
						}
						if (in_array($promo_cond['category_id'], $categories_ids)) {
							$promotions[] = $promo_data;
							break 2;
						} 
						break;
					case 'manufac_name': 
						if( $this->getManufacIDbyProdID($product_id) == $promo_cond['manufacturer_id']) {
							$promotions[] = $promo_data;
							break 2;
						} 
						break;
				}
			}


		}

		return array('promotions' => $promotions, 'button' => $button);
	}

	public function getTotalUses($promotion_id){
		$query = $this->db->query("SELECT customer_id FROM " . DB_PREFIX . "promotion WHERE promotion_id=".(int)$promotion_id)->rows;
	
		$uses['guests'] = 0;
		$uses['customers'] = array();
		foreach ($query as $value) {
			if($value['customer_id'] == 0) $uses['guests']++;
			else {
				$uses['customers'][] = $value['customer_id'];
			} 
		}
		$uses['total'] = $uses['guests']+count($uses['customers']);

		return $uses;
		
	}

	public function getAllProductsFromPromotion($settings) {
		$products = array();
		$categories = array();
		$manufacturers = array(); 

		foreach ($settings['conditions'] as $cond) {
			if($cond['condSelect'] == 'category_name' && isset($cond['category_id'])) $categories[] = $cond['category_id'];
			if($cond['condSelect'] == 'product_name'  && isset($cond['product_id'])) $products[] = $cond['product_id'];
			if($cond['condSelect'] == 'manufac_name'  && isset($cond['manufacturer_id'])) $manufacturers[] = $cond['manufacturer_id'];
		}

		foreach ($settings['actions'] as $action) {
			if($action['mainSelect'] == 'discount_on_products') {
				foreach ($action['product'] as $product_id) {
					$products[] = $product_id;
				}
			}

			if($action['mainSelect'] == 'discount_on_categories') {
				foreach ($action['category'] as $cat_id) {
					$categories[] = $cat_id;
				}
			}
		}

		$products 		= array_unique($products);
		$categories 	= array_unique($categories);
		$manufacturers 	= array_unique($manufacturers);

		return array('product_ids' => $products, 'category_ids' => $categories, 'manufacturer_ids' => $manufacturers);
	}

	public function getCategories($parent_id = 0) {
		$query = $this->db->query("SELECT c.category_id FROM " . DB_PREFIX . "category c LEFT JOIN " . DB_PREFIX . "category_description cd ON (c.category_id = cd.category_id) LEFT JOIN " . DB_PREFIX . "category_to_store c2s ON (c.category_id = c2s.category_id) WHERE c.parent_id = '" . (int)$parent_id . "' AND cd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND c2s.store_id = '" . (int)$this->config->get('config_store_id') . "'  AND c.status = '1' ORDER BY c.sort_order, LCASE(cd.name)");

		$cats = array();
		foreach ($query->rows as $key => $value) {
			$cats[] = $value['category_id'];
		}

		return $cats;
	}

	public function getCategoryParent($category_id) {
		$query = $this->db->query("SELECT parent_id FROM " . DB_PREFIX . "category WHERE category_id=".(int)$category_id);
		$cats = array();
		$last = 0;

		while($query->num_rows > 0) {
			$last = 0;
			foreach ($query->rows as $key => $value) {
				if($value['parent_id'] != 0) {
					$cats[] = $value['parent_id'];
					$last = $value['parent_id'];
				}
			}
			$query = $this->db->query("SELECT parent_id FROM " . DB_PREFIX . "category WHERE category_id=".(int)$last);
		}
		return $cats;
	}

	public function getProductTax($id, $discount, $quantity = 1) {

		$moduleSettings = $this->config->get('promotion');
		
		if(!isset($moduleSettings['discount_to_taxes']) || $moduleSettings['discount_to_taxes'] != 'yes') {
			return 0;
		}

		$product = $this->getProductInCart($id);
		$tax = 0;
		if ($product['tax_class_id']) {
			$tax_rates = $this->tax->getRates($product['total'] - ($product['total'] - $discount), $product['tax_class_id']);

			foreach ($tax_rates as $tax_rate) {
				if ($tax_rate['type'] == 'P') {
					$tax -= $tax_rate['amount'] * $quantity;
				}
			}

			return $tax;
		}

		return false;
	}

	public function checkProductInCart($id, $quantity = 1){
		$cartProducts = $this->cart->getProducts();
		$id = array_search($id , array_column1($cartProducts, 'product_id'));
		if($id === false ) return false;
		$product = $cartProducts[$id];
		if($product['quantity'] < $quantity) return false;
		return true;
	}

	public function checkProductInCartWithOptions($id, $quantity = 1, $option_id, $option_value_id){

		$cartProducts = $this->cart->getProducts();

		$foundItem = true;

		foreach ($cartProducts as $key => $product) {

			if($product['product_id'] == $id) {
				if($product['quantity'] >= $quantity) $foundItem = true;

				if($product['option'] && !empty($option_id)) {
					foreach ($product['option'] as $option_data) {
						if($option_data['option_id'] == $option_id) {
							if(!empty($option_value_id) && $option_data['option_value_id'] == $option_value_id) {
								$foundItem = true;
							} else {
								$foundItem = false;
							}
						} else {
							$foundItem = false;
						}
					}
				} 
			} else {
				$foundItem = false;
			}

			if($foundItem) return true;
		}
		
		return false;
	}

	private function getProductInCart($id){
        if($this->checkProductInCart($id)){
            $cartProducts = $this->cart->getProducts();

            $product = array();

            foreach ($cartProducts as $key => $product_in_cart) {
                if($product_in_cart['product_id'] == $id) {
                    if(!empty($product)) {
                        $product['quantity']+= $product_in_cart['quantity'];
                    } else {
                        $product = $product_in_cart;
                    }
                }
            }

            return !empty($product) ? $product : false;
        } 
        return false;
    }

	public function getProductInCartPrice($id, $notax = true){
		$moduleSettings = $this->config->get('promotion');
		$product = $this->getProductInCart($id);
		if($product){

				if($notax == false) {
					return  $this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax'));
				}

				if(!isset($moduleSettings['discount_to_taxes']) || $moduleSettings['discount_to_taxes'] != 'yes') {
					return $this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax'));
				} else {
					return $product['price'];
				} 
		} 

		return false;
	}

	public function getProductInCartQuantity($id){
		$product = $this->getProductInCart($id);
		if($product){
			return $product['quantity'];
		}
		return false;
	}

	public function isSpecialProduct($product_id) {
		$product_special_query = $this->db->query("SELECT ps.price FROM `" . DB_PREFIX . "product_special` ps LEFT JOIN `" . DB_PREFIX . "product_to_store` p2s ON (ps.product_id=p2s.product_id) WHERE ps.product_id = '" . (int)$product_id . "' AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' AND ((date_start = '0000-00-00' OR date_start < NOW()) AND (date_end = '0000-00-00' OR date_end > NOW())) ORDER BY priority ASC, price ASC LIMIT 1");

		if ($product_special_query->num_rows) {
			return true;
		} else {
			return false;
		}
	}

	public function isCouponCodeValid($code) {

		$totalPath = $this->config->get('promotion_totalPath');
		$totalCallModel = $this->config->get('promotion_totalModel');
		$this->load->model($totalPath);

		$query = $this->db->query("SELECT setting FROM " . DB_PREFIX . "module WHERE setting LIKE '%".$this->db->escape($code)."%'");
		if($query->num_rows > 0) {
			$data = array();
			if(version_compare(VERSION, '2.1.0.0', '<')) {
        		$data = unserialize($query->row['setting']);
        	} else {
        		$data = json_decode($query->row['setting'], true);
        	}

        	if(!isset($data['conditions']) || !isset($data['condition_rules']) || !isset($data['general_settings'])) return false;

        	$conditions = $data['conditions'];
			$condition_rules = $data['condition_rules'];
			$general_settings = $data['general_settings'];

			$this->session->data['coupon_promotion_module'] = $code;

			if($this->{$totalCallModel}->checkConditions($conditions, $condition_rules) && $this->{$totalCallModel}->checkGeneralSetting($general_settings)) {

				unset($this->session->data['coupon_promotion_module']);

				return true;

			}

			unset($this->session->data['coupon_promotion_module']);
		}
		return false;
	}

}