<?php

/**
 * Manage Customer Groups
 *
 * PHP version 5.6
 *
 * @category  Customer
 * @package   Eloquent
 * @author    Abhilash Das <abhilashd@riaxe.com>
 * @copyright 2020-2021 Riaxe Systems
 * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
 * @link      http://inkxe-v10.inkxe.io/xetool/admin
 */

namespace App\Modules\Customers\Controllers;

use CustomerStoreSpace\Controllers\StoreCustomersController;
use App\Components\Controllers\Component as ComponenetController;
use App\Modules\Customers\Models\CustomerGroup;
use App\Modules\Customers\Models\CustomerGroupRel;
use App\Modules\Customers\Models\CustomerGroupTierDiscount as CustomerGroupDiscount;
use App\Modules\Customers\Models\CustomerGroupAssetsCategoryRel as CustomerGroupAssets;
use App\Modules\PrintProfiles\Models\AssetType;
use App\Modules\Cliparts\Models\Clipart;
use App\Modules\Templates\Models\Template;
use App\Components\Models\Category as Category;
use Illuminate\Database\Capsule\Manager as DB;

/**
 * Customer group Controller
 *
 * @category Class
 * @package  Customer group
 * @author   Abhilash Das <abhilashd@riaxe.com>
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @link     http://inkxe-v10.inkxe.io/xetool/admin
 */
class CustomerGroupController
{

	/**
	 * Return single customer details (internal)
	 *
	 * @author dan@imprintnext.com
	 * @date   06 July 2022
	 * 
	 * @param object $request : Slim request
	 * @param object $response : Slim respose
	 * @param array $args :(store_id: store id, id: group id)
	 * @return array $GroupResponseArray : single customer group detail
	 */
	private function _singleCustomerGroup($request, $response, $args) {
		$GroupResponseArray = []; // group list - default blank
		$storeGroupDeatils = [];

		$storeId = $request->getQueryParam('store_id');
		$customerGroupId = $args['id'];
		if (STORE_NAME != 'Woocommerce') {
			$storeCustomerInit = new StoreCustomersController();
			$storeGroupDeatils = $storeCustomerInit->getStoreGroupById($customerGroupId);
		}

		// get the customer group details
		$conditions = [['store_id', '=', $storeId]]; // default conditions
		if (STORE_NAME != 'Woocommerce') {
			$conditions[] = ['store_ref_id', '=', $customerGroupId];
		} else {
			$conditions[] = ['xe_id', '=', $customerGroupId];
		}

		$getGroupDetails = (new CustomerGroup())->where($conditions);
		// do not proceed if group is not found
		if ($getGroupDetails->count() == 0) {
			//throw new \Exception('Customer group not found');
		}
		// get the group detail
		$groupDetails = $getGroupDetails->get()->first();

		$GroupResponseArray = [
			'id' => $customerGroupId,
			'tier_price_enable' => $groupDetails->tier_price_enable ? $groupDetails->tier_price_enable : '0',
			'price_discount' => $groupDetails->flat_discount ? $groupDetails->flat_discount : 0,
			'company_url' => $groupDetails->group_url ? $groupDetails->group_url : '',
			'discount_enable' => $groupDetails->discount_enable ? $groupDetails->discount_enable : 0,
			'company_address' => $groupDetails->group_address ? $groupDetails->group_address : '',
			'company_logo' => $groupDetails->group_img ? path('read', 'customer_group') . $groupDetails->group_img : null,
			'primary_email' => $groupDetails->group_primary_email ? $groupDetails->group_primary_email : '',
			'secondary_email' => $groupDetails->group_secondary_email ? $groupDetails->group_secondary_email : '',
			'phone_number' => $groupDetails->group_primary_number ? $groupDetails->group_primary_number : '',
			'alternative_number' => $groupDetails->group_alt_number ? $groupDetails->group_alt_number : '',
			'fax' => $groupDetails->group_fax ? $groupDetails->group_fax : '',
			'company_name' => (STORE_NAME != 'Woocommerce') ? $storeGroupDeatils['name'] : $groupDetails->name,
			'clipart_list' => [], 'tier_price_data' => [], 'template_list' => [], 'customer_list' => []
		];

		// get discount data from the price tier
		$priceTierObj = new CustomerGroupDiscount();
		$priceTiers = $priceTierObj->where('customer_group_id', '=', $customerGroupId)->select('qty_from', 'qty_to', 'discount_rate');

		// If discount data is availble
		if ($priceTiers->count() > 0) {
			$tierData = [];
			$groupTierdiscount = $priceTiers->get()->toArray();
			foreach ($groupTierdiscount as $val) {
				$tierData[] = [
					'from_qty' =>  $val['qty_from'],
					'to_qty' => $val['qty_to'],
					'discount' => $val['discount_rate']
				];
			}
			$GroupResponseArray['tier_price_data'] = $tierData;
		}
		$componentCtrlObj = new ComponenetController();
		// Get the customer group clipart
		$assetTypeArr = $componentCtrlObj->assetsTypeId('cliparts');
		$assetTypeId = $assetTypeArr['asset_type_id'];
		$groupClipArt = (new CustomerGroupAssets())->where('customer_group_id', '=', $customerGroupId)
			->where('asset_type_id', '=', $assetTypeId);

		// If clipart data is availble
		if ($groupClipArt->count() > 0) {
			$groupClipArtArry = $groupClipArt->get()->toArray();
			$data = $this->getAssetDetails($groupClipArtArry, $assetTypeId, $storeId);
			$GroupResponseArray['clipart_list'] = array_column($data, 'id');
		}

		// Get the template data
		$assetTypeArr = $componentCtrlObj->assetsTypeId('templates');
		$assetTypeId = $assetTypeArr['asset_type_id'];
		$groupTemplate = (new CustomerGroupAssets())->where('customer_group_id', '=', $customerGroupId)
			->where('asset_type_id', '=', $assetTypeId);

		// If template data is availble
		if ($groupTemplate->count() > 0) {
			$groupTemplateArry = $groupTemplate->get()->toArray();
			$tempData = $this->getAssetDetails($groupTemplateArry, $assetTypeId, $storeId);
			$GroupResponseArray['template_list'] = array_column($tempData, 'id');
		}

		// fetching all store group-wise customer 
		$storeCustomerInit = new StoreCustomersController();
		if (STORE_NAME != 'Woocommerce') {
			$StoreGrpCustomerRes = $storeCustomerInit->getAllStoreGroupCustomers($customerGroupId, $storeId);
			if (!empty($StoreGrpCustomerRes)) {
				$GroupResponseArray['customer_list'] = $StoreGrpCustomerRes;
			}
		} else {
			$groupCustomerObj = (new CustomerGroupRel())->select(['customer_id'])
				->where('customer_group_id', '=', $customerGroupId);
			if ($groupCustomerObj->count() > 0) {
				$groupCustomers = $groupCustomerObj->get()->toArray();
				$args = ['isCustomerGroup' =>  1];
				$groupCustomerData = [];
				// get each cumstomer details from the store and populate
				foreach ($groupCustomers as $groupCustomer) {
					$args['id'] = $groupCustomer['customer_id'];
					$customerDetail = $storeCustomerInit->getCustomers($request, $response, $args);
					if (!empty($customerDetail)) {
						$groupCustomerData[] = [
							'id' => $groupCustomer['customer_id'],
							'name' => $customerDetail['firstname'] . " " . $customerDetail['lastname'],
							'email' => ($customerDetail['email'] ? $customerDetail['email'] : '')
						];
					}
				}
				$GroupResponseArray['customer_list'] = $groupCustomerData;
			}
		}

		return $GroupResponseArray;
	}

