<?php
defined('BASEPATH') OR exit('No direct script access allowed');
// header("Access-Control-Allow-Headers: Authorization, Content-Type");
header("Access-Control-Allow-Origin: *");
header('content-type: application/json; charset=utf-8');	
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');  

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

// New Shopify Api
use Osiset\BasicShopifyAPI\BasicShopifyAPI;
use Osiset\BasicShopifyAPI\Options;
use Osiset\BasicShopifyAPI\Session;


class PostController extends CI_Controller {
	/**
	 * Index Page for this controller.
	 *
	 * Maps to the following URL
	 * 		http://example.com/index.php/welcome
	 *	- or -
	 * 		http://example.com/index.php/welcome/index
	 *	- or -
	 * Since this controller is set as the default controller in
	 * config/routes.php, it's displayed at http://example.com/
	 *
	 * So any other public methods not prefixed with an underscore will
	 * map to /index.php/welcome/<method_name>
	 * @see https://codeigniter.com/user_guide/general/urls.html
	 */

	public  $api,$shopData;
	public $shop;
	public function __construct()
	{
		parent::__construct();// you have missed this line.
		
		
		$options = new Options();
		$options->setVersion(SHOPIYF_VERSION);
		$options->setApiKey(SHOPIFY_API_KEY);
		$options->setApiSecret(SHOPIFY_SECRET_KEY);
		// Create the client and session
		$this->api = new BasicShopifyAPI($options);
		// ini_set('display_errors', 1);
	}
	
	function postOffer(){
		$productData=[];
	    $jwt= $_POST['token'];
	
	    $key= SHOPIFY_SECRET_KEY;
	    $decoded = JWT::decode($jwt, new Key($key, 'HS256'));

	    $this->shop=$domain=$decoded->input_data->shop->domain;
	    $inputData =$decoded->input_data;
	  //  echo json_encode($inputData->initialPurchase);
	    $initialPurchase= $inputData->initialPurchase;

	    $total= $initialPurchase->totalPriceSet->shopMoney->amount;
		
	    $lineItem=$initialPurchase->lineItems;
		// if($this->shop=="james-develop.myshopify.com"){
		// 	$this->getByProducts();
		// 	die;
		// }
	
	    $offers=[];
	        $shopData=$this->adminModel->get_row("app_record",array("shop_address"=>$domain));
	    $this->api->setSession(new Session($domain, $shopData->shop_token));
	    $productData=[];
	    $condition=["shop_name"=>$domain,'location'=>"postPurches"];

		$whereOn=array_merge($condition,["triggerOn"=>"minValue","minValue<="=>round($total),"status"=>1]);
	    $getOffers=$this->adminModel->get_data('funnels',$whereOn);

		if($getOffers){
		    foreach($getOffers as $keys){
			
		    	$offer=["offer"=>json_decode($keys->offer),"language"=>json_decode($keys->language),"design"=>json_decode($keys->design)];
		    	$id=base64_encode($keys->id);
		    	
		    	$products=$this->getProducts($offer);
		    	if(!empty($products)){
		    		$offers=array_merge($offers,$products);
		    		
		    	}
		    	//$offers[]=["id"=>$id,"funnelName"=>$keys->funnelName,"offer"=>$offer,"design"=>json_decode($keys->design),"settings"=>json_decode($keys->settings),"language"=>json_decode($keys->language),"products"=>$products];
		    	
		    }
	    }

		

	    $whereOnAll=array_merge($condition,["triggerOn"=>"all","status"=>1]);
		$getOffers=$this->adminModel->get_data('funnels',$whereOnAll);
		if($getOffers){
			foreach($getOffers as $keys){
				$id=base64_encode($keys->id);
				$offer=["offer"=>json_decode($keys->offer),"language"=>json_decode($keys->language),"design"=>json_decode($keys->design)];
		    	
				
				$products=$this->getProducts($offer);
				$searchKey=array_search($id, array_column($offers, 'id'));
				if($searchKey>-1){
					continue;
				}
				if(!empty($products)){
		    		$offers=array_merge($offers,$products);
		    		
		    	}
				//$offers[]=["id"=>$id,"funnelName"=>$keys->funnelName,"offer"=>$offer,"design"=>json_decode($keys->design),"settings"=>json_decode($keys->settings),"language"=>json_decode($keys->language),"products"=>$products,"position"=>$keys->position];
				
			}

			
		}

	    
	    if(!empty($lineItem)){
		   		$whereOnIds=array_merge($condition,["triggerOn"=>"products","status"=>1]);
		   		foreach( $lineItem as $item){
		   			$id= $item->product->id;
		   			$searchKey=array_search($id, array_column($offers, 'id'));
				    	if($searchKey>-1){
				    		continue;
				    	}
		   			$keys=$this->adminModel->get_front_row('funnels',$whereOnIds,["recommendedProduct"=>$id]);
		   			if($keys){
			   			$id=base64_encode($keys->id);
						$offer=["offer"=>json_decode($keys->offer),"language"=>json_decode($keys->language),"design"=>json_decode($keys->design)];
		    	
				    	//$offers[$id]=["id"=>$id,"funnelName"=>$keys->funnelName,"offer"=>json_decode($keys->offer),"design"=>json_decode($keys->design),"settings"=>json_decode($keys->settings),"language"=>json_decode($keys->language)];
						
				    	$products=$this->getProducts($offer);
				    	if(!empty($products)){
				    		$offers=array_merge($offers,$products);//$offers[]=$products;//array_push($offers, $products);
				    	}
			    	}
			    	//$offers[$id]["products"]=$products;
		   		}

		   		
		   	}


	    echo json_encode(["products"=>$offers]);

	    die();
	   	// foreach($getOffers as $value){
	   	// 	$offer=json_decode($value->offer);
	   	// }

	   	// $offer=json_decode($getOffers->offer);
	   
	   	// $result = $this->api->rest("get","/admin/api/products.json",["ids"=>$offer->offerProduct ,"fields"=>"id,title,handle,images,options,variants,body_html","status"=>"active"]);
	  
	    // $result=$this->adminModel->getBodyContainer($result,'products');
		// foreach($result as $value){
		// 	$value["body_html"]=strip_tags($value["body_html"]);
		// 	$value["discount"]=['discountValue'=>$offer->discountValue,"type"=>$offer->discount,"minQty"=>$offer->minQty];
		// 	$inventory=false;
		// 	$variants=[];
		// 	foreach($value["variants"] as $variant){
		// 		if($variant['inventory_quantity']>0){
		// 			array_push($variants,$variant);
		// 			$inventory=true;
		// 		}
		// 	}
		// 	if($inventory){
		// 		$value["variants"]=$variants;
		// 		array_push($productData, $value);
		// 	}

		// }


		
	}


