<?php
namespace App\Http\Controllers;

use App\Http\Controllers\MainController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use App\Services\SalesService;
use App\Services\CustomersService;
use App\Services\DeliveriesService;
use App\Services\StoresService;

use finfo;

class StoresController extends MainController{

	public $salesSrv;
	public $customersSrv;
	public $deliversSrv;
	
	public function __construct(
	  SalesService $salesSrv,
	  DeliveriesService $deliversSrv,
	  StoresService $storesSrv,
	  CustomersService $customersSrv
	){
	  $this->salesSrv = $salesSrv;
	  $this->customersSrv = $customersSrv;
	  $this->storesSrv = $storesSrv;
	  $this->deliversSrv = $deliversSrv;
	}

	/*
		loads the list of stores
	*/
	public function index(){
		$json = []; $status = 200; $error = "";
		$json['stores'] = $this->storesSrv->get();
		return $this->apiResponse($json,$status,$error);
	}
	/*
		loads the list of store orders
	*/
	public function orders(Request $request){
		$json = []; $status = 200; $error = "";

		$filters = json_decode($request->filters);
		# SET FILTERS
		$statuses = (isset($filters->statuses) && count($filters->statuses) > 0 ? $filters->statuses : ['pending']);
		$from = [
			'date' => (isset($filters->from_date) && $filters->from_date ? $filters->from_date : null), 
			'time' => (isset($filters->from_time) && $filters->from_time ? $filters->from_time : null), 
		];
		$to = [
			'date' => (isset($filters->to_date) && $filters->to_date ? $filters->to_date : null), 
			'time' => (isset($filters->to_time) && $filters->to_time ? $filters->to_time : null), 
		];
		$max = null;
		$order_by = [
			['col' => 'deliver_date', 'sort'=>'ASC'],
			['col' => 'deliver_time', 'sort'=>'ASC'],
		];
		$types = (isset($filters->types) && count($filters->types) > 0 ? $filters->types : null);

		$json['orders'] = $this->deliversSrv->get(null,null,null,null,$statuses,$types,$from,$to,$max,$order_by);

		return $this->apiResponse($json,$status,$error);
	}
	/*
		get the schedules
	*/
	public function schedules(Request $request){
		$json = []; $status = 200; $error = "";
		$json['schedule_type'] = $this->storesSrv->getSchedule();

		return $this->apiResponse($json,$status,$error);
	}
	/*
		get the delivery charge
	*/
	public function location_delivery_charge(Request $request){
		$json = []; $status = 200; $error = "";
		$json['schedule_type'] = $this->storesSrv->getLocationCharge($request);

		return $this->apiResponse($json,$status,$error);
	}
	/*
		get the promos
	*/
	public function promos(Request $request){
		$json = []; $status = 200; $error = "";
		$json['promos_data'] = $this->storesSrv->getPromos();

		return $this->apiResponse($json,$status,$error);
	}
	/*
		get the app_config
	*/
	public function appConfig(Request $request){
		$json = []; $status = 200; $error = "";
		$json['promos_data'] = $this->storesSrv->getAppConfig();

		return $this->apiResponse($json,$status,$error);
	}

	/*
		get the promo codes
	*/
	public function promoCode(Request $request){
		$json = []; $status = 200; $error = "";
		$promo_code = (isset($request->code) ? $request->code : false );
		$promo_id = (isset($request->promo_id) ? $request->promo_id : null );
		$promo_code_data = $this->storesSrv->getPromoCode($promo_code, $promo_id);
		if($promo_code_data) {
			if(isset($request->code) && is_object($promo_code_data)){
				$json['promo_code'] = [$promo_code_data];
			}else if($request->promo_id != null && is_object($promo_code_data)){
				$json['promo_code'] = $promo_code_data;
			}else{
				$json['promo_code'] = $promo_code_data;
			}
		} else {
			$json['promo_unavailable'] = true;
		};

		return $this->apiResponse($json,$status,$error);
	}