	/**
	 * Return customer list
	 *
	 * @author dan@imprintnext.com
	 * @date   06 July 2022
	 * 
	 * @param object $request : Slim request
	 * @param object $response : Slim respose
	 * @param array $args :(id: group id)
	 * @return array $jsonResponse : list customer group
	 */
	public function allCustomerGroup($request, $response, $args) {

		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = ['status' => 0, 'message' => message('Customer group', 'not_found'), 'data' => []];

		try {
			$GroupResponseArray = []; # default blank data
			$storeId = $request->getQueryParam('store_id');
			// Get Store id from helper if not provided with the request
			if (empty($storeId)) {
				$getStoreDetails = get_store_details($request);
				$storeId = $getStoreDetails['store_id'];
				$updateParams = array_merge($request->getQueryParams(), ['store_id' => $storeId]);
				$request = $request->withQueryParams($updateParams);
			}

			// For single customer group data fetch
			if (!empty($args['id'])) {
				$GroupResponseArray = $this->_singleCustomerGroup($request, $response, $args);
				$jsonResponse = ['status' => 1, 'data' => $GroupResponseArray];
				return response($response, [
					'data' => $jsonResponse, 'status' => $serverStatusCode
				]);
			}

			//pagination params
			$page = $request->getQueryParam('page') ? $request->getQueryParam('page') : 1;
			$perpage = $request->getQueryParam('perpage') ? $request->getQueryParam('perpage') : 10;
			$name = $request->getQueryParam('name') ? $request->getQueryParam('name') : '';
			$categoryId = $request->getQueryParam('asset_cat_id') ? $request->getQueryParam('asset_cat_id') : '';
			$AssetType = $request->getQueryParam('asset_type_id') ? $request->getQueryParam('asset_type_id') : '';

			//geting store customer groups 
			$filters = ['search' => $name, 'store_id' => $storeId];
			if (!empty($page)) {
				$filters['page'] = $page;
				$filters['perpage'] = $perpage;
				$filters['offset'] = $perpage * ($page - 1);
			}
			$componentCtrlObj = new ComponenetController();
			// get the clipart asset type id
			$assetTypeArr = $componentCtrlObj->assetsTypeId('cliparts');
			$clipartAssetTypeId = $assetTypeArr['asset_type_id'];
			// get the template asset type id
			$assetTypeArr = $componentCtrlObj->assetsTypeId('templates');
			$templateAssetTypeId = $assetTypeArr['asset_type_id'];

			if (STORE_NAME != 'Woocommerce') {
				// get all store customers
				$storeCustomerInit = new StoreCustomersController();
				$storeCustomerGroup = $storeCustomerInit->getAllStoreGroups($filters);
				$storeTotalCustomerGroup = $storeCustomerGroup['total_records'];
				$storeCustomerGroup = $storeCustomerGroup['data'];


				//Mapping the store groups with asset data
				foreach ($storeCustomerGroup as $storeGroup) {
					// get all customer based on store group customers
					$allcustomerGroups = (new CustomerGroup())->where([
						['store_id', '=', $storeId],
						['store_ref_id', '=', $storeGroup['id_group']]
					])->get()->first();

					$GroupResponse = [
						'id' => $storeGroup['id_group'],
						'company_name' => (!empty($allcustomerGroups->name)  ? $allcustomerGroups->name : $storeGroup['name']),
						'tier_price_enable' => (!empty($allcustomerGroups->tier_price_enable)  ? $allcustomerGroups->tier_price_enable : 0),
						'address' => (!empty($allcustomerGroups->group_address)  ? $allcustomerGroups->group_address : ''),
						'logo' => (!empty($allcustomerGroups->group_img)  ? path('read', 'customer_group') . $allcustomerGroups->group_img : null),
						'email' => (!empty($allcustomerGroups->group_primary_email)  ? $allcustomerGroups->group_primary_email : ''),
						'phone' => (!empty($allcustomerGroups->group_primary_number)  ? $allcustomerGroups->group_primary_number : ''),
						'clipart_list' => [], 'template_list' => [], 'customer_list' => []
					];

					// get the clipart asset details
					$groupClipArt = (new CustomerGroupAssets())->where([
						['customer_group_id', '=', $storeGroup['id_group']],
						['asset_type_id', '=', $clipartAssetTypeId]
					]);
					if ($groupClipArt->count() > 0) { # If clipart data is availble
						$groupClipArtArry = $groupClipArt->get()->toArray();
						$assetDetails = $this->getAssetDetails($groupClipArtArry, $clipartAssetTypeId, $storeId);
						$GroupResponse['clipart_list'] =  $assetDetails;
					}

					// get the template type asset details
					$groupTemplate = (new CustomerGroupAssets())->where([
						['customer_group_id', '=', $storeGroup['id_group']],
						['asset_type_id', '=', $templateAssetTypeId]
					]);
					if ($groupTemplate->count() > 0) { # If template data is availble
						$groupTemplateArry = $groupTemplate->get()->toArray();
						$assetDetails = $this->getAssetDetails($groupTemplateArry, $templateAssetTypeId, $storeId);
						$GroupResponse['template_list'] =  $assetDetails;
					}

					// fetching all store group-wise customer
					$StoreGrpCustomerRes = $storeCustomerInit->getAllStoreGroupCustomers($storeGroup['id_group'], $storeId, true);
					$GroupResponse['customer_count'] =  $StoreGrpCustomerRes;

					// checking the assigned asset by id
					if (!empty($categoryId) && !empty($AssetType)) {
						$assetCheck = (new CustomerGroupAssets())->where([
							['customer_group_id', '=', $storeGroup['id_group']],
							['category_id', '=', $categoryId],
							['asset_type_id', '=', $AssetType]
						])->count();
						$GroupResponse['is_assigned'] = ($assetCheck > 0) ? 1 : 0;
					}
					$GroupResponseArray[] = $GroupResponse;
				}
			} else {
				$genericStoreResponse = $this->getAllGenericGroups($filters, $storeId);
				$storeTotalCustomerGroup = $this->getTotalAllGenericGroups($filters, $storeId);
				if (!empty($genericStoreResponse['data'])) {
					foreach ($genericStoreResponse['data'] as $val) {
						$GroupResponse = [
							'id' => $val['xe_id'],
							'company_name' => ($val['name'] ? $val['name'] : ''),
							'tier_price_enable' => ($val['tier_price_enable'] ? $val['tier_price_enable'] : 0),
							'address' => ($val['group_address'] ? $val['group_address'] : ''),
							'logo' => ($val['group_img'] ? path('read', 'customer_group') . $val['group_img'] : null),
							'email' => ($val['group_primary_email'] ? $val['group_primary_email'] : ''),
							'phone' => ($val['group_primary_number'] ? $val['group_primary_number'] : ''),
							'clipart_list' => [], 'template_list' => [], 'customer_list' => []
						];

						// get the clipart asset details
						$groupClipArt = (new CustomerGroupAssets())->where([
							['customer_group_id', '=', $val['xe_id']],
							['asset_type_id', '=', $clipartAssetTypeId]
						]);
						if ($groupClipArt->count() > 0) { #If clipart data is availble
							$groupClipArtArry = $groupClipArt->get()->toArray();
							$assetDetails = $this->getAssetDetails($groupClipArtArry, $clipartAssetTypeId, $storeId);
							$GroupResponse['clipart_list'] = $assetDetails;
						}

						// get the template type asset details
						$groupTemplate = (new CustomerGroupAssets())->where([
							['customer_group_id', '=', $val['xe_id']],
							['asset_type_id', '=', $templateAssetTypeId]
						]);
						if ($groupTemplate->count() > 0) { # If template data is availble
							$groupTemplateArry = $groupTemplate->get()->toArray();
							$assetDetails = $this->getAssetDetails($groupTemplateArry, $templateAssetTypeId, $storeId);
							$GroupResponse['template_list'] = $assetDetails;
						}

						$groupCustomerObj = (new CustomerGroupRel())->where('customer_group_id', '=', $val['xe_id']);
						$groupCustomerCount = $groupCustomerObj->count();
						$GroupResponse['customer_count'] = $groupCustomerCount;
						$GroupResponse['customer_list'] = [];

						if (!empty($categoryId) && !empty($AssetType)) {
							$assetCheck = (new CustomerGroupAssets())->where([
								['customer_group_id', '=', $val['xe_id']],
								['category_id', '=', $categoryId],
								['asset_type_id', '=', $AssetType]
							])->count();
							$GroupResponse['is_assigned'] = ($assetCheck > 0) ? 1 : 0;
						}
						$GroupResponseArray[] = $GroupResponse;
					}
				}
			}
			$jsonResponse = [
				'status' => 1,
				'records' => count($GroupResponseArray),
				'total_records' => $storeTotalCustomerGroup,
				'data' => $GroupResponseArray,
			];
		} catch (\Exception $e) {
			$jsonResponse['message'] = $e->getMessage();
		}

		return response($response, [
			'data' => $jsonResponse, 'status' => $serverStatusCode
		]);
	}