	public function getByProducts()
	{
		// code...

		$productData=[];
	    $jwt= $this->input->post('token');
	    $key= SHOPIFY_SECRET_KEY;
	    $decoded = JWT::decode($jwt, new Key($key, 'HS256'));

	    $this->shop=$domain=$decoded->input_data->shop->domain;
	    $inputData =$decoded->input_data;
	  //  echo json_encode($inputData->initialPurchase);
	    $initialPurchase= $inputData->initialPurchase;

	    $total= $initialPurchase->totalPriceSet->shopMoney->amount;
	    $lineItem=$initialPurchase->lineItems;
		$itemCount=count($lineItem);
		$productsIds=$productsTitle=$productsPrices=[];
		if($lineItem){
			foreach($lineItem as $item){
				$productsIds[]=$item->product->id;
				$productsTitle[]=$item->product->title;
				$productsPrices[]=$item->totalPriceSet->shopMoney->amount;
			}
		}

		$offers=[];
		$shopData=$this->adminModel->get_row("app_record",array("shop_address"=>$domain));
	    $this->api->setSession(new Session($domain, $shopData->shop_token));

		    $condition=["shop_name"=>$domain,'location'=>"postPurches","status"=>1];

			
		    $whereOnAll=array_merge($condition,["triggerOn"=>"all"]);
		    $getOffersAll=$this->adminModel->get_data('funnels',$whereOnAll);
		    // Fetch all Orders
		    $ids="";
		    if($getOffersAll){
			    foreach($getOffersAll as $keys){
			    	$id=base64_encode($keys->id);
			    	$offer=json_decode($keys->offer);
			    	$products=	$offer->offerProduct;
			    	//$products=$offer->offerProduct?$this->getProducts($offer->offerProduct):[];
			    	$searchKey=array_search($id, array_column($offers, 'id'));
			    	if($searchKey>-1){
			    		continue;
			    	}

					$products=$offer->offerProduct?$this->getProducts($offer->offerProduct,$offer):[];
					if(!empty($products)){
						$offers=array_merge($offers,$products);
						
					}

			    	//$ids .=empty($ids)?$products:",".$products;
			    	//$offers[]=["id"=>$id,"funnelName"=>$keys->funnelName,"offer"=>$offer,"design"=>json_decode($keys->design),"layout"=>json_decode($keys->layout),"settings"=>json_decode($keys->settings),"language"=>json_decode($keys->language),"products"=>$products,"position"=>$keys->position];
			    }

			}
			// Fetch product from ids
			if(is_array($productsIds)){
			
				
				foreach($productsIds as $productId){
					$whereOnIds=array_merge($condition,["triggerOn"=>"products","status"=>1,"recommendedProduct"=>$productId]);
					
					$keys=$this->adminModel->get_front_row('funnels',$whereOnIds);
					
					if($keys){
						$id=base64_encode($keys->id);
						$offer=json_decode($keys->offer);
						$products=	$offer->offerProduct;
						$searchKey=array_search($id, array_column($offers, 'id'));
						if($searchKey>-1){
							continue;
						}

						$productInfo=$offer->offerProduct?$this->getProducts($offer->offerProduct,$offer):[];
						if(!empty($productInfo)){
							$offers=array_merge($offers,$productInfo);
						
						}
					
				 	}
				 
				}
		 	}
			
			// Fetch orders form total price
		    $whereOnTotal=array_merge($condition,["triggerOn"=>"orderTotal"]);
		    $getTotalOffer=$this->adminModel->get_data('funnels',$whereOnTotal);
		    if($getTotalOffer){
		    	foreach($getTotalOffer as $totalOffers){
		    		$checkOffer= $this->conditionForNumber($totalOffers,$total);
		    		if(!empty($checkOffer)){
		    			$offers=array_merge($offers,$checkOffer);
		    		}
		    	}
		    }

			 // trigger on the no of line item
			 $whereOnLineItem=array_merge($condition,["triggerOn"=>"noOfLineItem"]);
			 $getLineItemOffer=$this->adminModel->get_data('funnels',$whereOnLineItem);
			 if($getLineItemOffer){
				 foreach($getLineItemOffer as $subTotalOffers){
					 $checkOffer= $this->conditionForNumber($subTotalOffers,$itemCount);
					 if(!empty($checkOffer)){
						$offers=array_merge($offers,$checkOffer);
					 }
					 
 
				 }
			 }

			// item title
			if(is_array($productsTitle)){
				$whereOnTitle=array_merge($condition,["triggerOn"=>"lineItemTitle"]);
				foreach($productsTitle as $title){
					$keys=$this->adminModel->get_front_row('funnels',$whereOnTitle,["productTitle"=>$title]);
					
					if($keys){
						$id=base64_encode($keys->id);
						$offer=json_decode($keys->offer);
						$products=	$offer->offerProduct;
						//$products=$offer->offerProduct?$this->getProducts($offer->offerProduct):[];
						$searchKey=array_search($id, array_column($offers, 'id'));
						if($searchKey>-1){
							continue;
						}
						$productInfo=$offer->offerProduct?$this->getProducts($offer->offerProduct,$offer):[];
						if(!empty($productInfo)){
							$offers=array_merge($offers,$productInfo);
						
						}
					 
				 }
				 
				}
		 	}
			// item Price
		    if(is_array($productsPrices)){
				$whereOnLineItemPrice=array_merge($condition,["triggerOn"=>"lineItemPrice"]);
				$prces=$productsPrices[0];
				$getOnLineItemPrice=$this->adminModel->get_data('funnels',$whereOnLineItemPrice);
				if($getOnLineItemPrice){
					foreach($getOnLineItemPrice as $subTotalOffers){
						$checkOffer= $this->conditionForNumber($subTotalOffers,$prces);
						if(!empty($checkOffer)){
							$offers=array_merge($offers,$checkOffer);
						}
						

					}
				}
			}
		echo json_encode($offers);


		
	}
	

