<?php
namespace App\Library;
use App\Model\FxModel;
use App\Core\Service\Logger;
use App\Config\Main;
class Fx 
{   
    private $Fx_Model;
    public function __construct() {
        $this->Fx_Model = new FxModel();
    } 
	
	public function getCompanyDetail($comp_id) {
		try {
			$rsp = $this->Fx_Model->getFromTable($this->Fx_Model->tables['admin_client_master'], "id=:id", [":id"=>$comp_id]);
			if(empty($rsp['status'])) {
				throw new \Exception($rsp['error']);
			}
			if(empty($rsp['data'])) {
				throw new \Exception("Company detail not found");
			}
			return ["status"=>true, "data"=>$rsp['data'][0]];
		} catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ["status" => false, "error" => $e->getMessage()];
		}
	}
	
	public function getBranchDetail(Int $comp_id, $logged_user, Int $branch_id) {
		try {
			$rsp = $this->Fx_Model->getBranchList($comp_id, "branch_id=".$branch_id, $single = 1);
			if(empty($rsp['status'])) {
				throw new \Exception($rsp['error']);
			}
			if(empty($rsp['data'])) {
				throw new \Exception("Branch detail not found");
			}
			return ["status"=>true, "data"=>$rsp['data']];
		} catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ["status" => false, "error" => $e->getMessage()];
		}
	}

    public function stockOut($comp_id, $id, $rollback = 0, $type = 'IO', $conn=NULL)
	{
		try {
			$itemList = array();
			if ($type == 'IO') {
				$itemList = $this->Fx_Model->getOrderItemListForStock($comp_id, 'o.id='.$id);
			} else if ($type == 'IV') { 
				$itemList = $this->Fx_Model->getOuterStockInvenory($comp_id, 't1.inv_id='.$id, 'qty');
			}
			if(!empty($itemList['status'])) {
				foreach ($itemList['data'] as $item) {
					if ($item['item_id'] > 0){
						$updrs = $this->Fx_Model->stockOutUpdate($comp_id, $item['item_id'], $item['branch_id'], $item['qty'], $rollback, $conn);
						if(empty($updrs['status'])) {
							throw new \Exception($updrs['error']);
						}
					}
				}
			} else if(isset($itemList['error'])) {
				throw new \Exception($itemList['error']);
			} else {
				throw new \Exception("Unable to get Item List for stock");
			}
			Logger::debug("stockOut done", ['File' => __FILE__, 'Line' => __LINE__]);
			return ["status"=>true];
		} catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ["status" => false, "error" => $e->getMessage()];
		}
	}

	function generateOrderPrefix($string, $state_code = 'HR')
	{
		$dataArray = array('{state_code}', '{M}', '{m}', '{Y}', '{y}', '{Y+1}', '{y+1}');
		$responseArray = array($state_code, date('M'), date('m'), date('Y'), date('y'), date('Y') + 1, date('y') + 1);
		return str_replace($dataArray, $responseArray, $string);
	}

	function generateInvoiceNumberPrefix($comp_id, $branch_id, $state_code='HR') {
		try {
			$result = ['invoice_series' => '', 'invoice_prefix_id' => null, 'invoice_number' => ''];
			$inrs = $this->Fx_Model->getMaxInvoiceSeries($comp_id, $branch_id);
			if(empty($inrs['status'])) {
				throw new \Exception($inrs['error']);
			} 
			if(empty($inrs['data'])) {
				throw new \Exception("Unable to get Invoice series");
			}
			if (empty($inrs['data']['inv_prefix'])) {
				$result['invoice_number'] = str_pad($inrs['data']['max_no'], 4, "0", STR_PAD_LEFT);
				$result['invoice_series'] = $inrs['data']['max_no'];
				return ["status"=>true, "data"=>$result];
			}
			$result['invoice_series'] = $inrs['data']['max_no'];
			$result['invoice_prefix_id'] = $inrs['data']['invoice_prefix_id'];
			$result['invoice_number'] = $this->generateOrderPrefix($inrs['data']['inv_prefix'] . str_pad($inrs['data']['max_no'], $inrs['data']['min_length'], "0", STR_PAD_LEFT), $state_code);
			return ["status"=>true, "data"=>$result];
		} catch(\Exception $e) {
			Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ["status" => false, "error" => $e->getMessage()];
		}
	}

	function addOrderLogs($sess_user, $order_id, $last_status, $current_status, $remarks, $message, $conn) {
		try {
			$data = [
				"order_id" => $order_id,
				"last_status_id" => $last_status,
				"current_status_id" => $current_status,
				"log_message" => $message,
				"user_id" => $sess_user->id
			];
			if(!empty($remarks)) {
				$data['remarks'] = $remarks;
			}
			$inrs = $this->Fx_Model->addOrderLog($sess_user->comp_id, $data, $conn);
			if(empty($inrs['status'])) {
				throw new \Exception("Error occurred while saving the order activity log");
			} 
			if(empty($inrs['data'])) {
				throw new \Exception("Unable to save the order activity log");
			}
			return ["status"=>true, "data"=>$inrs['data']];
		} catch(\Exception $e) {
			Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ["status" => false, "error" => $e->getMessage()];
		}
	}

	function getOrderCustomerDetail($comp_id, $order_data) {
		try {
			$customer = !empty($order_data['customer_detail']) ? (array) json_decode(stripcslashes($order_data['customer_detail'])) : [];
			
			if(!empty($customer['address']) && !empty($customer['address_pincode']) && !empty($customer['address_city_id']) && !empty($customer['address_state_id'])) {
				$customer['address_state_name'] = '';
				$customer['address_city_name'] = '';
				if(!empty($customer['address_city_id'])) {
					$table = $this->Fx_Model->client_db_prefix.$comp_id . ".".$this->Fx_Model->tables['location_city'];
					$ctrs = $this->Fx_Model->getFromTable($table, "id=".$customer['address_city_id'], []);
					if(empty($ctrs['status'])) {
						Logger::error($ctrs['error'], ['File' => __FILE__, 'Line' => __LINE__]);
					} else if(!empty($ctrs['data'])) {
						$customer['address_city_name'] = $ctrs['data'][0]['city_name'];
					}
				}
				if(!empty($customer['address_state_id'])) {
					$staters = $this->Fx_Model->getFromTable($this->Fx_Model->tables['admin_state_master'], "state_id=".$customer['address_state_id'], []);
					if(empty($staters['status'])) {
						Logger::error($staters['error'], ['File' => __FILE__, 'Line' => __LINE__]);
					} else if(!empty($staters['data'])) {
						$customer['address_state_name'] = $staters['data'][0]['state_name'];
					}
				}
			} else {
				$ctrs = $this->Fx_Model->getCustomerAddress($comp_id, "t1.id=".$order_data['address_id'], 1);
				if(empty($ctrs['status'])) {
					Logger::error($ctrs['error'], ['File' => __FILE__, 'Line' => __LINE__]);
				}

				if(!empty($ctrs['data'])) {
					$customer['address_city_id'] = $ctrs['data']['address_city_id'];
					$customer['address_state_id'] = $ctrs['data']['address_state_id'];
					$customer['address_state_name'] = $ctrs['data']['address_state_name'];
					$customer['address_city_name'] = $ctrs['data']['address_city_name'];
					$customer['address'] = $ctrs['data']['address'];
					$customer['address_pincode'] = $ctrs['data']['address_pincode'];
					$customer['address_mobile'] = $ctrs['data']['address_mobile'];
					$customer['gst'] = $ctrs['data']['gst'];
				}
			}
			return ["status"=>true, "data"=>$customer];
		} catch(\Exception $e) {
			Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ["status" => false, "error" => $e->getMessage()];
		}
	}

	

	function getCouponDiccountAmt($comp_id, $coupon_code, $amount, $customer_id) {
		try {
			$currentTime = date('Y-m-d');			
			$where = 'c.status=1 AND m.status=1 AND DATE(m.valid_from) <="'.$currentTime.'" AND DATE(m.valid_to) >="'.$currentTime.'" AND c.coupon_name="'.$coupon_code.'"';
			$couponrs = $this->Fx_Model->getCouponDetail($comp_id, $where, 1);
			if(empty($couponrs['status'])) {
				throw new \Exception($couponrs['error']);
			} 
			if(empty($couponrs['data'])) {
				throw new \Exception("Invalid Coupon Code or Coupon Expired.");
			}
			if(!empty($customer_id)) {
				$usedrs = $this->Fx_Model->getCouponUsedCount($comp_id, $customer_id, $coupon_code);
				if(empty($usedrs['status'])) {
					throw new \Exception($usedrs['error']);
				} 
				if($usedrs['count'] > $couponrs['data']['user_apply_count']) {
					throw new \Exception("Sorry, Coupon has reached maximum redeemtion limit !!");
				}
			}
			if($amount < $couponrs['data']['min_order_amount']) {
				throw new \Exception("Sorry, Minimum coupon applicable order amount should be Rs." . $couponrs['data']['min_order_amount']);
			}

			$discountAmount = 0;
			if ($couponrs['data']['coupon_type'] == 1) {
				$discountAmount = round($couponrs['data']['discount'] * $amount / 100, 2);
			} else {
				$discountAmount = $couponrs['data']['discount'];
			}
			if ($discountAmount > $couponrs['data']['maximum_discount_amount']){
				$discountAmount = $couponrs['data']['maximum_discount_amount'];
			}
			if ($discountAmount > $amount) {
				throw new \Exception("Discount amount should not be greater than the item amount");
			}
			return ["status"=>true, "discount"=>$discountAmount, "coupon_detail"=>$couponrs['data']];
		} catch(\Exception $e) {
			Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ["status" => false, "error" => $e->getMessage()];
		}
	}

	function getCouponApplicableAmount($data) {
		try {
			$coupon_discount_type = Main::getCouponDiscountType();
			$amount = 0;
			if($coupon_discount_type == 1) { //Applicable only on the items - cart should not have any package
				if (!empty($data['package_id'])) {
					throw new \Exception("You cannot apply coupon on packages.Please remove coupon code!!");
				}
				foreach ($data['item_list'] as $key => $item) {
					if ($item['qty'] > 0 && $item['rate'] > 0 && $item['item_package_id'] == '') {
						$amount += round($data['total_amount']);
					}
				}
			} else if($coupon_discount_type == 2) {//Applicable only on the items - cart may have any package
				foreach ($data['item_list'] as $key => $item) {
					if ($item['qty'] > 0 && $item['rate'] > 0 && $item['item_package_id'] == '') {
						$amount += round($data['total_amount']);
					}
				}
			} else {//Applicable on all items and packages
				foreach ($data['item_list'] as $key => $item) {
					if ($item['qty'] > 0 && $item['rate'] > 0) {
						$amount += round($data['total_amount']);
					}
				}
			}
			return ["status"=>true, "data"=>$amount];
		} catch(\Exception $e) {
			Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line' => $e->getLine()]);
            return ["status" => false, "error" => $e->getMessage()];
		}
	}
}