	/**
	 * Get all generic group (internal)
	 *
	 * 
	 * @param array $filters : array of fileters
	 * @param integer $store_id : store id
	 * @return array $genericGroups : generic group array
	 */
	protected function getAllGenericGroups($filters, $store_id) {
		$genericGroups = ['data' => []];

		// get filters
		$totalItem = $filters['perpage'];
		$offset = $filters['offset'];
		$search = $filters['name'];

		$conditions = [['store_id', '=', $store_id]];
		// apply filters
		if (!empty($search)) {
			$conditions[] = ['name', 'LIKE', "%{$search}%"];
		}
		// get all customers
		$allcustomerGroups = (new CustomerGroup())->where($conditions)
			->skip($offset)->take($totalItem)->orderBy('xe_id', 'desc');
		$customerGroupData = $allcustomerGroups->get()->toArray();
		if (!empty($customerGroupData)) {
			$genericGroups['data'] = $customerGroupData;
		}

		return $genericGroups;
	}

	/**
	 * Get Customer group count (internal)
	 *
	 * @author steve@imprintnext.com
	 * @date   27 Jun 2022
	 * 
	 * @param array $filters : array of fileters
	 * @param integer $store_id : store id
	 * @return integer : customer group count
	 */
	protected function getTotalAllGenericGroups($filters, $store_id) {
		$allcustomerGroups = (new CustomerGroup())->where('store_id', '=', $store_id);
		return $allcustomerGroups->count();
	}