	private function conditionForNumber($subTotalOffers,$value)
	{
		$offers=[];
		// echo $value;
		// print_r($subTotalOffers);
		// code...
		if($subTotalOffers->triggerOnType=="is" && $subTotalOffers->minValue==$value){

			$id=base64_encode($subTotalOffers->id);
	    	$offer=json_decode($subTotalOffers->offer);
	    	$products=	$offer->offerProduct;
	    	//$products=$offer->offerProduct?$this->getProducts($offer->offerProduct):[];
	    	
			//$offers=["id"=>$id,"funnelName"=>$subTotalOffers->funnelName,"offer"=>$offer,"design"=>json_decode($subTotalOffers->design),"layout"=>json_decode($subTotalOffers->layout),"settings"=>json_decode($subTotalOffers->settings),"language"=>json_decode($subTotalOffers->language),"products"=>$products,"position"=>$subTotalOffers->position];
	    	$offers=$this->getProducts($products,$offer);
	    	

		}else if($subTotalOffers->triggerOnType=="isNot" && $subTotalOffers->minValue!=$value){

			$id=base64_encode($subTotalOffers->id);
	    	$offer=json_decode($subTotalOffers->offer);
	    	$products=	$offer->offerProduct;
			$offers=$this->getProducts($products,$offer);
	    	//$products=$offer->offerProduct?$this->getProducts($offer->offerProduct):[];
	    	//$offers=["id"=>$id,"funnelName"=>$subTotalOffers->funnelName,"offer"=>$offer,"design"=>json_decode($subTotalOffers->design),"layout"=>json_decode($subTotalOffers->layout),"settings"=>json_decode($subTotalOffers->settings),"language"=>json_decode($subTotalOffers->language),"products"=>$products,"position"=>$subTotalOffers->position];
	    	

		}else if($subTotalOffers->triggerOnType=="moreThan" && $subTotalOffers->minValue<$value){
			$id=base64_encode($subTotalOffers->id);
	    	$offer=json_decode($subTotalOffers->offer);
	    	$products=	$offer->offerProduct;
			$offers=$this->getProducts($products,$offer);
	    	//$products=$offer->offerProduct?$this->getProducts($offer->offerProduct):[];
	    	//$offers=["id"=>$id,"funnelName"=>$subTotalOffers->funnelName,"offer"=>$offer,"design"=>json_decode($subTotalOffers->design),"layout"=>json_decode($subTotalOffers->layout),"settings"=>json_decode($subTotalOffers->settings),"language"=>json_decode($subTotalOffers->language),"products"=>$products,"position"=>$subTotalOffers->position];
	    	
		}else if($subTotalOffers->triggerOnType=="isNot" && $subTotalOffers->minValue!=$value){

			$id=base64_encode($subTotalOffers->id);
	    	$offer=json_decode($subTotalOffers->offer);
	    	$products=	$offer->offerProduct;
			$offers=$this->getProducts($products,$offer);
	    	//$products=$offer->offerProduct?$this->getProducts($offer->offerProduct):[];
	    	//$offers=["id"=>$id,"funnelName"=>$subTotalOffers->funnelName,"offer"=>$offer,"design"=>json_decode($subTotalOffers->design),"layout"=>json_decode($subTotalOffers->layout),"settings"=>json_decode($subTotalOffers->settings),"language"=>json_decode($subTotalOffers->language),"products"=>$products,"position"=>$subTotalOffers->position];
	    	

		}
		return $offers;
	}

	

