<?php

/**
 * Manage Shapes
 *
 * PHP version 5.6
 *
 * @category  Shape
 * @package   Eloquent
 * @author    Satyabrata <satyabratap@riaxe.com>
 * @copyright 2019-2020 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\Shapes\Controllers;

use App\Components\Controllers\Component as ParentController;
use App\Modules\Shapes\Models\Shape;
use App\Modules\Shapes\Models\ShapeCategory as Category;
use App\Modules\Shapes\Models\ShapeCategoryRelation;
use App\Modules\Shapes\Models\ShapeTagRelation;
use Illuminate\Database\Capsule\Manager as DB;
use App\Modules\PrintProfiles\Models as PrintProfileModels;
use App\Modules\PrintProfiles\Models\PrintProfileAssetsCategoryRel;

/**
 * Shape Controller
 *
 * @category Class
 * @package  Shape
 * @author   Satyabrata <satyabratap@riaxe.com>
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @link     http://inkxe-v10.inkxe.io/xetool/admin
 */
class ShapeController extends ParentController
{
	/**
	 * POST: Save Shape
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 *
	 * @author satyabratap@riaxe.com
	 * @date   4th Nov 2019
	 * @return json
	 */
	public function saveShapes($request, $response)
	{
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = [
			'status' => 0,
			'message' => message('Shapes', 'error')
		];

		// Get Store Specific Details from helper
		$getStoreDetails = get_store_details($request);
		$storeId = $getStoreDetails['store_id'];

		$allPostPutVars = $request->getParsedBody();

		// Save file if request contain files
		$allFileNames = do_upload('upload', path('abs', 'shape'), [150], 'array');
		$uploadingFilesNo = count($allFileNames);
		if (!empty($allFileNames)) {
			$success = 0; // number of success records
			$isS3Enabled = $this->checkS3Settings($storeId);
			// remove empty value - skip empty check in loop
			$allFileNames = array_filter($allFileNames);
			foreach ($allFileNames as $eachFile) {
				$saveShapeList = [
					'store_id' => $storeId,
					'name' => $allPostPutVars['name'],
					'cloud_storage' => 0,
					'file_name' => $eachFile
				];
				// move file to cloud if enabled
				if ($isS3Enabled) {
					$fileToUpload = path('abs', 'shape') . $eachFile;
					$this->uploadFileToS3("shape", $fileToUpload, $storeId);
					$saveShapeList['cloud_storage'] = 1;
				}
				// save the shape data (create new)
				$saveEachShape = new Shape($saveShapeList);
				if ($saveEachShape->save()) {
					$lastInsertId = $saveEachShape->xe_id;
					/**
					 * Save category and subcategory data
					 * Category id format: [4,78,3]
					 */
					if (!empty($allPostPutVars['categories'])) {
						$categoryIds = $allPostPutVars['categories'];
						$this->saveShapeCategories($lastInsertId, $categoryIds);
					}
					/**
					 * Save tags
					 * Tag Names format : tag1,tag2,tag3
					 */
					$tags = !empty($allPostPutVars['tags'])
						? $allPostPutVars['tags'] : "";
					$this->saveShapeTags($storeId, $lastInsertId, $tags);
				}
				$success++;
			}
			$this->memcache('deleteMulti', '', '', "shapes_cat");
			if (!empty($categoryIds)) {
				$catgories = str_replace(array('\'', '"', '[', ']', '<', '>'), ' ', $categoryIds);
				$catIdArr = array_map('trim', array_filter(explode(",", $catgories)));
				foreach ($catIdArr as $categoryId) {
					$ppAssetCatRelGtInit = new PrintProfileModels\PrintProfileAssetsCategoryRel();
					$printProfileIds = $ppAssetCatRelGtInit->where('category_id', $categoryId)->pluck('print_profile_id');
					$this->createUpdateAssetJsonCache($getStoreDetails['store_id'], $printProfileIds, 'shapes', $request, $response);
				}
			}
		}
		if ($success) {
			$jsonResponse = [
				'status' => 1,
				'message' => $success . ' out of ' . $uploadingFilesNo
					. ' Shape(s) uploaded successfully'
			];
		}
		//Flush shape memcached
		$this->memcache('deleteMulti', '', '', 'shape');
		return response($response, [
			'data' => $jsonResponse,
			'status' => $serverStatusCode
		]);
	}