	/**
	 * Get all generic group (internal)
	 *
	 * 
	 * @param array $assetCategories : asset category id
	 * @param integer $assetTypeId : asset category id
	 * @param integer $storeId : store id
	 * @return array $genericGroups : generic group list array
	 */
	protected function getAssetDetails($assetCategories, $assetTypeId, $storeId) {
		$data = []; // default data
		// checking the asset categories
		if (!empty($assetCategories)) {
			// format category id: convert to array
			$categoryIDs = array_column($assetCategories, 'category_id');

			// fetch all categories
			$getCategories = (new Category())->where([
				['asset_type_id', '=', $assetTypeId],
				['store_id', '=', $storeId],
				[
					function ($q) use ($categoryIDs) {
						return $q->whereIn('xe_id', $categoryIDs);
					}
				]
			])
			->select('xe_id as id', 'parent_id', 'name', 'sort_order')
			->orderBy('sort_order', 'asc');
			if ($getCategories->count() > 0) {
				$data = $getCategories->get()->toArray();
			}
		}
		return $data;
	}


	/**
	 * Create customer group
	 *
	 * 
	 * @param object $request : Slim request
	 * @param object $response : Slim respose
	 * @return array $jsonResponse : customer_group_id
	 */
	public function customerGroupCreate($request, $response) {
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = ['status' => 0, 'message' => message('Customer group', 'not_found'), 'data' => []];
		try {
			// Get Store Specific Details from helper
			$storeId = $request->getQueryParam('store_id');
			if (empty($storeId)) {
				$getStoreDetails = get_store_details($request);
				$storeId = $getStoreDetails['store_id'];
			}

			$allPostPutVars = $request->getParsedBody();
			$now = date('Y-m-d');

			//if form data is available
			if (!empty($allPostPutVars)) {
				$companyName = !empty($allPostPutVars['company_name']) ? $allPostPutVars['company_name'] : '';
				// check if same groupname record exists
				$customerGroupInit = new CustomerGroup();
				$chkcustomerGrpName = $customerGroupInit->where('name', '=', $companyName);
				if ($chkcustomerGrpName->count() != 0) {
					$jsonResponse = [
						'status' => 0,
						'message' => 'Company name already exists',
						'data'    => []
					];
					return response($response, [
						'data' => $jsonResponse, 'status' => $serverStatusCode
					]);
				}

				$formData = [
					'name' => $companyName,
					'group_url' => !empty($allPostPutVars['company_url']) ? $allPostPutVars['company_url'] : '',
					'group_address' => !empty($allPostPutVars['company_address']) ? $allPostPutVars['company_address'] : '',
					'group_primary_email' => !empty($allPostPutVars['primary_email']) ? $allPostPutVars['primary_email'] : '',
					'group_secondary_email' => !empty($allPostPutVars['secondary_email']) ? $allPostPutVars['secondary_email'] : '',
					'group_primary_number' => !empty($allPostPutVars['phone_number']) ? $allPostPutVars['phone_number'] : '',
					'group_alt_number' => !empty($allPostPutVars['alternative_number']) ? $allPostPutVars['alternative_number'] : '',
					'group_fax' => !empty($allPostPutVars['fax']) ? $allPostPutVars['fax'] : '',
					'slug' => !empty($allPostPutVars['slug']) ? $allPostPutVars['slug'] : $allPostPutVars['company_name'],
					'discount_enable' => !empty($allPostPutVars['discount_enable']) ? $allPostPutVars['discount_enable'] : 0,
					'flat_discount' => !empty($allPostPutVars['price_discount']) ? $allPostPutVars['price_discount'] : 0,
					'store_id' => !empty($allPostPutVars['store_id']) ? $allPostPutVars['store_id'] : 1,
					'created_at' => $now,
					'store_ref_id' => null
				];

				// logo upload 
				$uploadedLogo = $request->getUploadedFiles();
				if (array_key_exists('company_logo', $uploadedLogo)) {
					$logoFileName = do_upload('company_logo', path('abs', 'customer_group'), [], 'string');
					$formData['group_img'] = $logoFileName;
				}

				// Tier price discount checking
				$tierPriceData = (!empty($allPostPutVars['tier_price_data']) ? json_clean_decode($allPostPutVars['tier_price_data']) : '');
				if (!empty($tierPriceData)) {
					$formData['discount_type'] = 'tier';
					$formData['tier_price_enable'] = $allPostPutVars['tier_price_enable'] ? $allPostPutVars['tier_price_enable'] : 0;
				}

				// Creating store group
				$customers = json_clean_decode($allPostPutVars['customer_id']);
				// if group is created in store
				if (STORE_NAME != 'Woocommerce') {
					$storeCustomerInit = new StoreCustomersController();
					$storeCreateData = $storeCustomerInit->createStoreCustomerGroup($allPostPutVars['company_name'], $customers, $storeId);
					$storeGroupId = $storeCreateData['data'];
					$formData['store_ref_id'] = $storeGroupId;
				}

				$newCustomerGroup = new CustomerGroup($formData);
				if ($newCustomerGroup->save()) {
					$createdGroupId = (STORE_NAME == 'Woocommerce') ? $newCustomerGroup->xe_id : $newCustomerGroup->store_ref_id;
					//saving tier price discount
					if (!empty($tierPriceData)) {
						foreach ($tierPriceData as $tierPrice) {
							$this->saveTierPrice($createdGroupId, $tierPrice);
						}
					}

					//saving customer group relation
					if (!empty($allPostPutVars['customer_id'])) {
						$groupCustomers = json_clean_decode($allPostPutVars['customer_id']);
						//inserting customer id in rel table
						foreach ($groupCustomers as $val) {
							$customerData = [
								'customer_id' => $val, 'customer_group_id' => $createdGroupId
							];
							//create mapping entry 
							$CustomerGroupRelObj = new CustomerGroupRel($customerData);
							$CustomerGroupRelObj->save();
						}
					}
					$componentCtrlObj = new ComponenetController();
					//saving clipart data in mapping table
					if (!empty($allPostPutVars['assigned_clipart_category'])) {
						$assetTypeArr = $componentCtrlObj->assetsTypeId('cliparts');
						$assetTypeId = $assetTypeArr['asset_type_id'];
						$customerGrpCliparts = json_clean_decode($allPostPutVars['assigned_clipart_category']);
						//inserting in asset mapping table
						foreach ($customerGrpCliparts as $val) {
							$clipArtData = [
								'customer_group_id' => $createdGroupId,
								'asset_type_id' => $assetTypeId,
								'category_id' => $val
							];
							$clipArtObj = new CustomerGroupAssets($clipArtData);
							$clipArtObj->save();
						}
					}

					// saving template data in mapping table
					if (!empty($allPostPutVars['assigned_template_category'])) {
						$assetTypeArr = $componentCtrlObj->assetsTypeId('templates');
						$assetTypeId = $assetTypeArr['asset_type_id'];
						$customerGrpTempl = json_clean_decode($allPostPutVars['assigned_template_category']);
						// inserting in asset mapping table
						foreach ($customerGrpTempl as $val) {
							$templateData = [
								'customer_group_id' => $createdGroupId,
								'asset_type_id' => $assetTypeId,
								'category_id' => $val
							];
							$templatetObj = new CustomerGroupAssets($templateData);
							$templatetObj->save();
						}
					}

					$jsonResponse = [
						'status' => 1,
						'message' => 'customer group created.',
						'data'    => ['customer_group_id' => $createdGroupId]
					];
				}
			}
		} catch (\Exception $e) {
			$jsonResponse['message'] = $e->getMessage();
		}
		return response($response, [
			'data' => $jsonResponse, 'status' => $serverStatusCode
		]);
	}