	private function getProducts ($layout){
		
		$productData=[];
		$offer=$layout["offer"];


		$offerProductIds=$offer->offerProduct;
		if(!$offerProductIds){
			return [];
		}

		$ids=explode(",", $offerProductIds);

		foreach($ids as $key => $value){
			$ids[$key]= "gid://shopify/Product/".$value;
		}

		$variable=['ids'=>$ids];
		$query= $this->getProductsByIds();
		$request =$this->api->graph($query,$variable);
		$products= $this->graphQuery->getBodyContainer($request,"nodes");
		if(!empty($products)){
			foreach($products as $key=>$value){
			   	$inventory=false;		
				$variants=[];
				foreach($value["variants"]['edges'] as $variant){
					// print_r($variant);
					if($variant['node']['inventoryQuantity']>0 || $variant['node']['inventoryQuantity']<0){
						$variants[]=['id'=>str_replace("gid://shopify/ProductVariant/", "", $variant['node']['id']),'price'=>$variant['node']['price'],'inventory_quantity'=>$variant['node']["inventoryQuantity"]];
						$inventory=true;
					}
				}
				$images=[];
				foreach($value["media"]['nodes'] as $image){
					$images[]=[
						'id'=>$image['preview']['image']['id'],
						'src'=>$image['preview']['image']['url']
					];
				}
				// print_r($value["variants"]);
				if($inventory){
					$productData[$key]['id']=str_replace("gid://shopify/Product/", "", $value['id']);
					$productData[$key]['handle']=$value['handle'];
					$productData[$key]['body_html']=strip_tags($value['descriptionHtml']);
					
					$productData[$key]['discount']=['discountValue'=>$offer->discountValue,"type"=>$offer->discount,"minQty"=>$offer->minQty];
					$productData[$key]['language']=$layout["language"];
					$productData[$key]['design']=$layout["design"];
					$productData[$key]["variants"]=$variants;
					$productData[$key]['images']=$images;
					
				}
			}
		}
		return $productData;
		/*$result = $this->api->rest("get","/admin/api/products.json",["ids"=>$offerProductIds,"fields"=>"id,title,handle,images,options,variants,body_html","status"=>"active"]);
	  
	 	$result=$this->adminModel->getBodyContainer($result,'products');
	 	foreach($result as $value){
			$value["body_html"]=strip_tags($value["body_html"]);
			$value["discount"]=['discountValue'=>$offer->discountValue,"type"=>$offer->discount,"minQty"=>$offer->minQty];
			$value['language']=$layout["language"];
			$value['design']=$layout["design"];
			$inventory=false;
			$variants=[];
			foreach($value["variants"] as $variant){
				if($variant['inventory_quantity']>0 || $variant['inventory_quantity']<0){
					array_push($variants,$variant);
					$inventory=true;
				}
			}
			if($inventory){
				$value["variants"]=$variants;
				array_push($productData, $value);
			}

		}

		return $productData;*/
	}