	/*
		loads the last orders
	*/
	public function orderLast(Request $request){
		$json = []; $status = 200; $error = "";
		
		if($request->statuses){
			$statuses = json_decode($request->statuses);
		}
		else
			$statuses = ['pending'];

		$json['orders'] = $this->deliversSrv->after($request->sale_id,$statuses);
		return $this->apiResponse($json,$status,$error);
	}
	/*
		UPDATES THE ORDER STATUS, RIDERS, DELIVERIES
	*/
	public function orderUpdateItems(Request $request){
		$json = []; $status = 200; $error = "";

		$employee_id = $request->user;
		$sale_id = $request->sale_id;
		$cart_items = json_decode($request->items);

		$merged = $this->salesSrv->mergeItems($cart_items);
		$items = $merged['items'];
		$cart_total = $merged['total_amount'];

		$this->transDB(function() use(&$json,&$error,$sale_id,$items,$cart_total,$employee_id){
			try{
				## IF CUSTOMER IS FOUND
				$updated_items = $saved = $this->salesSrv->updateItems($sale_id,$items,$employee_id);
			}
			catch (\Exception $e) {
				DB::rollback();
				$error_msg = $e->getMessage();
				$error_line = $e->getLine();
				$error_file = $e->getFile();
				// $this->logError($e,$this->trans_type,$request->client_id,$request->user,"Generate Workorder");
				$error = $error_msg." - ".$error_line." - ".$error_file;
				// $error = "Failed to update order.";
			}
		});

		return $this->apiResponse($json,$status,$error);
	}
	/*
		UPDATES THE ORDER STATUS, RIDERS, DELIVERIES
	*/
	public function orderUpdate(Request $request){
		$json = []; $status = 200; $error = "";

		$this->transDB(function() use(&$json,&$error,$request){
			try{
				$sale_id = $request->sale_id;
				$status_to = $request->status_to; // DISPATCHED, DELIVERED
				$user_id = $request->user;

				$order = $this->deliversSrv->toStatus($sale_id,$status_to,$user_id);
				switch ($status_to) {
					case 'accepted':
						$rider_id = $user_id;
						$reason = $request->reason;
						if($rider_id && $reason)
							$rider = $this->deliversSrv->setRiderEnd($sale_id,$rider_id,$reason);						
						break;
					case 'dispatched':
						$rider_id = $user_id;
						if($rider_id)
							$rider = $this->deliversSrv->setRider($sale_id,$rider_id);						
						break;
					case 'delivered':
						$rider_id = $user_id;
						if($rider_id)
							$rider = $this->deliversSrv->setRiderEnd($sale_id,$rider_id);						
						break;
				}
			}
			catch (\Exception $e) {
				DB::rollback();
				$error_msg = $e->getMessage();
				$error_line = $e->getLine();
				$error_file = $e->getFile();
				// $this->logError($e,$this->trans_type,$request->client_id,$request->user,"Generate Workorder");
				$error = $error_msg." - ".$error_line." - ".$error_file;
				// $error = "Failed to update order.";
			}
		});

		return $this->apiResponse($json,$status,$error);
	}
	/*
		GETS THE STORE IMAGE
	*/
	public function getImage(Request $request){
		$json = []; $status = 200; $error = "";
		// $path = app()->basePath('/public/images/stores/'.$request->id.'.jpg');
		// if (!File::exists($path)) {}
    	$image_file = $this->storesSrv->getStoreImage($request->id);
    	if($image_file != null){
			return response()->make($image_file, 200, array(
		        'Content-Type' => (new finfo(FILEINFO_MIME))->buffer($image_file)
		    ));
    	}
    	else{
			$path = app()->basePath('/public/images/stores/1.jpg');
			$file = File::get($path);
		    $type = File::mimeType($path);
	    	return response()->make($file, 200, array(
	 	       'Content-Type' => $type
	 	   	));
    	}    			
	}
	/*
		GETS THE BRAND STORE IMAGE
	*/
	public function getBrandImage(Request $request){
		$json = []; $status = 200; $error = "";
		// $path = app()->basePath('/public/images/stores/'.$request->id.'.jpg');
		// if (!File::exists($path)) {}
    	$image_file = $this->storesSrv->getBrandImage($request->id);
    	if($image_file != null){
			return response()->make($image_file, 200, array(
		        'Content-Type' => (new finfo(FILEINFO_MIME))->buffer($image_file)
		    ));
    	}
    	else{
			$path = app()->basePath('/public/images/stores/1.jpg');
			$file = File::get($path);
		    $type = File::mimeType($path);
	    	return response()->make($file, 200, array(
	 	       'Content-Type' => $type
	 	   	));
    	}    			
	}
	/*
		GETS THE PROMO STORE IMAGE
	*/
	public function getPromoImage(Request $request){
		$json = []; $status = 200; $error = "";
		// $path = app()->basePath('/public/images/stores/'.$request->id.'.jpg');
		// if (!File::exists($path)) {}
    	$image_file = $this->storesSrv->getPromoImage($request->id);
    	if($image_file != null){
			return response()->make($image_file, 200, array(
		        'Content-Type' => (new finfo(FILEINFO_MIME))->buffer($image_file)
		    ));
    	}
    	else{
			$path = app()->basePath('/public/images/stores/1.jpg');
			$file = File::get($path);
		    $type = File::mimeType($path);
	    	return response()->make($file, 200, array(
	 	       'Content-Type' => $type
	 	   	));
    	}    			
	}
	/*
		loads the list of stores
	*/
	public function getMenus(Request $request){
		$json = []; $status = 200; $error = "";
		
		$favorites = array();
		if((bool)$request->with_favorites && $request->user){
			$customer = $this->customersSrv->getCustomer($request->user);
			if($customer){
				$favorites_raw = $this->customersSrv->getFavorites($customer->person_id);
				
				foreach ($favorites_raw as $fv) {
					if((int)$request->brand_id == (int)$fv->brand_id)
						$favorites[] = $fv->item_id;
				}
			}
		}
		$item_id_filter = isset($request->item_id) ? $request->item_id : null;
		$menu_list = $this->storesSrv->getMenus($request->store_id,$request->brand_id,true,$item_id_filter);

		$menus = [];
		foreach ($menu_list as $mn) {
			$location_id = $mn->location_id;
			$menu_det = $mn->getRelation('menu_details')->toArray();

			if($mn->unit_price != "")
				$menu_det['unit_price'] = $mn->unit_price;

			$menu_det['location_id'] = $location_id;			

			// if((bool)$request->with_favorites && $request->user && count($favorites) > 0){
				$fav = false;
				if(in_array($menu_det['item_id'],$favorites)){
					$fav = true;
				}
				$menu_det['favorite'] = $fav;
			// }
			$menu_det['inventory_qty'] = $mn['quantity'];
			$menu_det['delivery'] = $mn['delivery'];
			$menu_det['pick_up'] = $mn['pick_up'];

			if($menu_det['brand_id'] == $request->brand_id){
				$menus[] = $menu_det;
			}
		}
		// echo "<pre>",print_r($menus),"<pre>";die();

		$json = $menus;
		return $this->apiResponse($json,$status,$error);
	}
}