	/**
	 * Customer group update
	 *
	 * 
	 * @param object $request : Slim request
	 * @param object $response : Slim respose
	 * @param array $args : (id: customer group id)
	 * @return array $jsonResponse
	 */

	public function customerGroupUpdate($request, $response, $args) {
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = ['status' => 0, 'message' => message('Customer group', 'error')];

		if (!empty($args['id'])) {
			try {
				$customerGroupId = $args['id'];
				$allPostPutVars = $request->getParsedBody();
				// Get the Store id
				$storeId = $allPostPutVars['store_id'];
				if (empty($storeId)) {
					$getStoreDetails = get_store_details($request);
					$storeId = $getStoreDetails['store_id'];
				}

				$updateData = [
					'tier_price_enable' => !empty($allPostPutVars['tier_price_enable']) ? $allPostPutVars['tier_price_enable'] : 0,
					'flat_discount' => !empty($allPostPutVars['price_discount']) ? $allPostPutVars['price_discount'] : 0,
					'name' => !empty($allPostPutVars['company_name']) ? $allPostPutVars['company_name'] : '',
					'group_url' => !empty($allPostPutVars['company_url']) ? $allPostPutVars['company_url'] : '',
					'discount_enable' => !empty($allPostPutVars['discount_enable']) ? $allPostPutVars['discount_enable'] : 0,
					'group_address' => !empty($allPostPutVars['company_address']) ? $allPostPutVars['company_address'] : '',
					'group_primary_email' => !empty($allPostPutVars['primary_email']) ? $allPostPutVars['primary_email'] : '',
					'group_secondary_email' => !empty($allPostPutVars['secondary_email']) ? $allPostPutVars['secondary_email'] : '',
					'group_primary_number' => !empty($allPostPutVars['phone_number']) ? $allPostPutVars['phone_number'] : '',
					'group_alt_number' => !empty($allPostPutVars['alternative_number']) ? $allPostPutVars['alternative_number'] : '',
					'group_fax' => !empty($allPostPutVars['fax']) ? $allPostPutVars['fax'] : '',
					'slug'  => !empty($allPostPutVars['slug']) ? $allPostPutVars['slug'] : $allPostPutVars['company_name'],
					'store_id' => $storeId,
					'discount_type' => (!empty($allPostPutVars['tier_price_enable']) ? 'tier' : 'flat')
				];

				// get the correct customer group condition
				$conditions = [['store_ref_id', '=', $customerGroupId]];
				if (STORE_NAME == 'Woocommerce') {
					$conditions = [['xe_id', '=', $customerGroupId]];
				}
				// find the group
				$getOldcustomerGroup = (new CustomerGroup())->where($conditions);

				$storeResponse = ['status' => 1]; // default set to 1
				// updating store group
				if (STORE_NAME != 'Woocommerce') {
					if ($getOldcustomerGroup->count() == 0) {
						// create relational record for the group created through store.
						$updateData['store_ref_id'] = $customerGroupId;
						$newCustomerGroup = new CustomerGroup($updateData);
						$newCustomerGroup->save();
					}
					// update the customers for the group
					$formData = [
						'id' => $customerGroupId,
						'name' => $allPostPutVars['company_name'],
						'customer_id' => (!empty($allPostPutVars['customer_id']) ? json_clean_decode($allPostPutVars['customer_id']) : [])
					];
					$storeCustomerInit = new StoreCustomersController();
					$storeResponse = $storeCustomerInit->updateStoreCustomerGroup($formData);
				}

				if ($storeResponse['status'] == 1) {
					// logo update
					$uploadedFiles = $request->getUploadedFiles();
					if (array_key_exists('company_logo', $uploadedFiles)) {
						// delete old logo file
						$componentCtrlObj = new ComponenetController();
						$componentCtrlObj->deleteOldFile(
							'customer_groups',
							'group_img',
							$conditions,
							path('abs', 'customer_group')
						);
						// upload the new logo
						$logoFileName = do_upload('company_logo', path('abs', 'customer_group'), [], 'string');
						if (!empty($logoFileName)) {
							$updateData['group_img'] = $logoFileName;
						}
					}
					$componentCtrlObj = new ComponenetController();
					// template mapping update  
					if (!empty($allPostPutVars['assigned_template_category'])) {
						$newTemplatesIds = json_clean_decode($allPostPutVars['assigned_template_category']);
						$assetTypeArr = $componentCtrlObj->assetsTypeId('templates');
						$assetTypeId = $assetTypeArr['asset_type_id'];
						//deleting old mapping entries
						$this->deleteGroupAssetRelation($customerGroupId, $assetTypeId);
						//for all template ids
						foreach ($newTemplatesIds as $val) {
							$templateData = [
								'customer_group_id' => $customerGroupId,
								'asset_type_id' => $assetTypeId,
								'category_id' => $val
							];
							$templatetObj = new CustomerGroupAssets($templateData);
							$templatetObj->save();
						}
					}

					// clipart mapping update
					if (!empty($allPostPutVars['assigned_clipart_category'])) {
						$assetTypeArr = $componentCtrlObj->assetsTypeId('cliparts');
						$assetTypeId = $assetTypeArr['asset_type_id'];
						$newClipartsIds = json_clean_decode($allPostPutVars['assigned_clipart_category']);

						// deleting old mapping entries
						$this->deleteGroupAssetRelation($customerGroupId, $assetTypeId);

						// for all clipart ids
						foreach ($newClipartsIds as $val) {
							$clipArtData = [
								'customer_group_id' => $customerGroupId,
								'asset_type_id' => $assetTypeId,
								'category_id' => $val
							];
							$clipArtObj = new CustomerGroupAssets($clipArtData);
							$clipArtObj->save();
						}
					}

					// customer relation mapping
					if (!empty($allPostPutVars['customer_id'])) {
						$newCustomersIds = json_clean_decode($allPostPutVars['customer_id']);
						//deleting old mapping entries
						$this->deleteCustomerGroupRelation($customerGroupId);

						foreach ($newCustomersIds as $val) {
							$customers = [
								'customer_id' => $val,
								'customer_group_id' => $customerGroupId
							];
							//create mapping entry 
							$CustomerGroupRelObj = new CustomerGroupRel($customers);
							$CustomerGroupRelObj->save();
						}
					}

					// tier price mapping update
					if (!empty($allPostPutVars['tier_price_data']) && $allPostPutVars['tier_price_enable'] == 1) {
						$newTierPriceData = json_clean_decode($allPostPutVars['tier_price_data']);
						//deleting old mapping entries
						$this->deleteGroupDiscountTier($customerGroupId);
						foreach ($newTierPriceData as $val) {
							$this->saveTierPrice($customerGroupId, $val);
						}
					}
					// update the customer group
					$getOldcustomerGroup->update($updateData);
					$jsonResponse = ['status' => 1, 'message' => 'Customer group updated'];
				}
			} catch (\Exception $e) {
				$jsonResponse['message'] = $e->getMessage();
			}
		}
		return response($response, [
			'data' => $jsonResponse, 'status' => $serverStatusCode
		]);
	}