	/**
	 * Save Categories/Sub-categories and Shape-Category Relations
	 *
	 * @param $shapeId     Shape ID
	 * @param $categoryIds (in  an array with comma separated)
	 *
	 * @author satyabratap@riaxe.com
	 * @date   4th Nov 2019
	 * @return boolean
	 */
	protected function saveShapeCategories($shapeId, $categoryIds)
	{
		$getAllCategoryArr = json_clean_decode($categoryIds, true);
		// SYNC Categories to the Shape_Category Relationship Table
		foreach ($getAllCategoryArr as $catId) {
			$shapeCat = new Category();
			$categoriesData = $shapeCat->where('xe_id', '=', $catId)->get()->toArray();
			if ($catId == $categoriesData[0]['xe_id']) {
				$flagList = ['asset_available_flag' => 1];
				$shapeCat->where('xe_id', '=', $catId)->update($flagList);
			}
		}
		$shapeInit = new Shape();
		$findShape = $shapeInit->find($shapeId);
		if ($findShape->categories()->sync($getAllCategoryArr)) {
			return true;
		}
		return false;
	}

	/**
	 * Save Tags and Shape-Tag Relations
	 *
	 * @param $storeId Shape ID
	 * @param $shapeId Shape ID
	 * @param $tags    Multiple Tags
	 *
	 * @author satyabratap@riaxe.com
	 * @date   4th Nov 2019
	 * @return boolean
	 */
	protected function saveShapeTags($storeId, $shapeId, $tags)
	{
		// Save Shape and tags relation
		if (!empty($tags)) {
			$getTagIds = $this->saveTags($storeId, $tags);
			// SYNC Tags into Relationship Table
			$shapeInit = new Shape();
			$findShape = $shapeInit->find($shapeId);
			if ($findShape->tags()->sync($getTagIds)) {
				return true;
			}
		} else {
			// Clean relation in case no tags supplied
			$tagRelInit = new ShapeTagRelation();
			$shapeTags = $tagRelInit->where('shape_id', $shapeId);
			if ($shapeTags->delete()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * GET: List of Shape
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author satyabratap@riaxe.com
	 * @date   4th Nov 2019
	 * @return All/Single Shape List
	 */
	public function getSingleShapes($request, $response, $args)
	{
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = [
			'status' => 0,
			'data' => [],
			'message' => message('Shapes', 'not_found'),
		];

		// Get Store Specific Details from helper
		$getStoreDetails = get_store_details($request);

		$shapeId = to_int($args['id']);

		$shapeInit = new Shape();
		$getShapes = $shapeInit->where([
			['xe_id', '>', 0],
			['store_id', '=', $getStoreDetails['store_id']],
			['xe_id', '=', $shapeId]
		]);

		// remove all appends (skip unset 'category_names')
		$shapeData = $getShapes->first()->setAppends([])->toArray();

		if (!empty($shapeData)) {
			// get the cloud url for the file
			if ($shapeData['cloud_storage'] == 1) {
				$value = $this->getS3URL($shapeData['file_name'], $getStoreDetails['store_id']);
				$shapeData['file_name'] = $value;
			}
			// Get Category Ids
			$getCategories = $this->getCategoriesById(
				'Shapes',
				'ShapeCategoryRelation',
				'shape_id',
				$shapeId
			);
			// Get tags
			$getTags = $this->getTagsById(
				'Shapes',
				'ShapeTagRelation',
				'shape_id',
				$shapeId
			);
			$shapeData['categories'] = $getCategories;
			$shapeData['tags'] = $getTags;

			$jsonResponse = ['status' => 1, 'data' => [$shapeData]];
		}

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

	/**
	 * Internal: Shape for tool
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author dan@imprintnext.com
	 * @date   20-07-2022
	 * @return All Shapes for tool
	 */

	private function _getShapesForTool($request, $response, $args)
	{
		$jsonResponse = [
			'status' => 0,
			'data' => [],
			'message' => message('Shapes', 'not_found')
		];

		$records = $totalRecords = 0;
		$categoriesList = [];

		// filter params
		$getStoreDetails = get_store_details($request);
		$storeId = $getStoreDetails['store_id'];
		$source = $request->getQueryParam('source') ?
			$request->getQueryParam('source') : '';
		$page = $request->getQueryParam('page');
		$perpage = $request->getQueryParam('perpage');
		$sortBy = !empty($request->getQueryParam('sortby'))
			&& $request->getQueryParam('sortby') != ""
			? $request->getQueryParam('sortby') : 'xe_id';
		$order = !empty($request->getQueryParam('order'))
			&& $request->getQueryParam('order') != ""
			? $request->getQueryParam('order') : 'desc';
		$name = $request->getQueryParam('name');

		$currentStoreUrl = '';
		if ($storeId > 1) {
			$databaseStoreInfo = DB::table('stores')->where('xe_id', '=', $storeId);
			if ($databaseStoreInfo->count() > 0) {
				$storeData = $databaseStoreInfo->get()->first();
				$currentStoreUrl = $storeData->store_url;
			}
		}

		// multistore flag
		$isMultiStore = ($storeId > 1 && !empty($currentStoreUrl) && $source != 'admin');

		// get the shape category list
		$shapesCategoryList = $this->getCategoryByPrintProfileId($request, $response, $args);
		if (!empty($shapesCategoryList) && !empty($shapesCategoryList['data'])) {
			$records = $shapesCategoryList['records'];
			$totalRecords = $shapesCategoryList['total_records'];

			foreach ($shapesCategoryList['data'] as $category) {
				// Filter by Category IDs and It's Subcategory IDs
				if (!empty($category->id)) {
					$shapeInit = new Shape();
					$getShapes = $shapeInit->join('shape_category_rel as scr', 'scr.shape_id', '=', 'shapes.xe_id')
						->where([
							['xe_id', '>', 0],
							['store_id', '=', $storeId],
							['scr.category_id', $category->id]
						])
						->select(['shapes.xe_id', 'shapes.name', 'shapes.file_name', 'shapes.cloud_storage']);
					// filter by name
					if (isset($name) && $name != "") {
						$getShapes->where(function ($query) use ($name) {
							$query->where('shapes.name', 'LIKE', '%' . $name . '%')
								->orWhereHas('sTags', function ($query) use ($name) {
									return $query->where('tags.name', 'LIKE', '%' . $name . '%');
								});
						});
					}
					$getTotalPerFilters = $getShapes->count();
					// Pagination Data
					if (!empty($page)) {
						$totalItem = empty($perpage) ? PAGINATION_MAX_ROW : $perpage;
						$offset = $totalItem * ($page - 1);
						$getShapes->skip($offset)->take($totalItem);
					}
					// Sorting All records by column name and sord order parameter
					if (!empty($sortBy) && !empty($order)) {
						$getShapes->orderBy($sortBy, $order);
					}
					// get the shape list
					if ($getTotalPerFilters) {
						$shapesArr = $getShapes->get()->map(function ($item) {
							// unused field category_id
							$item->setHidden(['category_id']);
							return $item;
						})->toArray();

						$shapes = [];
						// format the shape list per category
						foreach ($shapesArr as $shapeValue) {
							$fileName = $shapeValue['file_name'];
							if ($fileName) {
								if ($shapeValue['cloud_storage'] == 1) {
									$fileName = $this->getS3URL($fileName, $storeId);
								} else {
									if ($isMultiStore && IS_HOSTED == 0) {
										$hostname = parse_url($fileName, PHP_URL_HOST); // hostname
										$fileName = str_replace($hostname, $currentStoreUrl, $fileName);
									}
								}
							}
							$shapes[] = [
								"name" => $shapeValue['name'],
								"file_name" => $fileName,
								"cloud_storage" => $shapeValue['cloud_storage'],
								"category_names" => $shapeValue['category_names'],
							];
						}

						$categoriesList[] = [
							'id' =>  $category->id,
							'name' => $category->name,
							'image_path' => $category->file_name,
							'order' => $category->order,
							'is_disable' => $category->is_disable,
							'is_default' => $category->is_default,
							'shapes' => $shapes,
							'records' => count($shapes),
							'total_records' => $getTotalPerFilters
						];
					}
				}
			}
		}
		if (!empty($categoriesList)) {
			$jsonResponse = [
				'status' => 1,
				'records' => $records,
				'total_records' => $totalRecords,
				'data' => $categoriesList
			];
		}
		return $jsonResponse;
	}

	/**
	 * GET: List of Shape
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author satyabratap@riaxe.com
	 * @date   4th Nov 2019
	 * @return All Shape List
	 */
	public function getShapes($request, $response, $args)
	{
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = [
			'status' => 0,
			'data' => [],
			'message' => message('Shapes', 'not_found')
		];
		try {
			// Get Shapes According to Designer Tool
			$type = $request->getQueryParam('type');
			if ($type == 'tool') {
				$currentStoreId = $request->getQueryParam('store_id');
				$printProfileId = $request->getQueryParam('print_profile_id');
				$page = $request->getQueryParam('cat_page');
				$perpage = $request->getQueryParam('cat_perpage');
				$name = $request->getQueryParam('name');
				$order = $request->getQueryParam('cat_order');

				//MEMCACHED KEY
				$thisCacheKey = "shape" . "_page" . $page . "_order" . $order . "_perpage" . $perpage . "_pp" . $printProfileId . "_s" . $currentStoreId;


				//Register MEMCACHED KEY in Local Cache
				$this->createUpdateMemCacheGroup('shape', $thisCacheKey, 'SET');

				//GET MEMCACHEDATA
				$memcacheData = [];
				if (IS_MEMCACHE and empty($name)) {
					$memcacheData = $this->memcache("get", $thisCacheKey);
				}
				if (empty($memcacheData)) {
					$jsonResponse = $this->_getShapesForTool($request, $response, $args);
					if (IS_MEMCACHE and empty($name)) {
						$this->memcache("set", $thisCacheKey, $jsonResponse);
					}
				} else {
					$jsonResponse = $memcacheData;
					if (MEM_MODE) {
						$jsonResponse['mode'] = 'memcache';
					}
				}
				return response($response, [
					'data' => $jsonResponse,
					'status' => $serverStatusCode
				]);
			}
			// Get Store Specific Details from helper
			$getStoreDetails = get_store_details($request);
			$storeId = $getStoreDetails['store_id'];
			// All Filter params
			$page = $request->getQueryParam('page');
			$perpage = $request->getQueryParam('perpage');
			$categoryId = $request->getQueryParam('category');
			$searchCategories = !empty($categoryId) ? json_clean_decode($categoryId, true) : [];
			$sortBy = !empty($request->getQueryParam('sortby'))
				&& $request->getQueryParam('sortby') != ""
				? $request->getQueryParam('sortby') : 'xe_id';
			$order = !empty($request->getQueryParam('order'))
				&& $request->getQueryParam('order') != ""
				? $request->getQueryParam('order') : 'desc';
			$name = $request->getQueryParam('name');
			$printProfileKey = $request->getQueryParam('print_profile_id');

			$shapeInit = new Shape();
			$getShapes = $shapeInit->join('shape_category_rel as scr', 'scr.shape_id', '=', 'shapes.xe_id')
				->where([
					['xe_id', '>', 0],
					['store_id', '=', $storeId]
				])
				->select(['shapes.xe_id', 'shapes.name', 'shapes.file_name', 'shapes.cloud_storage']);

			$shapeInit = new Shape();
			$getShapes = $shapeInit->where([
				['xe_id', '>', 0],
				['store_id', '=', $storeId]
			])
				->select(['shapes.xe_id', 'shapes.name', 'shapes.file_name', 'shapes.cloud_storage']);

			if (!empty($printProfileKey) || $searchCategories) {
				$categoryMatch = $searchCategories;
				// Filter By Print Profile Id
				if (!empty($printProfileKey)) {
					$assetTypeArr = $this->assetsTypeId('shapes');
					$profileCatRelObj = new \App\Modules\PrintProfiles\Models\PrintProfileAssetsCategoryRel();
					$profileCatRelDetails = $profileCatRelObj->where([
						['asset_type_id', '=', $assetTypeArr['asset_type_id']],
						['print_profile_id', '=', $printProfileKey]
					]);
					// combine print profile category with category filter parameter
					if ($searchCategories) {
						$profileCatRelObj->whereIn('category_id', $searchCategories);
					}
					$categoryMatch = $profileCatRelDetails->select('category_id')->groupBy('category_id');
				}
				$getShapes->whereHas('shapeCategory', function ($q) use ($categoryMatch) {
					return $q->whereIn('category_id', $categoryMatch);
				});
			}

			// filter by name
			if (isset($name) && $name != "") {
				$getShapes->where(function ($query) use ($name) {
					$query->where('shapes.name', 'LIKE', '%' . $name . '%')
						->orWhereHas('sTags', function ($query) use ($name) {
							return $query->where('tags.name', 'LIKE', '%' . $name . '%');
						});
				});
			}
			// Total records including all filters
			$getTotalPerFilters = $getShapes->count();
			// Pagination Data
			if (isset($page) && $page != "") {
				$totalItem = empty($perpage) ? PAGINATION_MAX_ROW : $perpage;
				$offset = $totalItem * ($page - 1);
				$getShapes->skip($offset)->take($totalItem);
			}
			// Sorting All records by column name and sord order parameter
			if (isset($sortBy) && $sortBy != "" && isset($order) && $order != "") {
				$getShapes->orderBy($sortBy, $order);
			}
			// get shape list
			$shapeData = $getShapes->get()->toArray();
			// format the list
			foreach ($shapeData as $shapekey => $shapevalue) {
				if ($shapevalue['cloud_storage'] == 1) {
					$thisFileName = $shapevalue['file_name'];
					$shapeData[$shapekey]['file_name'] = $this->getS3URL($thisFileName, $storeId);
				}
			}
			$jsonResponse = [
				'status' => 1,
				'records' => count($shapeData),
				'total_records' => $getTotalPerFilters,
				'data' => $shapeData
			];
		} catch (\Exception $e) {
			$serverStatusCode = EXCEPTION_OCCURED;
			create_log('Shapes', 'error', [
				'message' => $e->getMessage(),
				'extra' => [
					'module' => 'Get Sahpes'
				]
			]);
		}
		return response($response, [
			'data' => $jsonResponse,
			'status' => $serverStatusCode
		]);
	}

	/**
	 * PUT: Update a Single Shape
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author satyabratap@riaxe.com
	 * @date   4th Nov 2019
	 * @return json
	 */
	public function updateShape($request, $response, $args)
	{
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = [
			'status' => 0,
			'message' => message('Shape', 'not_found'),
		];
		try {
			// all parameters
			$allPostPutVars = $updateData = $request->getParsedBody();

			// Get Store Specific Details from helper
			$getStoreDetails = get_store_details($request);
			$storeId = $getStoreDetails['store_id'];

			if (!empty($args['id'])) {
				$shapeId = $args['id'];
				$shapeInit = new Shape();
				$getOldShape = $shapeInit->where('xe_id', '=', $shapeId)->get()->first()->toArray();
				$oldCategoryArr = explode(",", $getOldShape['category_id']);
				$newCategory = str_replace(array('\'', '"', '[', ']', '<', '>'), ' ', $allPostPutVars['categories']);
				$newCategoryArr = explode(",", $newCategory);
				$result = array_diff($oldCategoryArr, $newCategoryArr);
				foreach ($result as $res) {
					$shapeCount = new ShapeCategoryRelation();
					$countData = $shapeCount->where('category_id', '=', $res)->get()->toArray();
					$newCategory = new Category();
					if (count($countData) == 1) {
						$flagList = ['asset_available_flag' => 0];
						$newCategory->where('xe_id', '=', $res)->update($flagList);
					} else {
						$flagList = ['asset_available_flag' => 1];
						$newCategory->where('xe_id', '=', $res)->update($flagList);
					}
				}
				if (!empty($getOldShape)) {

					unset(
						$updateData['id'],
						$updateData['tags'],
						$updateData['categories'],
						$updateData['upload'],
						$updateData['shapeId']
					);

					if ($getOldShape['cloud_storage'] == 1) {
						//delete old file in S3
						$this->deleteS3File($getOldShape['file_name'], $storeId);
					} else {
						// Delete old file if exist
						$this->deleteOldFile(
							"shapes",
							"file_name",
							['xe_id' => $shapeId],
							path('abs', 'shape')
						);
					}
					$getUploadedFileName = do_upload('upload', path('abs', 'shape'), [150], 'string');
					if (!empty($getUploadedFileName)) {
						if ($getOldShape['cloud_storage'] == 1) {
							$fileToUpload =  path('abs', 'shape') . $getUploadedFileName;
							$this->uploadFileToS3("shape", $fileToUpload, $storeId);
							$getOldShape['cloud_storage'] = 1;
						}
						$updateData['file_name'] = $getUploadedFileName;
					}
					$updateData['store_id'] = $storeId;

					// Update record
					$shapeInit->where('xe_id', '=', $shapeId)->update($updateData);

					/**
					 * Save category and subcategory data
					 * Category id format: [4,78,3]
					 */
					if (
						isset($allPostPutVars['categories'])
						&& !empty($allPostPutVars['categories'])
					) {
						$categoryIds = $allPostPutVars['categories'];
						$this->saveShapeCategories($shapeId, $categoryIds);
					}
					/**
					 * Save tags
					 * Tag Names format : tag1,tag2,tag3
					 */
					$tags = !empty($allPostPutVars['tags']) ? $allPostPutVars['tags'] : "";
					$this->saveShapeTags($storeId, $shapeId, $tags);
					$this->memcache('deleteMulti', '', '', "shapes_cat");
					if (!empty($categoryIds)) {
						$catgories = str_replace(array('\'', '"', '[', ']', '<', '>'), ' ', $categoryIds);
						$catIdArr = array_map('trim', array_filter(explode(",", $catgories)));
						foreach ($catIdArr as $categoryId) {
							$ppAssetCatRelGtInit = new PrintProfileModels\PrintProfileAssetsCategoryRel();
							$printProfileIds = $ppAssetCatRelGtInit->where('category_id', $categoryId)->pluck('print_profile_id');
							$this->createUpdateAssetJsonCache($getStoreDetails['store_id'], $printProfileIds, 'shapes', $request, $response);
						}
					}

					$jsonResponse = [
						'status' => 1,
						'message' => message('Shape', 'updated')
					];
				}
			}
		} catch (\Exception $e) {
			// Store exception in logs
			create_log('shapes', 'error', [
				'message' => $e->getMessage(),
				'extra' => [
					'module' => 'Shapes'
				]
			]);
		}
		//Flush shape memcached
		$this->memcache('deleteMulti', '', '', 'shape');
		return response($response, [
			'data' => $jsonResponse,
			'status' => $serverStatusCode
		]);
	}

	/**
	 * DELETE: Delete single/multiple Shape
	 *
	 * @param $request  Slim's Argument parameters
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author satyabratap@riaxe.com
	 * @date   4th Nov 2019
	 * @return json
	 */
	public function deleteShape($request, $response, $args)
	{
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = [
			'status' => 0,
			'message' => message('Shape', 'not_found')
		];
		try {
			// get the store details
			$getStoreDetails = get_store_details($request);
			// deleted shape ids
			$getDeleteIds = !empty($args['id']) ? json_clean_decode($args['id'], true) : [];

			if ($getDeleteIds) {
				$totalCount = count($getDeleteIds);
				$shapeInit = new Shape();
				$shapesCount = $shapeInit->whereIn('xe_id', $getDeleteIds);

				if ($shapesCount->count() > 0) {
					$shapeDetails = $shapesCount->get()->toArray();
					$success = 0;
					foreach ($shapeDetails as $shapeValue) {
						$categoryIdArr = explode(",", $shapeValue['category_id']);
						foreach ($categoryIdArr as $shapeCatId) {
							$shapeCount = new ShapeCategoryRelation();
							$countData = $shapeCount->where('category_id', '=', $shapeCatId)
								->get()->toArray();
							$newCategory = new Category();
							if (count($countData) == 1) {
								$flagList = ['asset_available_flag' => 0];
								$newCategory->where('xe_id', '=', $shapeCatId)->update($flagList);
							} else {
								$flagList = ['asset_available_flag' => 1];
								$newCategory->where('xe_id', '=', $shapeCatId)->update($flagList);
							}
						}
						if ($shapeValue['cloud_storage'] == 1) {
							$fileName = $shapeValue['file_name'];
							$this->deleteS3File($fileName, $getStoreDetails['store_id']);
						} else {
							$this->deleteOldFile(
								"shapes",
								"file_name",
								['xe_id' => $shapeValue['xe_id']],
								path('abs', 'shape'),
								false
							);
						}
						$shapeCount->where('shape_id', $shapeValue['xe_id'])->delete();
						$shapeInit->where('xe_id', $shapeValue['xe_id'])->delete();
						$success++;
					}
					$this->memcache('deleteMulti', '', '', "shapes_cat");
					if (!empty($categoryIdArr)) {
						foreach ($categoryIdArr as $categoryId) {
							$ppAssetCatRelGtInit = new PrintProfileModels\PrintProfileAssetsCategoryRel();
							$printProfileIds = $ppAssetCatRelGtInit->where('category_id', $categoryId)->pluck('print_profile_id');
							$this->createUpdateAssetJsonCache($getStoreDetails['store_id'], $printProfileIds, 'shapes', $request, $response);
						}
					}
					if ($success > 0) {
						$jsonResponse = [
							'status' => 1,
							'message' => $success . ' out of '
								. $totalCount . ' Shape(s) deleted successfully'
						];
					}
				}
			}
		} catch (\Exception $e) {
			$serverStatusCode = EXCEPTION_OCCURED;
			create_log('Assets', 'error', [
				'message' => $e->getMessage(),
				'extra' => [
					'module' => 'Shapes'
				]
			]);
		}
		//Flush Shape memcahed.
		$this->memcache('deleteMulti', '', '', 'shape');
		return response($response, [
			'data' => $jsonResponse,
			'status' => $serverStatusCode
		]);
	}

	/**
	 * Delete a category from the table
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author satyabratap@riaxe.com
	 * @date   20 Jan 2020
	 * @return Delete Json Status
	 */
	public function deleteCategory($request, $response, $args)
	{
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = [
			'status' => 0,
			'message' => message('Category', 'error')
		];
		try {
			$getStoreDetails = get_store_details($request);
			$storeId = $getStoreDetails['store_id'];
			if (!empty($args['id'])) {
				$categoryId = $args['id'];
				$jsonResponse = $this->deleteCat(
					$storeId,
					'shapes',
					$categoryId,
					'Shapes',
					'ShapeCategoryRelation'
				);
			}
			$this->memcache('deleteMulti', '', '', "shapes_cat");
			if (!empty($args['id'])) {
				$ppAssetCatRelGtInit = new PrintProfileModels\PrintProfileAssetsCategoryRel();
				$printProfileIds = $ppAssetCatRelGtInit->where('category_id', $args['id'])->pluck('print_profile_id');
				$this->createUpdateAssetJsonCache($getStoreDetails['store_id'], $printProfileIds, "shapes", $request, $response);
			}
		} catch (\Exception $e) {
			// Store exception in logs
			create_log('Shape Category', 'error', [
				'message' => $e->getMessage(),
				'extra' => [
					'module' => 'Shapes'
				]
			]);
		}

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

	/**
	 * Get all Categories in Recursion format from the Database
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author radhanatham@riaxe.com
	 * @date   10 Sept 2020
	 * @return json
	 */
	private function getCategoryByPrintProfileId($request, $response, $args)
	{
		//All Filter columns from url
		$categoryId = $request->getQueryParam('category');
		$page = $request->getQueryParam('cat_page');
		$perpage = $request->getQueryParam('cat_perpage');
		$printProfileId = $request->getQueryParam('print_profile_id');
		// $primaryCategory = (!empty($request->getQueryParam('primary_cat'))
		// && $request->getQueryParam('primary_cat') != null
		// ) ? $request->getQueryParam('primary_cat') : 0;
		$getStoreDetails = get_store_details($request);
		$storeId = $getStoreDetails['store_id'];
		$shapesCategories = $getShapesCategories = [];
		$moduleSlugName = 'shapes';
		// Getting Assets module id
		$assetTypeArr = $this->assetsTypeId($moduleSlugName);
		if (!empty($assetTypeArr) && $assetTypeArr['status'] == 1) {
			$assetTypeId = $assetTypeArr['asset_type_id'];
			// Filter shapes with primary category paramenter.
			### Filter param "primary_cat" always received blank from the front-end - can be removed if unused
			// if (!empty($primaryCategory) && $primaryCategory && $page == 1) {
			// 	$profileCat = DB::table('print_profile_assets_category_rel as ppac')
			// 	->leftjoin('shape_category_rel as scr', 'ppac.category_id', '=', 'scr.category_id')
			// 	->join('categories as cat', 'ppac.category_id', '=', 'cat.xe_id')
			// 	->where('ppac.asset_type_id', $assetTypeId);
			// 	// ->where('ppac.print_profile_id', $printProfileId)	
			// 	// ->where('ppac.category_id', $primaryCategory);

			// 	$profileCatRel = $profileCat->select([
			// 		'ppac.print_profile_id as pid', 'cat.xe_id as id', 'cat.parent_id', 'cat.name', 
			// 		'cat.sort_order', 'cat.is_disable', 'cat.is_default', 'ppac.asset_type_id as aid'
			// 	])->distinct('cat.xe_id');

			// 	$getTotalPerFilters = $profileCatRel->get()->count();
			// 	if ($getTotalPerFilters > 0) {
			// 		$clipartsPrimaryCategory = $profileCatRel->get()->first();
			// 		$primaryCategoryArr = [
			// 			'id' => $clipartsPrimaryCategory->id,
			// 			'name' => $clipartsPrimaryCategory->name,
			// 			'order' => $clipartsPrimaryCategory->sort_order,
			// 			'is_disable' => $clipartsPrimaryCategory->is_disable,
			// 			'is_default' => $clipartsPrimaryCategory->is_default
			// 		];
			// 	}
			// }

			// Filter shapes with Printprofile. 
			$profileCat = DB::table('print_profile_assets_category_rel as ppac')->where('ppac.asset_type_id', $assetTypeId);
			// filter by categories
			$searchCategories = !empty($categoryId) ? json_clean_decode($categoryId, true) : [];
			if ($searchCategories) {
				$profileCat->whereIn('ppac.category_id', $searchCategories);
			}
			if (!empty($printProfileId)) {
				$profileCat->where('ppac.print_profile_id', $printProfileId);
			}
			$profileCatIds = $profileCat->select('category_id')->groupBy('category_id');

			$shapesQuery = DB::table('categories as cat')->select([
				'cat.xe_id as id',
				'cat.name',
				'cat.sort_order',
				'cat.is_disable',
				'cat.is_default',
				'file_name',
				'cloud_storage'
			])
				->whereIn('cat.xe_id', $profileCatIds);

			$getTotalPerFilters = $shapesQuery->count();
			// add pagination
			if (!empty($page)) {
				$totalItem = empty($perpage) ? PAGINATION_MAX_ROW : $perpage;
				$offset = $totalItem * ($page - 1);
				$shapesQuery->orderBy('sort_order', 'asc')->skip($offset)->take($totalItem);
			}

			if ($getTotalPerFilters > 0) {
				$getShapesCategories = $shapesQuery->get()->map(function ($item) use ($storeId) {
					if (!empty($item->file_name)) {
						if ($item->cloud_storage == 1) {
							$file = path('abs', 'category') . 'thumb_' . $item->file_name;
							$item->file_name = $this->getS3URL($file, $storeId);
						} else {
							$item->file_name = path('read', 'category') . 'thumb_' . $item->file_name;
						}
					}
					return $item;
				})->toArray();
				$shapesCategories = [
					'records' => count($getShapesCategories),
					'total_records' => $getTotalPerFilters,
					'data' => $getShapesCategories
				];
			}
		}
		return $shapesCategories;
	}
}