	private function getProductsQuery(){
		
	}

	function signChangeset(){
		$jwt= $_POST['token'];
	    $key= SHOPIFY_SECRET_KEY;
		$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
		
		$decodedReferenceId=$decoded->input_data->initialPurchase->referenceId;
		$referenceId=$_POST['referenceId'];
		$status=$referenceId==$decodedReferenceId?true:false;
		
		$payload = [
		    'iss' => SHOPIFY_API_KEY,
		    'jti' => $this->v4(),
		    'name'=> "enormapps",
		    'iat' => time(),
		    'sub' =>$referenceId,
		    "changes"=>json_decode($_POST['changes'])
		    
		];

		//echo json_encode($payload);

		$token = JWT::encode($payload, $key, 'HS256');
		echo json_encode(["token"=>$token]);
	}

	private function getProductsByIds(){
		return ('query Products($ids: [ID!]!) {
			  nodes(ids: $ids) {
			    ... on Product {
			       	id
			        title
			        handle
			        descriptionHtml 
			        media(first:2){
			        	nodes{
			        		preview{
			        			image{
			        				id
			        				url
			        			}
			        		}
			        	}
			        }
			        variants(first:20){
			            edges{
				            node{
				                id
				                price
				                compareAtPrice
				                inventoryQuantity
				            }
			            }
			        }
			      
			    }
			  }
			}');
	}

	public function v4() {
	    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',

	      // 32 bits for "time_low"
	      mt_rand(0, 0xffff), mt_rand(0, 0xffff),

	      // 16 bits for "time_mid"
	      mt_rand(0, 0xffff),

	      // 16 bits for "time_hi_and_version",
	      // four most significant bits holds version number 4
	      mt_rand(0, 0x0fff) | 0x4000,

	      // 16 bits, 8 bits for "clk_seq_hi_res",
	      // 8 bits for "clk_seq_low",
	      // two most significant bits holds zero and one for variant DCE1.1
	      mt_rand(0, 0x3fff) | 0x8000,

	      // 48 bits for "node"
	      mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
	    );
	 }



	
}