	/**
	 * Delete customer group relation (internal)
	 *
	 * 
	 * @param integer $customer_group_id : customer group id
	 * @return boolean: true on success
	 */

	protected function deleteCustomerGroupRelation($customer_group_id) {
		if (!empty($customer_group_id)) {
			$customerRelObj = new CustomerGroupRel();
			$customerRelObj->where('customer_group_id', '=', $customer_group_id)
				->delete();
			return true;
		}
		return false;
	}

	/**
	 * Delete customer group-asset relation (internal)
	 *
	 * 
	 * @param integer $customer_group_id : customer group id
	 * @param integer $type : asset type id
	 * @return boolean: true on success
	 */

	protected function deleteGroupAssetRelation($customer_group_id, $type) {
		if (!empty($customer_group_id) && !empty($type)) {
			$AssetRelObj = new CustomerGroupAssets();
			$AssetRelObj->where('customer_group_id', '=', $customer_group_id)->where('asset_type_id', '=', $type)->delete();
			return true;
		}
		return false;
	}

	/**
	 * Delete group discount (internal)
	 *
	 * 
	 * @param integer $customer_group_id : customer group id
	 * @return boolean: true on success
	 */

	protected function deleteGroupDiscountTier($customer_group_id) {
		if (!empty($customer_group_id)) {
			$DiscountTier = new CustomerGroupDiscount();
			$DiscountTier->where('customer_group_id', '=', $customer_group_id)->delete();
			return true;
		}
		return false;
	}

	/**
	 * Save tier price (internal)
	 *
	 * 
	 * @param integer $grp_id : customer group id
	 * @param array $data : tier price data
	 * @return boolean: true on success
	 */
	protected function saveTierPrice($grp_id, $data) {
		if (!empty($grp_id) && !empty($data)) {
			$discountData = [
				'customer_group_id' => $grp_id,
				'qty_from' => $data['from_qty'],
				'qty_to' => $data['to_qty'],
				'discount_rate' => $data['discount']
			];
			$tierPrice = new CustomerGroupDiscount($discountData);
			if ($tierPrice->save()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Customer group delete
	 *
	 * 
	 * @param object $request : Slim request
	 * @param object $response : Slim respose
	 * @param array $args : Slim param arguments
	 * @return array $jsonResponse
	 */

	public function customerGroupDelete($request, $response, $args) {
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = ['status' => 0, 'message' => message('Customer Group', 'error')];

		// get the store id from the helper
		$getStoreDetails = get_store_details($request);
		$storeId = $getStoreDetails['store_id'];

		if (!empty($args)) {
			// Multiple Ids in json format
			$getDeleteIdsToArray = json_clean_decode(trim($args['id']), true);

			if (!empty($getDeleteIdsToArray)) {
				$totalCount = count($getDeleteIdsToArray);
				$customerGroupInit = new CustomerGroup();

				if (STORE_NAME != 'Woocommerce') {
					$customerGroupCount = $customerGroupInit->whereIn('store_ref_id', $getDeleteIdsToArray); //->count();
				} else {
					$customerGroupCount = $customerGroupInit->whereIn('xe_id', $getDeleteIdsToArray); //->count();
				}

				//deleting records
				if ($customerGroupCount > 0) {
					try {
						$success = 0;
						$deleteStoreStatus = true;
						foreach ($getDeleteIdsToArray as $customerGroupId) {
							// delete groups in store
							if (STORE_NAME != 'Woocommerce') {
								$storeCustomerInit = new StoreCustomersController();
								$deleteStoreStatus = $storeCustomerInit->deleteStoreCustomerGroup($customerGroupId, $storeId);
							}
							if ($deleteStoreStatus) {
								// get the correct customer group condition
								if (STORE_NAME != 'Woocommerce') {
									$delConditions = [['store_ref_id', '=', $customerGroupId]];
								} else {
									$delConditions = [['xe_id', '=', $customerGroupId]];
								}

								if (STORE_NAME == 'Woocommerce') {
									$this->deleteCustomerGroupRelation($customerGroupId);
								}
								$componentCtrlObj = new ComponenetController();
								// deleting cliparts mapping entries
								$assetTypeArr = $componentCtrlObj->assetsTypeId('cliparts');
								$assetTypeId = $assetTypeArr['asset_type_id'];
								$this->deleteGroupAssetRelation($customerGroupId, $assetTypeId);

								// deleting template mapping entries
								$assetTypeArr = $componentCtrlObj->assetsTypeId('templates');
								$assetTypeId = $assetTypeArr['asset_type_id'];
								$this->deleteGroupAssetRelation($customerGroupId, $assetTypeId);

								// deleting discount entries
								$this->deleteGroupDiscountTier($customerGroupId);

								// delete old logo file
								$componentCtrlObj = new ComponenetController();
								$componentCtrlObj->deleteOldFile(
									'customer_groups',
									'group_img',
									$delConditions,
									path('abs', 'customer_group'),
									false
								);
								// delete the customer group
								(new CustomerGroup())->where($delConditions)->delete();
								$success++;
							}
						}
						$jsonResponse = [
							'status' => 1,
							'message' => $success . ' out of ' . $totalCount . ' Customer group(s) deleted successfully',
						];
					} catch (\Exception $e) {
						$serverStatusCode = EXCEPTION_OCCURED;
						create_log('customer group', 'error', [
							'message' => $e->getMessage(),
							'extra' => ['module' => 'Deleting a customer group']
						]);
					}
				}
			}
		}
		return response($response, [
			'data' => $jsonResponse, 'status' => $serverStatusCode
		]);
	}

	// ****customerGroupAssign:: function usages is unknown****
	public function customerGroupAssign($request, $response) {
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = ['status' => 0, 'message' => message('Customer group', 'not_found'), 'data' => []];
		try {
			// Get the form data
			$allPostPutVars = $request->getParsedBody();
			if (
				!empty($allPostPutVars['customer_group_id'])  &&
				!empty($allPostPutVars['cat_ids']) &&
				!empty($allPostPutVars['asset_type_id'])
			) {
				$customerGroups = json_clean_decode($allPostPutVars['customer_group_id']);
				$categoryIds = json_clean_decode($allPostPutVars['cat_ids']);
				$assetTypeId = to_int($allPostPutVars['asset_type_id']);

				//for every customer
				foreach ($customerGroups as $val) {
					//for every category
					foreach ($categoryIds as $cat) {
						$assetInit = new CustomerGroupAssets();
						$assetCheckCount = $assetInit->where('customer_group_id', '=', $val)
							->where('asset_type_id', '=', $assetTypeId)
							->where('category_id', '=', $cat)
							->count();

						if ($assetCheckCount == 0) {
							$assetData = [
								'customer_group_id' => $val,
								'asset_type_id' => $assetTypeId,
								'category_id' => $cat
							];
							$assetObj = new CustomerGroupAssets($assetData);
							$assetObj->save();
						}
					}
				}
				$jsonResponse = [
					'status' => 1,
					'message' => 'Customer group assets assigned successfully.',
				];
			}
		} catch (\Exception $e) {
			$jsonResponse['message'] = $e->getMessage();
		}

		return response($response, [
			'data' => $jsonResponse, 'status' => $serverStatusCode
		]);
	}

	//getting customer group id from store
	public function getGroupIdBycustomerId($customer_id, $storeId = 1) {
		if (!empty($customer_id)) {
			if (STORE_NAME != 'Woocommerce') {
				$storeCustomerInit = new StoreCustomersController();
				return $storeCustomerInit->getStoreGroupIdByCustomerId($customer_id);
			}
			$customerGroupsDetail = DB::table('customer_groups as CG')
				->join('customer_group_relation as CGR', 'CGR.customer_group_id', '=', 'CG.xe_id')
				->where('CGR.customer_id', '=', $customer_id)
				->where('CG.store_id', $storeId)
				->select('CG.xe_id')->get()->first();

			return $customerGroupsDetail->xe_id;
		}
	}
	//fetching mapping assets for group
	public function getAssetsBygroupId($customer_group_id, $assetTypeId, $store_id) {
		$catIds = [];
		if (!empty($customer_group_id)) {
			$aseetRelObj = new CustomerGroupAssets();
			$groupClipArt = $aseetRelObj->join('categories', 'customer_group_assets_category_rel.category_id', '=', 'categories.xe_id')
			->where('customer_group_assets_category_rel.customer_group_id', '=', $customer_group_id)
			->where('customer_group_assets_category_rel.asset_type_id', '=', $assetTypeId)
			->select('categories.xe_id')
			->groupBy('categories.xe_id')
			->get()
			->pluck('xe_id')
			->toArray();
			if (!empty($groupClipArt)) {
				$catIds = $groupClipArt;
			}
		}
		return $catIds;
	}

	// **** getDiscountDataBycustomerId:: usages of this method is unknown ****
	//shaping the discount for a group-customer
	public function getDiscountDataBycustomerId($request, $response, $args) {
		if (!empty($args['customerId'])) {
			$customerId = $args['customerId'];
			$discountdata = [
				'group_id' => '',
				'group_name' => '',
				'customer_name' => '',
				'customer_email' => '',
				'tier_price_enable' => 0,
				'flat_discount' => '',
				'tier_price_data' => []
			];
			$args['id'] = $customerId;
			$storeCustomerInit = new StoreCustomersController();
			$customerDetails = $storeCustomerInit->getCustomers($request, $response, $args);
			//checking for customer deatils
			if (!empty($customerDetails)) {
				$discountdata['customer_name'] = $customerDetails['first_name'] . " " . $customerDetails['last_name'];
				$discountdata['customer_email'] = $customerDetails['email'];
			}
			$storeId = $request->getQueryParam('store_id') ? $request->getQueryParam('store_id') : 1;
			$groupId = $this->getGroupIdBycustomerId($customerId, $storeId);
			//checking for customer group discount data
			if (!empty($groupId)) {
				$discountdata['group_id'] = $groupId;
				// get the customer group
				$conditions = [['store_ref_id', '=', $groupId]];
				if (STORE_NAME == 'Woocommerce') {
					$conditions = [['xe_id', '=', $groupId]];
				}
				$groupObj = (new CustomerGroup())->where($conditions)->select('tier_price_enable', 'discount_enable', 'flat_discount', 'name');
				if ($groupObj->count() > 0) {
					$groupData = $groupObj->get()->first();
					$discountdata['group_name']  = $groupData->name;
					$discountdata['discount_enable']  = $groupData->discount_enable;
					$discountdata['tier_price_enable'] = $groupData->tier_price_enable;
					$discountdata['flat_discount'] = $groupData->flat_discount;
				}

				$custGrpDiscountObj = (new CustomerGroupDiscount())->where('customer_group_id', '=', $groupId)
					->select('qty_from', 'qty_to', 'discount_rate');
				if ($custGrpDiscountObj->count() > 0) {
					$tierPriceData = $custGrpDiscountObj->get()->toArray();
					$discountdata['tier_price_data'] = $tierPriceData;
				}
			}
			return $discountdata;
		}
	}
}