<?php

/**
 * Manage Templates and Designs
 *
 * PHP version 5.6
 *
 * @category  Template
 * @package   Template_Design
 * @author    Tapas Ranjan Panda <tapasranjanp@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\Templates\Controllers;

use App\Components\Controllers\Component as ParentController;
use App\Components\Models\DesignStates;
use App\Modules\Templates\Models\Template;
use App\Modules\Templates\Models\TemplateCategory as Category;
use App\Modules\PrintProfiles\Models\PrintProfile;
use App\Modules\Templates\Models as TemplateModel;
use App\Modules\Templates\Models\TemplateCategoryRel;
use App\Modules\Settings\Models\Setting;
use Illuminate\Database\Capsule\Manager as DB;
use App\Components\Models\Tag;
use App\Components\Models\CategoryTagRel;
use App\Components\Models\CategoryDetails;
use App\Modules\Customers\Controllers\CustomerGroupController as CustomerGroup;
use App\Components\Models\Category as CommonCategory;
use App\Modules\PrintProfiles\Models as PrintProfileModels;
use App\Modules\PrintProfiles\Models\PrintProfileAssetsCategoryRel;
use ProductStoreSpace\Controllers\StoreProductsController;


/**
 * Template Controller
 *
 * @category Class
 * @package  Template_Design
 * @author   Tapas Ranjan Panda <tapasranjanp@riaxe.com>
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @link     http://inkxe-v10.inkxe.io/xetool/admin
 */
class TemplateController extends ParentController
{
    /**
     * Post: Save Design State along with Templates
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     *
     * @author Tapas Ranjan Panda
     * @date   5 Oct 2019
     * @return Save status in json format
     */
    public function saveDesigns($request, $response)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Design Data', 'error')
        ];
        try {
            // get the store id
            $getStoreDetails = get_store_details($request);
            $storeId = $getStoreDetails['store_id'];

            //checking for s3
            $isS3Enabled = $this->checkS3Settings($storeId);

            $allPostPutVars = $request->getParsedBody();

            $designData = !empty($allPostPutVars['design_data']) ? $allPostPutVars['design_data'] : '';

            // Save design data and svg json format
            $protocol = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] != 'off') ? 'https' : 'http';
            $blobURL = "blob:" . $protocol . "://";
            if (strpos($designData, $blobURL) !== false) {
                throw new \Exception('Unable to save template, blob data missing in design');
            }

            $productArray = json_clean_decode($allPostPutVars['product_info'], true); // product id array

            $designState = [
                'store_id' => $storeId,
                'cloud_storage' => ($isS3Enabled ? 1 : 0),
                'product_variant_id' => !empty($allPostPutVars['product_variant_id']) ? $allPostPutVars['product_variant_id'] : 0,
                'product_id' => !empty($productArray['product_id']) ? $productArray['product_id'] : null,
                'type' => !empty($allPostPutVars['template_type']) ? $allPostPutVars['template_type'] : "template",
                'custom_price' => !empty($allPostPutVars['custome_price']) ? to_decimal($allPostPutVars['custome_price']) : 0.00,
                'selected_category_id' => !empty($allPostPutVars['selected_category_id']) ? $allPostPutVars['selected_category_id'] : ""
            ];

            $reffId = $this->saveDesignData($designState, "", ['directory' => 'templates']);

            if ($reffId > 0) {
                // Save Template Data with its dedicated function
                $templateSaveResponse = $this->_saveTemplates(
                    $request,
                    $response,
                    $reffId,
                    'save'
                );

                // save the images to the server / cloud
                $this->saveDesignImages($request, $response, [
                    'ref_id' => $reffId,
                    'svg_data' => $designData
                ]);

                // save the related tables
                if (!empty($templateSaveResponse) && $templateSaveResponse > 0) {
                    // Save Print Profile Relations
                    $this->_savePrintProfileRelations(
                        $request,
                        $response,
                        $reffId,
                        $templateSaveResponse,
                        'save'
                    );
                    // Save Template Tag Relations
                    $templateTagRels = [
                        'reff_id' => $reffId,
                        'template_id' => $templateSaveResponse,
                        'store_id' => $storeId
                    ];
                    $this->_saveTemplateTags(
                        $storeId,
                        $templateSaveResponse,
                        $allPostPutVars['tags']
                    );
                    // Save Template Categories
                    $this->_SaveTemplateCategories(
                        $request,
                        $response,
                        $templateTagRels,
                        'save'
                    );
                }

                // get the captured images
                $getAssocCaptures = $this->getCaptureImages($reffId, $storeId);

                // if(gettype($allPostPutVars['design_urls']) == 'string' ){
                // $colorImageData = json_clean_decode($allPostPutVars['design_urls'],true);
                //$getAssocCaptures['color_product_image_url'] = $colorImageData;
                // }
                //update template asset cache for designer studio 
               
                $type = $allPostPutVars['is_easy_edit'] ? $allPostPutVars['is_easy_edit'] : 0;
                
                $is_cms = $allPostPutVars['is_cms'] ? $allPostPutVars['is_cms'] : 0;

                //Flush Memcached
                $this->memcache('deleteMulti', '', '', 'template');
                $this->memcache('deleteMulti', '', '', "templates_cat");

                $this->updateAssetCache($storeId, $templateSaveResponse, $allPostPutVars, 'template_is_ed_' . $type."_is_cms_". $is_cms);
                
                $categoryIds = $allPostPutVars['categories'];
                
                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, 'templates', $request, $response);
                    }
                }
                $jsonResponse = [
                    'status' => 1,
                    'ref_id' => $reffId,
                    'template_id' => $templateSaveResponse,
                    'capture_images' => $getAssocCaptures,
                    'product_id' => $designState['product_id'],
                    'message' => message('Design Template', 'saved')
                ];
            }
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'save template'
                ]
            ]);
        }
       
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }
    /**
     * Post: Save Design Images
     * It consists of images with and with-out product images
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Response object
     *
     * @author tanmayap@riaxe.com
     * @date   19 Feb 2020
     * @return boolean
     */
    protected function saveDesignImages($request, $response, $args)
    {
        $reffId = $args['ref_id'];
        $svgData = $args['svg_data'];
        $allPostPutVars = $request->getParsedBody();
        $getStoreDetails = get_store_details($request);
        $sideDetails = json_decode($allPostPutVars['sides'],true);
        $primeLocationW = path('abs', 'design_preview') . 'templates';
        $primeLocationR = path('read', 'design_preview') . 'templates';
        $primeJsonLocW = path('abs', 'design_state') . 'templates';
        $storeId = $allPostPutVars['store_id'];
        // Create direcotry if not exist
        if (!file_exists($primeJsonLocW)) {
            create_directory($primeJsonLocW);
        }
        $listOfFiles = [];

        $excludedFileNames = do_upload('design_without_product', $primeLocationW, [200], 'array');

        $colorImageData = [];

        $colorImageData = json_clean_decode($allPostPutVars['design_urls_color'], true);

        $includedFileNames = do_upload('design_urls', $primeLocationW, [200], 'array');


        // check S3 settings
        $templateDesignStInit = new DesignStates();
        $designStateData = $templateDesignStInit->select('cloud_storage')->where('xe_id', $reffId)->get()->first();
        $isS3Enabled = $designStateData->cloud_storage;

        if ($isS3Enabled) {
            foreach ($excludedFileNames as $excludedFileName) {
                $thumbFile = $primeLocationW  . "/" . "thumb_" . $excludedFileName;
                $fileName = $primeLocationW . "/" . $excludedFileName;
                $this->uploadFileToS3("design_preview", $thumbFile, $getStoreDetails['store_id']);
                $this->uploadFileToS3("design_preview", $fileName, $getStoreDetails['store_id']);
            }
            foreach ($includedFileNames as $includedFileName) {
                $thumbFile2 = $primeLocationW . "/" . "thumb_" . $includedFileName;
                $fileName2 = $primeLocationW . "/" . $includedFileName;
                $this->uploadFileToS3("design_preview", $thumbFile2, $getStoreDetails['store_id']);
                $this->uploadFileToS3("design_preview", $fileName2, $getStoreDetails['store_id']);
            }
        }

        if (!empty($svgData)) {
            $listOfFiles['design_data'] = $svgData;
        }
        if (!empty($excludedFileNames)) {
            foreach ($excludedFileNames as $exfileName) {
                $listOfFiles['without_product_file'][] = [
                    'filename' => $exfileName,
                ];
            }
        }

        $designUrl = [];
        $designIndex = $retainIndex = 0;

        foreach ($sideDetails as $sideData) {
            if ($sideData['is_designed'] == 1 && $sideData['is_design_retain'] == 0) {
                if ($isS3Enabled) {
                    $srcUrl = "";
                    $srcFile = $primeLocationW . '/' . $includedFileNames[$designIndex];
                    $srcUrl = $this->getS3URL($srcFile, $storeId);
                    if (empty($srcUrl)) {
                        $designUrl[] = $primeLocationR . '/' . $includedFileNames[$designIndex];
                        $listOfFiles['with_product_file'][] = ['filename' => $includedFileNames[$designIndex]];
                    } else {
                        $designUrl[] = $srcUrl;
                        $listOfFiles['with_product_file'][] = ['filename' => $includedFileNames[$designIndex]];
                    }
                } else {
                    $designUrl[] = $primeLocationR . '/' . $includedFileNames[$designIndex];
                    $listOfFiles['with_product_file'][] = ['filename' => $includedFileNames[$designIndex]];
                }
                $designIndex++;
            } elseif ($sideData['is_designed'] == 1 && $sideData['is_design_retain'] == 1) {
                $designUrl[] = $primeLocationR . '/' . $allPostPutVars['design_urls'][$retainIndex];
                $listOfFiles['with_product_file'][] = ['filename' => $allPostPutVars['design_urls'][$retainIndex]];
                $retainIndex++;
            } else {
                $designUrl[] = $sideData['url'];
            }
        }

        $designProductData = [
            [
                'variant_id' => [$allPostPutVars['product_variant_id']],
                'design_urls' => $designUrl
            ]
        ];

        $designData = [
            'notes' => "",
            'product_info' => json_clean_decode($allPostPutVars['product_info']),
            'design_product_data' => $designProductData,
            'sides' => json_decode($allPostPutVars['sides'],true),
            'env_info' => json_clean_decode($allPostPutVars['env_info']),
            'face_data' => isset($allPostPutVars['face_data']) ? json_clean_decode($allPostPutVars['face_data']) : "",
            'layer_data' => isset($allPostPutVars['layer_data']) ?  json_clean_decode($allPostPutVars['layer_data']) : "",
            'other_file_details' => $listOfFiles,
            'color_product_image_url' => $colorImageData,
            'attribute' => isset($allPostPutVars['attribute']) ? json_clean_decode($allPostPutVars['attribute'], true) : []
        ];

        // convert the design data to json format
        $designData = json_clean_encode($designData);

        // Save the design data into a json file
        $writeStatus =  write_file($primeJsonLocW . '/' . $reffId . '.json', $designData);
        $this->generateDesignFiles($designData, $reffId);

        // upload the json file to s3
        if ($isS3Enabled) {
            $s3Json = $primeJsonLocW . '/' . $reffId . '.json';
            $this->uploadFileToS3("design_state", $s3Json, $getStoreDetails['store_id']);
            write_file($primeJsonLocW . '/' . $reffId . '.json', $designData);
        }

        return $writeStatus;
    }
    /**
     * Put: Update Design State along with Templates
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author tanmayap@riaxe.com
     * @date   5 Oct 2019
     * @return Save status in json format
     */
    public function updateDesigns($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Design Template', 'error')
        ];
        try {
            $designId = !empty($args['id']) ? to_int($args['id']) : 0;
            $allPutVars = $request->getParsedBody();
            $getStoreDetails = get_store_details($request);

            if ($designId) {
                $temlate = new Template();
                $getDesignState = $temlate->where('ref_id', '=', $designId)->get()->toArray();
                $tempId = $getDesignState[0]['xe_id'];
                $getOldTemplate = $temlate->where('xe_id', '=', $tempId)->with(['templateCategory'])->get()->toArray();
                $oldTemplateData = $getOldTemplate[0]['template_category'];
                $oldTemplateData = array_column($oldTemplateData, 'category_id');
                $newCategory = str_replace(array('\'', '"', '[', ']', '<', '>'), ' ', $allPutVars['categories']);
                $newCategoryArr = explode(",", $newCategory);
                $result = array_diff($oldTemplateData, $newCategoryArr);
                foreach ($result as $res) {
                    $tempCount = new TemplateModel\TemplateCategoryRel();
                    $countData = $tempCount->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);
                    }
                }
                $designState = [
                    'product_setting_id' => $allPutVars['product_settings_id'],
                    'product_variant_id' => $allPutVars['product_variant_id'],
                    'type' => $allPutVars['template_type'],
                    'selected_category_id' => $allPutVars['selected_category_id'],
                ];

                $designInit = (new DesignStates())->where('xe_id', $designId);
                $templateDesignCount = $designInit->count();

                /*Only for imported Template*/
                $importedTemplateCount = 0;
                if ($templateDesignCount == 0) {
                    $templateInit = new TemplateModel\Template();
                    $getTemplates = $templateInit->where('ref_id', $designId);
                    $importedTemplateCount = $getTemplates->count();
                }
                /*End*/

                if ($templateDesignCount > 0 || $importedTemplateCount) {
                    if ($templateDesignCount > 0) {
                        $designInit->update($designState);
                    }
                    // Save Template Data with its dedicated function
                    $templateSaveResponse = $this->_saveTemplates(
                        $request,
                        $response,
                        $designId,
                        'update'
                    );
                    if ($templateSaveResponse) {
                        // Save Print Profile Relations
                        $this->_savePrintProfileRelations(
                            $request,
                            $response,
                            $designId,
                            $templateSaveResponse,
                            'update'
                        );
                        // Save Template Tag Relations
                        $templateTagRels = [
                            'reff_id' => $designId,
                            'template_id' => $templateSaveResponse,
                            'store_id' => $getStoreDetails['store_id']
                        ];
                        $this->_saveTemplateTags(
                            $getStoreDetails['store_id'],
                            $templateSaveResponse,
                            $allPutVars['tags']
                        );
                        // Save Template Categories
                        $this->_SaveTemplateCategories(
                            $request,
                            $response,
                            $templateTagRels,
                            'update'
                        );

                        $type = $allPutVars['is_easy_edit'] ? $allPutVars['is_easy_edit'] : 0;
                        $is_cms = $allPutVars['is_cms'] ? $allPutVars['is_cms'] : 0;

                        //Flush Memcached
                        $this->memcache('deleteMulti', '', '', 'template');
                        $this->memcache('deleteMulti', '', '', "templates_cat");

                        //update template asset cache for designer studio 
                        $this->updateAssetCache($getStoreDetails['store_id'], $templateSaveResponse, $allPutVars, 'template_is_ed_' . $type."_is_cms_". $is_cms);
                        $categoryIds = $allPutVars['categories'];

                        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, 'templates', $request, $response);
                            }
                        }
                    }

                    $jsonResponse = [
                        'status' => 1,
                        'message' => message('Design Template', 'updated')
                    ];
                }
            }
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Update Design State'
                ],
            ]);
        }
        
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }

    /**
     * GET: Get single template
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author dan@imprintnext.com
     * @date   12 July 2022
     * @return Json Response
     *
     */
    public function getSingleTemplate($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 1,
            'total_records' => 0,
            'records' => 0,
            'data' => [],
            'message' => message('Template', 'not_found')
        ];
        try {
            // get the store id
            $storeId =  $request->getQueryParam('store_id');
            if (empty($storeId)) {
                $getStoreDetails = get_store_details($request);
                $storeId['store_id'] = $getStoreDetails['store_id'];
            }

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

            if (!empty($templateID)) {
                //get this template data
                $templateInit = new Template();
                $thisTemplate = $templateInit->where('xe_id', $templateID)->first()->toArray();
                $designId = $thisTemplate['ref_id'];
                $isImportedFromIN = $thisTemplate['is_imported'];
                $templateData = [];
                //if imported fetch data from local DB else get from Central Imprintnext
                if ($isImportedFromIN == 0) {
                    $templateDesignStInit = new DesignStates();
                    $designStateData = $templateDesignStInit->where('xe_id', $designId)->first();
                    if ($designStateData->type == "template") {
                        $result = $this->getTemplateDetail($thisTemplate, $storeId);
                        $urlPath = $result['urlPath'];
                        $templateData = $result['template'];
                    } else {
                        // other type of template
                        $type = '';
                        switch ($designStateData->type) {
                            case 'cart':
                                $type = 'carts';
                                break;
                            case 'predecorator':
                                $type = 'predecorators';
                                break;
                            case 'quote':
                                $type = 'quotes';
                                break;
                            case 'share':
                                $type = 'shares';
                                break;
                            case 'user_design':
                                $type = 'user_designs';
                                break;
                            case 'artwork':
                                $type = 'artworks';
                                break;
                            default:
                                break;
                        }
                        // Get Associated product Details
                        $assocProductId = $this->getAssocProductId($designId, true); // true = store product
                        if ($assocProductId) {
                            $designData = [
                                'product_id' => $assocProductId['conditional_products_id'],
                                'product_name' => $assocProductId['product_name'],
                                'variant_id' => $assocProductId['product_variant_id'],
                                'product_name' => $assocProductId['product_name'],
                                'design_data' => $this->getSVGFile($designId, $type)
                            ];
                            // get the svg file
                            $svgJsonPath = path('abs', 'design_state') . $type . '/' . $designId . '.json';
                            if (file_exists($svgJsonPath)) {
                                $urlPath = path('read', 'design_state') . $type . '/' . $designId . '.json';
                                // read the svg data
                                $svgData = read_file($svgJsonPath);
                                $svgDecodedData = json_clean_decode($svgData, true);
                                $designData['layer_data'] = $svgDecodedData['layer_data'];
                            }
                            $templateData = [$designData];
                        }
                    }
                } else {
                    $result = $this->getTemplateDetail($thisTemplate, $storeId);
                    $urlPath = $result['urlPath'];
                    $templateData = $result['template'];
                }
                if ($templateData) {
                    $jsonResponse = [
                        'status' => 1,
                        'records' => 1,
                        'total_records' => 1,
                        'data' => $templateData,
                        'design_url' => $urlPath
                    ];
                }
            }

            return response($response, [
                'data' => $jsonResponse,
                'status' => $serverStatusCode
            ]);
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'save template'
                ]
            ]);
        }
    }

    /**
     * Internal get template detail local/imported
     */
    private function getTemplateDetail($thisTemplate, $storeId)
    {
        $result = [
            'template' => [],
            'urlPath' => ''
        ];
        $urlPath = '';
        if (!empty($thisTemplate)) {
            // Create template_id from xe_id
            $templateId = $thisTemplate['xe_id'];
            $referenceId = $thisTemplate['ref_id'];
            $isImported = isset($thisTemplate['is_imported']) ? $thisTemplate['is_imported'] : 0;
            unset($thisTemplate['xe_id']);

            if (!$isImported) {
                // json path local
                $urlPath = path('read', 'design_state') . 'templates' . '/' . $referenceId . '.json';
                // design state data
                $getDesignState = (new TemplateModel\TemplateDesignStates())->where('xe_id', '=', $thisTemplate['ref_id'])->get()->first();
                $thisTemplate['get_design_state'] = $getDesignState;
                // Get Associated product Details
                $assocProductId = $this->getAssocProductId($referenceId, true); // true = store product
                $thisTemplate['product_id'] = $assocProductId['conditional_products_id'];
                $thisTemplate['product_name'] = $assocProductId['product_name'];
                $thisTemplate['variant_id'] = $assocProductId['product_variant_id'];
            } else {
                // json path remote
                $urlPath = CENTRAL_ASSETS_BASEURL . 'assets/design_states/' . 'templates' . '/' . $referenceId . '.json';
                $thisTemplate['get_design_state'] = '';
                $thisTemplate['product_id'] = '';
                $thisTemplate['product_name'] = '';
                $thisTemplate['variant_id'] = '';
            }

            // Get Associated Tags and Categories
            $getTagCategories = $this->getAssocCategoryTag($templateId);
            $thisTemplate['categories'] = $getTagCategories['categories'];
            $thisTemplate['tags'] = $getTagCategories['tags'];
            // Get Associated Print profiles
            $thisTemplate['print_profiles'] = $this->templateToPrintProfile($templateId);

            $getAssocCaptures = $this->getCaptureImages($referenceId, $storeId, false, $isImported); // 0 = not imported
            $thisTemplate['capture_images'] = $getAssocCaptures;

            // Get svg design data
            $svgCode = $this->getSVGFile($referenceId, 'templates', $isImported);
            $thisTemplate['design_data'] = $svgCode;
            $result = [
                'template' => [$thisTemplate],
                'urlPath' => $urlPath
            ];
        }
        return $result;
    }

    /**
     * GET: Get all templates
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author tanmayap@riaxe.com
     * @date   5 Oct 2019
     * @return Json Response
     */
    public function getTemplates($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 1,
            'total_records' => 0,
            'records' => 0,
            'data' => [],
            'message' => message('Template', 'not_found')
        ];
        try {
            // get the filters
            $storeId =  $request->getQueryParam('store_id');
            if (empty($storeId)) {
                $getStoreDetails = get_store_details($request);
                $storeId = $getStoreDetails['store_id'];
            }
            $isAdmin = $request->getQueryParam('is_admin');
            $name = $request->getQueryParam('name');
            $page = $request->getQueryParam('page');
            $order = $request->getQueryParam('order');
            $perpage = $request->getQueryParam('perpage');
            $printProfileId = $request->getQueryParam('print_profile');
            $catagoryId = $request->getQueryParam('catagory');
            
            if(empty($catagoryId)){
                $catagoryId = $request->getQueryParam('category');
            }

            $colorUsed = $request->getQueryParam('color_used'); // number of colors
            $tagId = $request->getQueryParam('tag');
            $sortBy = $request->getQueryParam('sortby');
            $is_easy_edit = $request->getQueryParam('is_easy_edit',0);
            $prod_cat_id = $request->getQueryParam('prod_cat_id','');

            $show_in_tool = intval($request->getQueryParam('show_in_tool', 1));
            //customer group
            $customerId = $request->getQueryParam('customer') ? (int) $request->getQueryParam('customer') : 0;

            // ************not received filters***********
            $printProfileKey = $request->getQueryParam('print_profile_id');
            $productCategoryID = $request->getQueryParam('prod_cat_id');
            
            $type = $request->getQueryParam('type', 0);
            
           
            // ************not received filters end*******
            //
            
            $is_cms = $request->getQueryParam('is_cms', 0);
            if(empty($catagoryId) and empty($name) and empty($prod_cat_id)){
                if (!$isAdmin || $is_cms ) {
                    $jsonResponse = $this->_getTemplatesForTool($request, $response, $args);
                    return response($response, [
                        'data' => $jsonResponse,
                        'status' => $serverStatusCode
                    ]);
                }
            }

            $templateInit = new TemplateModel\Template();
            $getTemplates = $templateInit->where('xe_id', '>', 0);
            $fields = [
                'xe_id as id',
                'xe_id',
                'name',
                'ref_id',
                'no_of_colors',
                'is_easy_edit',
                'is_blank_canvas',
                'is_imported',
                'is_blank_canvas'
            ];
            if (!$isAdmin) {
                $fields[]  = 'color_hash_codes';
            }
            // For multiple Shape data
            $getTemplates->select($fields);
            // This is derived from import template section.
            // Filter Search as per type
            if (isset($type) && (int)$type > 0 and $is_cms == 0 and $isAdmin == 0) {
               $getTemplates->where('is_easy_edit', '=', $type);
            }
            
            $getTemplates = $getTemplates->where('show_in_tool', '=', $show_in_tool);
            // Filter by customer group asset
            if (STORE_NAME != 'Opencart') {
                if ($customerId > 0) {
                    $customerGroupControllerInit = new CustomerGroup();
                    $customerGroupId = $customerGroupControllerInit->getGroupIdBycustomerId($customerId);
                    if ($customerGroupId != '') {
                        $assetTypeArr = $this->assetsTypeId('templates');
                        $assetTypeId = $assetTypeArr['asset_type_id'];
                        $catIds = $customerGroupControllerInit->getAssetsBygroupId($customerGroupId, $assetTypeId, $storeId);
                        if (!empty($catIds)) {
                            $getTemplates->whereHas('templateCategory', function ($q) use ($catIds) {
                                return $q->whereIn('category_id', $catIds);
                            });
                        }
                    }
                }
                
                // end filter customer group
                $totalCounts = $getTemplates->count();
                if ($totalCounts > 0) {

                    // match with store id
                    if (!empty($storeId)) {
                        $getTemplates->where('store_id', $storeId);
                    }

                    // Color used Filter
                    if (!empty($colorUsed)) {
                        $getTemplates->where('no_of_colors', $colorUsed);
                    }

                    // this block will get the templates assigned for selected product categories.
                    if (!empty($productCategoryID)) {
                        $productCatArr = explode(',', $productCategoryID);
                        // get the template product relation settings
                        $settingInit = new Setting();
                        $categoryRelations = $settingInit->where('setting_key', '=', 'template_products_rel')->get()->first();
                        $relationSetting = json_clean_decode($categoryRelations->setting_value);
                        if (!empty($relationSetting['categories'])) {
                            $relationRows = $relationSetting['categories'];
                            $templateCatArr = array();
                            foreach ($relationRows as $relation) {
                                if (count(array_intersect($productCatArr, $relation['prodCatId'])) > 0) {
                                    $templateCatArr = array_merge($templateCatArr, $relation['templateCats']);
                                }
                            }
                        }
                        $templateCatsToFilter = array_unique($templateCatArr);
                        $catagoryId = json_encode($templateCatsToFilter);
                    } else {
                        // Filter By Print Profile Id (multiple)
                        if (!empty($printProfileKey)) {
                            $assetTypeArr = $this->assetsTypeId('templates');
                            // get asset category from print profile relation
                            $profileCatRelObj = new \App\Modules\PrintProfiles\Models\PrintProfileAssetsCategoryRel();
                            $profileCatRelDetails = $profileCatRelObj->where([
                                ['asset_type_id', '=', $assetTypeArr['asset_type_id']],
                                ['print_profile_id', '=', $printProfileKey]
                            ]);
                            // related category array
                            $relCatIds = $profileCatRelDetails->get()->pluck('category_id')->toArray();
                            $catagoryId = json_encode($relCatIds);
                        }
                    }

                    // Filter by Category IDs
                    if (!empty($catagoryId)) {
                        $searchCategories = json_clean_decode($catagoryId, true);
                        if (!empty($searchCategories)) {
                            $getTemplates->whereHas('templateCategory', function ($q) use ($searchCategories) {
                                return $q->whereIn('category_id', $searchCategories);
                            });
                        }
                    }

                    // Filter by Tag IDs
                    if (!empty($tagId)) {
                        $searchTags = json_clean_decode($tagId, true);
                        if (!empty($searchTags)) {
                            $getTemplates->whereHas('templateTags', function ($q) use ($searchTags) {
                                return $q->whereIn('tag_id', $searchTags);
                            });
                        }
                    }

                    // Filter by Print Profile
                    if (!empty($printProfileId)) {
                        $searchPrintProfiles = json_clean_decode($printProfileId, true);
                        if (!empty($searchPrintProfiles)) {
                            $getTemplates->whereHas('templatePrintProfiles', function ($q) use ($searchPrintProfiles) {
                                return $q->whereIn('print_profile_id', $searchPrintProfiles);
                            });
                        }
                    }

                    // Multiple Table search for name attribute (multiple)
                    if (!empty($name)) {
                        $catTempIdArr = $tempIdArr = [];
                        $tagsInit = new Tag();
                        $tagData = $tagsInit->join(
                            'template_tag_rel',
                            'tags.xe_id',
                            '=',
                            'template_tag_rel.tag_id'
                        )
                            ->select('template_tag_rel.template_id')->where('tags.name',  'LIKE', '%' . $name . '%');
                        if ($tagData->count() > 0) {
                            $getTagData = $tagData->get()->toArray();
                            $tempIdArr = array_column($getTagData, 'template_id');
                        }
                        $categoryInit = new CommonCategory();
                        $catData = $categoryInit->join(
                            'template_category_rel',
                            'categories.xe_id',
                            '=',
                            'template_category_rel.category_id'
                        )
                            ->select('template_category_rel.template_id')->where('categories.name',  'LIKE', '%' . $name . '%');
                        if ($catData->count() > 0) {
                            $getCatData = $catData->get()->toArray();
                            $catTempIdArr = array_column($getCatData, 'template_id');
                        }
                        $getTemplates->where('name', 'LIKE', '%' . $name . '%')
                            ->orWhereIn('xe_id', $tempIdArr)
                            ->orWhereIn('xe_id', $catTempIdArr);
                    }

                    // Total records including all filters
                    $getTotalPerFilters = $getTemplates->count();

                    // Get pagination data
                    if (!empty($page)) {
                        $totalItem = empty($perpage) ? PAGINATION_MAX_ROW : $perpage;
                        $offset = $totalItem * ($page - 1);
                        $getTemplates->skip($offset)->take($totalItem);
                    }

                    // Sorting by column name and sort order parameter
                    if (!empty($sortBy) && !empty($order)) {
                        if (!empty($catTempIdArr)) {
                            $getTemplates->orderBy($sortBy, $order)
                                ->orWhereIn('xe_id', $catTempIdArr);
                        } else {
                            $getTemplates->orderBy($sortBy, $order);
                        }
                    }
                    if (!empty($tempIdArr)) {
                        if ($type == 0) {
                            $getTemplates->where('name', 'LIKE', '%' . $name . '%')
                                ->orWhereIn('xe_id', $tempIdArr);
                        } else {
                            $getTemplates->where('name', 'LIKE', '%' . $name . '%')
                                ->orWhereIn('xe_id', $tempIdArr)
                                ->orWhereIn('xe_id', $catTempIdArr);
                        }
                    }
                }

                // get the template data
                $templateData = $getTemplates->orderBy('xe_id', 'DESC')
                ->with('getDesignState')->get()->toArray();

                // format, pupulate other fields
                foreach ($templateData as $key => $template) {
                    // Create template_id from xe_id
                    $templateId = $templateData[$key]['id'] = $templateData[$key]['template_id'] = $template['xe_id'];
                    $referenceId = $templateData[$key]['xe_id'] = $template['ref_id'];
                    unset($templateData[$key]['xe_id']);

                    if (!empty($templateId)) {
                        // Get Associated Tags and Categories
                        $getTagCategories = $this->getAssocCategoryTag($templateId);
                        $templateData[$key]['categories'] = $getTagCategories['categories'];
                        $templateData[$key]['tags'] = $getTagCategories['tags'];

                        // Get Associated Print profiles
                        $templateData[$key]['print_profiles'] = $this->templateToPrintProfile($templateId);

                        if ($template['is_imported'] == 1) {

                            // Get template Images
                            // $endPoint = CENTRAL_ASSETS_BASEURL . "api/v1/import-template/design-data/" . $referenceId;
                            // $getAssocCaptures = api_call_by_curl(["id" => $referenceId], $endPoint, false, false);

                            $imagePath = CENTRAL_ASSETS_BASEURL . 'assets/design_previews/templates/';
                            $getAssocCaptures =  [
                                "without_product_file" => [
                                    ["src" => "{$imagePath}template_{$referenceId}_wp.jpeg", "thumb" =>  "{$imagePath}thumb_template_{$referenceId}_wp.jpeg"]
                                ],
                                "with_product_file" => [
                                    ["src" => "{$imagePath}template_{$referenceId}.png", "thumb" =>  "{$imagePath}thumb_template_{$referenceId}.png"]
                                ]
                            ];
                        } else {
                            // Get Associated product Details
                            $assocProductId = $this->getAssocProductId($referenceId, false);

                            $templateData[$key]['product_id'] = $assocProductId['conditional_products_id'];

                            // Get template Images
                            $getAssocCaptures = $this->getCaptureImages($referenceId, $storeId, false, false);
                        }
                        $templateData[$key]['capture_images'] = $getAssocCaptures;
                    }
                }

                if ($getTotalPerFilters > 0) {
                    $jsonResponse = [
                        'status' => 1,
                        'total_records' => $getTotalPerFilters,
                        'records' => count($templateData),
                        'data' => $templateData
                    ];
                }

                if (!empty($printProfileId) && $page <= 2) {
                    $assetData = $page == 1 ?
                        [
                            'total_records' => $getTotalPerFilters,
                            'data' => $templateData
                        ] : $templateData;
                    $this->createAssetCache('template_is_ed_' . $type."_is_cms_". $is_cms, $storeId, $printProfileId, $assetData, $page);
                }
            }

            //SET IN MEMCACHED
            if (IS_MEMCACHE and empty($name) and isset($thisCacheKey)) {
                $this->memcache("set", $thisCacheKey, $jsonResponse);
            }
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'save template'
                ]
            ]);
        }
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }



    /**
     * Get SVG Files json data associated to the Template's Ref ID (internal)
     *
     * @param $refId Custom Design Id
     * @param $type  Type of the design
     *
     * @author tanmayap@riaxe.com
     * @date   19 Feb 2020
     * @return Array
     */
    private function getSVGFile($refId, $type, $isImported = 0)
    {
        $designData = [];

        // read the svg file
        $svgJsonPath = path('abs', 'design_state') . $type . '/' . $refId . '.json';
        if (!$isImported && file_exists($svgJsonPath)) {
            $svgData = read_file($svgJsonPath);
        } else {
            $svgJsonPath = CENTRAL_ASSETS_BASEURL . 'assets/design_states/templates/' . $refId . '.json';
            $svgData = fileGetContentsCurl($svgJsonPath);
        }
        if (!empty($svgData)) {
            $currentStoreUrl = '';
            $databaseStoreInfo = DB::table('stores')->where('xe_id', '=', 1);
            if ($databaseStoreInfo->count() > 0) {
                $currentStoreUrl = $databaseStoreInfo->get()->first()->store_url;
            }
            $fileLocationDir = path('read', 'design_preview') . 'templates';
            $hostname = parse_url($fileLocationDir, PHP_URL_HOST);

            $svgDataArray = json_clean_decode($svgData, true);
            if (!empty($svgDataArray['sides'])) {
                foreach ($svgDataArray['sides'] as $svgKey => $svg) {
                    $svg['svg'] = str_replace($hostname, $currentStoreUrl, $svg['svg']);
                    $designData[$svgKey] = ['svg' => $svg['svg']];
                }
            } else {
                if (!empty($svgDataArray['design_data'])) {
                    $designData = json_clean_decode($svgDataArray['design_data']);
                }
            }
            return $designData;
        }
        return false;
    }

    /**
     * Get Associated Product Primary Key from the Template's RefId
     *
     * @param $refId        Design Ref Id
     * @param $storeProduct Flag
     *
     * @author tanmayap@riaxe.com
     * @date   14 aug 2019
     * @return integer
     */
    protected function getAssocProductId($refId, $storeProduct = false)
    {

        $productDetails = []; // default blank array

        $prodSettsProdId = 0;

        // get the product setting data
        $getDesignStateData = DesignStates::with('productSetting')->find($refId);

        // Get Product Id : Conditional Case applied for Inkxe 8
        if (!empty($getDesignStateData)) {
            $designState = $getDesignStateData->toArray();
            if (isset($designState['product_id'])  && $designState['product_id'] > 0) {
                $prodSettsProdId = $designState['product_id'];
            } else {
                if (isset($designState['product_setting']['product_id'])  && $designState['product_setting']['product_id'] > 0) {
                    $prodSettsProdId = to_int($designState['product_setting']['product_id']);
                }
            }
        }

        $productDetails['conditional_products_id'] = $prodSettsProdId;

        if ($storeProduct) {
            $endPoint = 'products/' . $prodSettsProdId;
            $singleProductApi = call_curl([], $endPoint, 'GET');
            if (!empty($singleProductApi) && $singleProductApi['status'] == 1) {
                $productDetails += [
                    'product_id' => $singleProductApi['data']['id'],
                    'product_name' => $singleProductApi['data']['name'],
                    'product_variant_id' => $singleProductApi['data']['variant_id']
                ];
            }
        }
        return $productDetails;
    }
    /**
     * Get Associated print Profile Lists from the Template ID
     *
     * @param $templateId Slim's Request object
     *
     * @author tanmayap@riaxe.com
     * @date   14 aug 2019
     * @return json response
     */
    protected function templateToPrintProfile($templateId)
    {

        $printProfileSelected = []; // default blank

        $tempProfileRelObj = new TemplateModel\TemplatePrintProfileRel();

        // get the print_profile_ids from the template-print-profile relation
        $getPrintProfiles = $tempProfileRelObj->where('template_id', $templateId)
            ->select('print_profile_id');

        // get the print-profile from the master matching with the print profile relation
        $getPrintProfileMaster = (new PrintProfile())->select(['xe_id', 'name'])
            ->whereIn('xe_id', $getPrintProfiles);

        // if found add is_seleted  = 1 with each record
        if ($getPrintProfileMaster->count() > 0) {
            $printProfiles = $getPrintProfileMaster->get();
            foreach ($printProfiles as $printProfile) {
                $printProfileSelected[] = [
                    'id' => $printProfile->xe_id,
                    'name' => $printProfile->name,
                    'is_selected' => 1
                ];
            }
        }

        return $printProfileSelected;
    }
    /**
     * Get Associated Categories and tags of Template by ID
     *
     * @param $templateId Slim's Request object
     *
     * @author tanmayap@riaxe.com
     * @date   14 aug 2019
     * @return Array
     */
    protected function getAssocCategoryTag($templateId)
    {
        // Get Category Ids
        $tempCatRelObj = new TemplateModel\TemplateCategoryRel();
        $tempTagRelObj = new TemplateModel\TemplateTagRel();

        // get the category list
        $categoryIdList = $tempCatRelObj->where('template_id', $templateId)
            ->with('category')->get()->pluck('category_id')->toArray();

        // get the tag list
        $tagNameList = $tempTagRelObj->where('template_id', $templateId)
            ->with('tag')->get()->pluck('tag.name')->toArray();

        return [
            'categories' => $categoryIdList,
            'tags' => $tagNameList
        ];
    }
    /**
     * Get Captured Images associated to the Template's Ref ID (internal)
     *
     * @param $refId Design ID
     * @param $isRaw Flag
     *
     * @author tanmayap@riaxe.com
     * @date   14 aug 2019
     * @return Array
     */
    private function getCaptureImages($reffId, $storeId, $isRaw = false, $is_Imported = 0)
    {
        $getCaptures = [];
        $withOutProductFile = [];
        $withProductFile = [];
        $finalSortedFileList = [];

        if ($is_Imported == 1) {
            $fileLocationDir = CENTRAL_ASSETS_BASEURL . 'assets/design_previews/' . 'templates';
            $absDirectoryName = CENTRAL_ASSETS_BASEURL . 'assets/design_states/' . 'templates';
        } else {
            $fileLocationDir = path('read', 'design_preview') . 'templates';
            $absDirectoryName = path('abs', 'design_state') . 'templates';
        }


        if (file_exists($absDirectoryName . '/' . $reffId . '.json') || $is_Imported == 1) {
            // read the design state
            $designState = $absDirectoryName . '/' . $reffId . '.json';
            $getImageFileHistory = ($is_Imported == 1 ? fileGetContentsCurl($designState) : read_file($designState));

            // Get Capture Records as json format
            $finalSortedFileList = json_clean_decode($getImageFileHistory, true);
            if (!empty($isRaw)) {
                return $finalSortedFileList;
            }

            //checking for S3
            $templateDesignStInit = new DesignStates();
            $designStateData = $templateDesignStInit->select('cloud_storage')->where('xe_id', $reffId)->get()->first();
            $isS3Enabled = $designStateData->cloud_storage;

            if (!empty($finalSortedFileList['other_file_details']['without_product_file'])) {
                foreach ($finalSortedFileList['other_file_details']['without_product_file'] as $woFile) {
                    if ($isS3Enabled) {
                        $srcFile = path('abs', 'design_preview') . 'templates' . '/' . $woFile['filename'];
                        $thumbFile = path('abs', 'design_preview') . 'templates' . '/' . 'thumb_' . $woFile['filename'];
                        $srcUrl = $this->getS3URL($srcFile, $storeId);
                        $thumbUrl = $this->getS3URL($thumbFile, $storeId);
                        $withOutProductFile[] = [
                            'src' => $srcUrl,
                            'thumb' => $thumbUrl
                        ];
                    } else {
                        $withOutProductFile[] = [
                            'src' => $fileLocationDir . '/' . $woFile['filename'],
                            'thumb' => $fileLocationDir . '/' . 'thumb_' . $woFile['filename']
                        ];
                    }
                }
                $getCaptures['without_product_file'] = $withOutProductFile;
            } else {
                if (!empty($finalSortedFileList['without_product_file'])) {
                    foreach ($finalSortedFileList['without_product_file'] as $woFile) {
                        $withOutProductFile[] = [
                            'src' => $fileLocationDir . '/' . $woFile['filename'],
                            'thumb' => $fileLocationDir . '/' . 'thumb_' . $woFile['filename']
                        ];
                    }
                    $getCaptures['without_product_file'] = $withOutProductFile;
                }
            }

            if (!empty($finalSortedFileList['other_file_details']['with_product_file'])) {
                foreach ($finalSortedFileList['other_file_details']['with_product_file'] as $woFile) {
                    if ($isS3Enabled) {
                        $srcFile = path('abs', 'design_preview') . 'templates' . '/' . $woFile['filename'];
                        $thumbFile = path('abs', 'design_preview') . 'templates' . '/' . 'thumb_' . $woFile['filename'];
                        $srcUrl = $this->getS3URL($srcFile, $storeId);
                        $thumbUrl = $this->getS3URL($thumbFile, $storeId);
                        $withProductFile[] = [
                            'src' => $srcUrl,
                            'thumb' => $thumbUrl
                        ];
                    } else {
                        $withProductFile[] = [
                            'src' => $fileLocationDir . '/' . $woFile['filename'],
                            'thumb' => $fileLocationDir . '/' . 'thumb_' . $woFile['filename']
                        ];
                    }
                }
                $getCaptures['with_product_file'] = $withProductFile;
            } else {
                if (!empty($finalSortedFileList['with_product_file'])) {
                    foreach ($finalSortedFileList['with_product_file'] as $woFile) {
                        $withOutProductFile[] = [
                            'src' => $fileLocationDir . '/' . $woFile['filename'],
                            'thumb' => $fileLocationDir . '/' . 'thumb_' . $woFile['filename']
                        ];
                    }
                    $getCaptures['with_product_file'] = $withOutProductFile;
                }
            }
        }

        return $getCaptures;
    }
    /**
     * Delete: Delete a clipart along with all the tags and categories
     * - Input must be in a valid JSON format like [1,2,3,...] where 1,2,3.. are
     *   clipart IDs
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author tanmayap@riaxe.com
     * @date   14 aug 2019
     * @return json response
     */
    public function deleteTemplate($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Template', 'error')
        ];
        try {
            // get the store id
            $getStoreDetails = get_store_details($request);
            $storeId = $getStoreDetails['store_id'];

            // get the array of template ids
            $getTemplateId = !empty($args) ? json_clean_decode($args['id'], true) : null;

            if ($getTemplateId) {
                // get the template matching with the id
                $templateInit = new TemplateModel\Template();
                $getTemplates = $templateInit->whereIn('xe_id', $getTemplateId);
                $templateCategoryIdArr = $getTemplates->with(['templateCategory'])->get()->toArray();
                $categoryIdList = [];
                foreach ($templateCategoryIdArr as $categoryList) {
                    foreach ($categoryList['template_category'] as $cateId) {
                        $categoryId = $cateId['category_id'];
                        $categoryIdList[] = $categoryId;
                        $templateCatInit = new TemplateModel\TemplateCategoryRel();
                        $countData = $templateCatInit->where('category_id', '=', $categoryId)->get()->toArray();
                        $newCategory = new Category();
                        if (count($countData) == 1) {
                            $flagList = ['asset_available_flag' => 0];
                            $newCategory->where('xe_id', '=', $categoryId)->update($flagList);
                        } else {
                            $flagList = ['asset_available_flag' => 1];
                            $newCategory->where('xe_id', '=', $categoryId)->update($flagList);
                        }
                    }
                }

                if ($getTemplates->count() > 0) {
                    // get the array of ref_id
                    $refIdList = $getTemplates->select('ref_id')->get()->pluck('ref_id')->toArray();
                    // get the array of xe_id (unmatched ids will be removed)
                    $templateIds = $getTemplates->select('xe_id')->get()->pluck('xe_id')->toArray();

                    // Delete Record
                    $templateInit = new TemplateModel\Template();
                    //for update asset cache ($typeId)
                    $typeId = $templateInit->whereIn('xe_id', $templateIds)->pluck('is_easy_edit')->toArray();
                    $isDeletedTemplate = $templateInit->whereIn('xe_id', $templateIds)->delete();
                    if ($isDeletedTemplate) {
                        // Delete Template design state Data
                        $templateDesignStInit = new DesignStates();
                        $templateDesignStInit->whereIn('xe_id', $refIdList)->delete();

                        // Delete Template_Tag_Rel Data
                        $templateTagInit = new TemplateModel\TemplateTagRel();
                        $templateTagInit->whereIn('template_id', $templateIds)->delete();

                        // Delete Template_PP_Rel Data
                        $templateProfileInit = new TemplateModel\TemplatePrintProfileRel();
                        $templateProfileInit->whereIn('template_id', $templateIds)->delete();

                        // Delete Template_Cat_Rel Data
                        $templateCatInit = new TemplateModel\TemplateCategoryRel();
                        $templateCatInit->whereIn('template_id', $templateIds)->delete();

                        // Delete Capture_Img Data
                        $templateImgInit = new TemplateModel\TemplateCaptureImages();
                        $templateImgInit->whereIn('ref_id', $refIdList)->delete();

                        //Flush Memcached
                        $this->memcache('deleteMulti', '', '', 'template');
                        $this->memcache('deleteMulti', '', '', "templates_cat");

                        // Delete Design Data Files
                        $this->deleteTemplateStuffs($refIdList, $storeId);
                        
                        //update template asset cache for designer studio 
                        $allPostPutVars = $request->getParsedBody();
                        $is_cms = $allPostPutVars['is_cms'] ? $allPostPutVars['is_cms'] : 0;
                        foreach ($typeId as $type) {
                            $this->updateAssetCache($storeId, $getTemplateId, $categoryIdList, 'template_is_ed_' . $type."_is_cms_". $is_cms);
                        }
    
                        if (!empty($categoryIdList)) {
                            foreach ($categoryIdList as $categoryId) {
                                $ppAssetCatRelGtInit = new PrintProfileModels\PrintProfileAssetsCategoryRel();
                                $printProfileIds = $ppAssetCatRelGtInit->where('category_id', $categoryId)->pluck('print_profile_id');
                                $this->createUpdateAssetJsonCache($getStoreDetails['store_id'], $printProfileIds, 'templates', $request, $response);
                            }
                        }
                        $jsonResponse = [
                            'status' => 1,
                            'message' => message('Template', 'deleted')
                        ];
                    }
                }
            }
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'save template'
                ]
            ]);
        }
        //Flush Memcached
        $this->memcache('deleteMulti', '', '', 'template');
        $this->memcache('deleteMulti', '', '', "templates_cat");
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }
    /**
     * Delete Files used by Design Data and Templates by reading the json file
     *
     * @param $refIdList Array of Design Ids
     *
     * @author tanmayap@riaxe.com
     * @date   20 Feb 2020
     * @return boolean
     */
    public function deleteTemplateStuffs($refIdList, $storeId)
    {
        $jsonLocW = path('abs', 'design_state') . 'templates';
        $primeLocationR = path('abs', 'design_preview') . 'templates';
        $deleteStatus = 0;

        $templateDesignStInit = new DesignStates();

        if (!empty($refIdList)) {
            foreach ($refIdList as $designId) {

                $designStateData = $templateDesignStInit->select('cloud_storage')->where('xe_id', $designId)->get()->first();
                $isS3Enabled = $designStateData->cloud_storage;

                $getJsonFile = $this->getCaptureImages($designId, true);
                $jsonFileLoc = $jsonLocW . '/' . $designId . '.json';

                // delete without product files
                if (!empty($getJsonFile['without_product_file'])) {
                    foreach ($getJsonFile['without_product_file'] as $woFile) {
                        $fileName = explode("/templates/", $woFile['src']);
                        $woFile['filename'] = $fileName[1];
                        if ($isS3Enabled) {
                            $fileFullLoc =  $woFile['src'];
                            $fileFullLocThumb = $woFile['thumb'];
                            $this->deleteS3File($fileFullLoc, $storeId);
                            $this->deleteS3File($fileFullLocThumb, $storeId);
                        }
                        $fileFullLoc = $primeLocationR . '/' . $woFile['filename'];
                        $fileFullLocThumb = $primeLocationR . '/' . 'thumb_' . $woFile['filename'];
                        if (file_exists($fileFullLoc)) {
                            delete_directory($fileFullLoc);
                            $deleteStatus++;
                        }
                        if (file_exists($fileFullLocThumb)) {
                            delete_directory($fileFullLocThumb);
                            $deleteStatus++;
                        }
                    }
                }
                // delete with product files
                if (!empty($getJsonFile['with_product_file'])) {
                    foreach ($getJsonFile['with_product_file'] as $wFile) {
                        $fileName = explode("/templates/", $wFile['src']);
                        $wFile['filename'] = $fileName[1];
                        if ($isS3Enabled) {
                            $fileFullLoc =  $wFile['src'];
                            $fileFullLocThumb =  $wFile['thumb'];
                            $this->deleteS3File($fileFullLoc, $storeId);
                            $this->deleteS3File($fileFullLocThumb, $storeId);
                        }
                        $fileFullLoc = $primeLocationR . '/' . $wFile['filename'];
                        $fileFullLocThumb = $primeLocationR . '/' . 'thumb_' . $wFile['filename'];
                        if (file_exists($fileFullLoc)) {
                            delete_directory($fileFullLoc);
                            $deleteStatus++;
                        }
                        if (file_exists($fileFullLocThumb)) {
                            delete_directory($fileFullLocThumb);
                            $deleteStatus++;
                        }
                    }
                }

                // After Deleting all Binary image files, Delete the json file
                if (file_exists($jsonFileLoc)) {
                    delete_directory($jsonFileLoc);
                }
            }
            // Manupulate the response
            if ($deleteStatus > 0) {
                return true;
            }
        }

        return false;
    }
    /**
     * Save Template Tags into Tags table and Template-tag Relational table
     *
     * @param $storeId    Store ID
     * @param $templateId Template ID
     * @param $tags       Tags in json array format
     *
     * @author tanmayap@riaxe.com
     * @date   5 Oct 2019
     * @return Boolean
     */
    protected function _saveTemplateTags($storeId, $templateId, $tags)
    {
        // Save Clipart and tags relation
        if (!empty($tags)) {
            $tagToArray = json_clean_decode($tags, true);
            $tagToString = implode(',', $tagToArray);
            $getTagIds = $this->saveTags($storeId, $tagToString);
            // SYNC Tags into Clipart Tag Relationship Table
            $templateInit = new TemplateModel\Template();
            $findTemplate = $templateInit->find($templateId);
            if ($findTemplate->tags()->sync($getTagIds)) {
                return true;
            }
        } else {
            // Clean relation in case no tags supplied
            $templateTagRelInit = new TemplateModel\TemplateTagRel();
            $templateTags = $templateTagRelInit->where('template_id', $templateId);
            if ($templateTags->delete()) {
                return true;
            }
        }
        return false;
    }

    /**
     * Save Template Categories into Categories table and Template-category
     * Relational table
     *
     * @param $request    Slim's Request object
     * @param $response   Slim's Response object
     * @param $parameters Slim's Argument parameters
     * @param $saveType   Flag for Save or Update
     *
     * @author tanmayap@riaxe.com
     * @date   5 Oct 2019
     * @return Boolean
     */
    private function _SaveTemplateCategories($request, $response, $parameters, $saveType = 'save')
    {
        $getPostData = $request->getParsedBody();
        $templateId = $parameters['template_id'];
        $categories = $getPostData['categories'];
        // get the categories
        $categoryListArray = json_clean_decode($categories, true);
        foreach ($categoryListArray 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);

                $parentId =  $categoriesData[0]['parent_id'];
                if ($parentId > 0) {
                    $shapeCat->where('xe_id', '=', $parentId)->update($flagList);
                }
            }
        }
        // Clean-up old records before updating the table
        if ($saveType == 'update') {
            TemplateModel\TemplateCategoryRel::where('template_id', $templateId)
                ->delete();
        }

        // SYNC Categories to the Clipart_Category Relationship Table
        $templateInit = new TemplateModel\Template();
        $findTemplate = $templateInit->find($templateId);
        if ($findTemplate->categories()->sync($categoryListArray)) {
            return true;
        }
        return false;
    }

    /**
     * Save method for Template data
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $reffId   REF ID from Design State Table
     * @param $saveType Flag for Save or Update
     *
     * @author tanmayap@riaxe.com
     * @date   5 Oct 2019
     * @return Boolean
     */
    private function _saveTemplates($request, $response, $reffId, $saveType = 'save')
    {
        $getStoreDetails = get_store_details($request);
        $getPostData = $request->getParsedBody();

        //Flush Memcached
        $this->memcache('deleteMulti', '', '', 'template');
        $this->memcache('deleteMulti', '', '', "templates_cat");

        try {
            $templateData = [
                'ref_id' => $reffId,
                'store_id' => $getStoreDetails['store_id'],
                'name' => $getPostData['name'],
                'description' => isset($getPostData['description'])
                    ? $getPostData['description'] : null,
                'no_of_colors' => $getPostData['no_of_colors'],
                'color_hash_codes' => $getPostData['used_colors'],
                'template_index' => $getPostData['template_index'],
                'is_easy_edit' => !empty($getPostData['is_easy_edit']) ? $getPostData['is_easy_edit'] : 0,
                'is_blank_canvas' => !empty($getPostData['is_blank_canvas']) ? $getPostData['is_blank_canvas'] : 0,
                'show_in_tool' => isset($getPostData['show_in_tool']) ? intval($getPostData['show_in_tool']) : 1
            ];

            if ($saveType == 'update') {
                unset($templateData['ref_id']);
                // Create a new object instance for fetch
                $templateInit = new TemplateModel\Template();
                $updateTemplateInit = $templateInit->where('ref_id', $reffId);

                $updateTemplateInit->update($templateData);
                // Send template id on success updation so that at update method
                // we can check if update done or not
                return $updateTemplateInit->first()->xe_id;
            } else {
                // Create a new object instance for save
                $saveTemplateInit = new TemplateModel\Template($templateData);
                $saveTemplateInit->save();
                if ($saveTemplateInit->xe_id) {
                    return $saveTemplateInit->xe_id;
                }
            }
        } catch (\Exception $e) {
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'save template'
                ]
            ]);
        }
        return false;
    }

    /**
     * Save method for Print profile Relations
     *
     * @param $request    Slim's Request object
     * @param $response   Slim's Response object
     * @param $reffId     REF ID from Design State Table
     * @param $templateId Insert ID of Template Record
     * @param $saveType   Flag for Save or Update
     *
     * @author tanmayap@riaxe.com
     * @date   5 Oct 2019
     * @return Boolean
     */
    private function _savePrintProfileRelations($request, $response, $reffId, $templateId, $saveType = 'save')
    {
        $getPostData = $request->getParsedBody();
        $printProfileRels = [];

        $getPrintProfiles = json_clean_decode($getPostData['print_profiles'], true);

        if (!empty($getPrintProfiles)) {
            foreach ($getPrintProfiles as $printKey => $printProfile) {
                $printProfileRels[$printKey] = [
                    'print_profile_id' => $printProfile,
                    'template_id' => $templateId,
                ];
            }
        }
        // Clean-up old records before updating the table
        if ($saveType == 'update') {
            TemplateModel\TemplatePrintProfileRel::where('template_id', $templateId)
                ->delete();
        }
        // create the template print profile relation
        if ($printProfileRels) {
            $tempPrintProfRelInit = new TemplateModel\TemplatePrintProfileRel();
            $savePrintProfileData = $tempPrintProfRelInit->insert($printProfileRels);
            if ($savePrintProfileData) {
                return true;
            }
        }

        return false;
    }

    /**
     * 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;
        $getStoreDetails = get_store_details($request);
        $storeId = $getStoreDetails['store_id'];
        $jsonResponse = [
            'status' => 0,
            'message' => message('Category', 'error')
        ];
        if (!empty($args) && $args['id'] > 0) {
            $categoryId = $args['id'];
            $jsonResponse = $this->deleteCat(
                $storeId,
                'templates',
                $categoryId,
                'Templates',
                'TemplateCategoryRel'
            );
        }
        $this->memcache('deleteMulti', '', '', "templates_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, "templates", $request, $response);
        }
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }

    /**
     * Get most used template
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     *
     * @author debashrib@riaxe.com
     * @date   04 Mar 2020
     * @return json
     */
    public function mostUsedTemplate($request, $response)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Fonts', 'error')
        ];

        $getStoreDetails = get_store_details($request);
        $page = $request->getQueryParam('page');
        $perpage = $request->getQueryParam('perpage');

        $templateInit = new TemplateModel\Template();
        $getTemplates = $templateInit->where($getStoreDetails)
            ->select('xe_id', 'name', 'ref_id');
        $totalCounts = $getTemplates->count();

        if ($totalCounts > 0) {
            // Get pagination data
            $offset = 0;
            if (isset($page) && $page != "") {
                $totalItem = empty($perpage) ? PAGINATION_MAX_ROW : $perpage;
                $offset = $totalItem * ($page - 1);
                $getTemplates->skip($offset)->take($totalItem);
            }

            $templateData = $templateList = $getTemplates->orderBy('total_used', 'DESC')
                ->get();

            foreach ($templateList as $templateKey => $template) {
                $referenceId = $template->ref_id;
                // Get template Images
                $getAssocCaptures = $this->getCaptureImages($referenceId);
                $templateData[$templateKey]['capture_images']
                    = $getAssocCaptures;
            }
            $jsonResponse = [
                'status' => 1,
                'total_records' => $totalCounts,
                'records' => count($templateData),
                'data' => $templateData
            ];
        }

        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }
    /**
     * POST: Update Templates along with designs
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author satyabratap@riaxe.com
     * @date   22 Sept 2020
     * @return Save status in json format
     */
    public function updateTemplates($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Design Template', 'error')
        ];
        try {
            // get the store details
            $getStoreDetails = get_store_details($request);
            $allPutVars = $request->getParsedBody();

            if (!empty($args['id']) && $args['id'] > 0) {
                $designId = to_int($args['id']);

                $templateDesignInit = new DesignStates();
                $getDesignState = $templateDesignInit->where('xe_id', $designId);
                $isDesignExists = $getDesignState->count() > 0;
                if (!$isDesignExists) {
                    // if designe state does not exists, and template is imported, then delete the template and create a new
                    $templateInit = new Template();
                    $getImportedTeplate = $templateInit->where([
                        ['ref_id', '=', $designId],
                        ['is_imported', '=', '1']
                    ])->first();
                    if (!empty($getImportedTeplate)) {
                        // delete the template
                        $this->deleteTemplate($request, $response, ['id' => "[{$getImportedTeplate->xe_id}]"]);
                        // save a new template
                        return $this->saveDesigns($request, $response);
                    } else {
                        throw new \Exception('Template not found');
                    }
                }

                $designData = !empty($allPutVars['design_data']) ? $allPutVars['design_data'] : '';

                $designState = [
                    'product_setting_id' => $allPutVars['product_settings_id'],
                    'product_variant_id' => $allPutVars['product_variant_id'],
                    'type' => $allPutVars['template_type'],
                    'selected_category_id' => $allPutVars['selected_category_id']
                ];
                $option = [
                    'directory' => 'templates',
                    'save_type' => 'update',
                    'design_id' => $designId,
                ];

                // Save design data and svg json format
                $this->saveDesignData($designState, "", $option);

                // save the design images
                $this->saveDesignImages($request, $response, [
                    'ref_id' => $designId,
                    'svg_data' => $designData,
                    'update_type' => 'update'
                ]);

                if ($isDesignExists) {
                    $getDesignState->update($designState);
                    // Save Template Data with its dedicated function
                    $templateSaveResponse = $this->_saveTemplates(
                        $request,
                        $response,
                        $designId,
                        'update'
                    );
                    if ($templateSaveResponse) {
                        // Save Print Profile Relations
                        $this->_savePrintProfileRelations(
                            $request,
                            $response,
                            $designId,
                            $templateSaveResponse,
                            'update'
                        );
                        // Save Template Tag Relations
                        $templateTagRels = [
                            'reff_id' => $designId,
                            'template_id' => $templateSaveResponse,
                            'store_id' => $getStoreDetails['store_id']
                        ];
                        $this->_saveTemplateTags(
                            $getStoreDetails['store_id'],
                            $templateSaveResponse,
                            $allPutVars['tags']
                        );
                        // Save Template Categories
                        $this->_SaveTemplateCategories(
                            $request,
                            $response,
                            $templateTagRels,
                            'update'
                        );
                    }
                    $jsonResponse = [
                        'status' => 1,
                        'message' => message('Design Template', 'updated')
                    ];
                }
                 //update template asset cache 
                 $assetParams['categories'] = $allPutVars['selected_category_id'];
    
                 $type = $allPutVars['is_easy_edit'] ? $allPutVars['is_easy_edit'] : 0;
                 $is_cms = $allPutVars['is_cms'] ? $allPutVars['is_cms'] : 0;
     
                 $this->updateAssetCache($getStoreDetails['store_id'], '', $assetParams, 'template_is_ed_' . $type."_is_cms_". $is_cms);
            }
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Update Design State'
                ]
            ]);
        }
        //Flush Memcached
        $this->memcache('deleteMulti', '', '', 'template');
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }

    /**
     * GET: Central server method - get template data through curl
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author soam@imprintnext.com
     * @date   22 July 2021
     * @return json format
     */
    public function importTemplates($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 1,
            'data' => [],
            'message' => message('Template', 'not_found')
        ];
        try {
            $categoryId = $request->getQueryParam("catagory");
            $printProfileId = $request->getQueryParam('print_profile_id');

            if (!empty($categoryId)) {
                $templateArreay = $this->getTemplatesByCatId($categoryId, $printProfileId);
                $totalRecords = count($templateArreay);
                if (!empty($templateArreay)) {
                    $jsonResponse = [
                        'status' => 1,
                        'total_records' => $totalRecords,
                        'data' => $templateArreay
                    ];
                }
            } else {
                $catPage = $request->getQueryParam('cat_page');
                $catPerpage = $request->getQueryParam('cat_perpage');
                $sortBy = $request->getQueryParam('sortby');
                $catOrder = (!empty($request->getQueryParam('cat_order'))
                    && $request->getQueryParam('cat_order') != null
                ) ? $request->getQueryParam('cat_order') : 'desc';
                $subCatAllow = (!empty($request->getQueryParam('sub_cat'))
                    && $request->getQueryParam('sub_cat') != null
                ) ? $request->getQueryParam('sub_cat') : 1;
                $searchKey = $request->getQueryParam('search_cat_name');

                $getCategory = (new Category())->where('asset_type_id', '=', 11);
                if (!empty($searchKey)) {
                    $getCategory->where('name', 'LIKE', '%' . $searchKey . '%');
                }
                if ($subCatAllow == "false") {
                    $getCategory->where('parent_id', '=', 0);
                }
                $totalRecords = $getCategory->count();

                // Pagination Data
                if (!empty($catPage)) {
                    $totalItem = empty($catPerpage) ? PAGINATION_MAX_ROW : $catPerpage;
                    $catOffset = $totalItem * ($catPage - 1);
                    $getCategory->skip($catOffset)->take($totalItem);
                }

                // Sorting All records by column name and sord catOrder parameter
                if (!empty($sortBy) && !empty($catOrder)) {
                    $getCategory->orderBy($sortBy, $catOrder);
                }

                $getCategoryArray = $getCategory->get()->toArray();
                $datacnt = $getCategory->count();
                if (!empty($getCategoryArray)) {
                    $jsonResponse = [
                        'status' => 1,
                        'records' => $datacnt,
                        'total_records' => $totalRecords,
                        'data' => $getCategoryArray
                    ];
                }
            }
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Update Design State'
                ]
            ]);
        }

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

    /**
     * GET: Save template data 
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author soam@imprintnext.com
     * @date   22 July 2021
     * @return json format
     */

    public function saveImportTemaplates($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 1,
            'data' => [],
            'message' => message('Template', 'not_found'),
        ];
        try {
            // model objects
            $categoryInit = new Category();

            // post data
            $allPostPutVars = $request->getParsedBody();
            $categoryId = $allPostPutVars["cat_id"];
            $printProfileId = $allPostPutVars["print_id"];
            $tagId = $allPostPutVars["tag"];
            $storeId = $allPostPutVars["store_id"] ? $allPostPutVars["store_id"] : 1;

            // get the store details
            $getStoreDetails = get_store_details($request);

            // get the templates on the central server
            $endPoint = CENTRAL_ASSETS_BASEURL . "api/v1/import-template";
            $allTemplates = api_call_by_curl([
                "catID" => $categoryId,
                "print_profile_id" => $printProfileId
            ], $endPoint, false, false);

            $onlyData = $allTemplates["data"]; // template data
            foreach ($onlyData as $subCat) {
                $insertTemplates = $subCat['template'];
                foreach ($insertTemplates as $iTemplate) {
                    // delete the existing template with the matching reference
                    $templateInit = new Template();
                    $templateInit->where('ref_id', $iTemplate['ref_id'])->delete();

                    // prepare the template data
                    $colorcode = json_encode($iTemplate['color_hash_codes']);
                    $templatesArray = [
                        'ref_id' => $iTemplate['ref_id'],
                        'name' => $iTemplate['name'],
                        'description' => $iTemplate['description'],
                        'no_of_colors' => $iTemplate['no_of_colors'],
                        'color_hash_codes' => $colorcode,
                        'template_index' => $iTemplate['template_index'],
                        'is_easy_edit' => $iTemplate['is_easy_edit'],
                        'is_blank_canvas' => isset($iTemplate['is_blank_canvas']) ? $iTemplate['is_blank_canvas'] : 0,
                        'show_in_tool' => isset($iTemplate['show_in_tool']) ? $iTemplate['show_in_tool'] : 1,
                        'total_used' => $iTemplate['total_used'],
                        'is_imported' => '1',
                        'store_id' => $storeId
                    ];

                    if ($iTemplate['is_imported'] == 0) {
                        // create new template
                        $templateInitSave = new Template($templatesArray);
                        if ($templateInitSave->save()) {
                            $templateLastId = $templateInitSave->xe_id;
                            $catagories = json_decode($iTemplate['catagories'], true);
                            $thisCatName =  $catagories[$categoryId];

                            // Template's asset type id = 11
                            $getCategory = $categoryInit->where(['asset_type_id' => 11, 'name' => $thisCatName]);
                            // create template asset if not existed
                            $importId = $subCat['parent_id'] == 0 ? $subCat['xe_id'] : $subCat['parent_id'];
                            if ($getCategory->count() == 0) {
                                $insertCat = [
                                    "asset_type_id" => 11,
                                    "name" => $thisCatName,
                                    "parent_id" => 0,
                                    "sort_order" => 0,
                                    "store_id" => $getStoreDetails['store_id'],
                                    "import_id" => $importId
                                ];
                                $saveCategory = new Category($insertCat);
                                $saveCategory->save();
                                $tempCatID = $saveCategory->xe_id;
                            } else {
                                $getCat = $getCategory->get()->first();
                                $tempCatID = $getCat->xe_id;
                                $categoryInit->where('xe_id', '=', $tempCatID)->update(['import_id' => $importId]);
                            }

                            // create the template category relation
                            if (!empty($tempCatID)) {
                                $saveData = ['template_id' => $templateLastId, 'category_id' => $tempCatID];
                                $catagoryTemplateInit = new TemplateCategoryRel($saveData);
                                $catagoryTemplateInit->save();
                            }
                            // create print profile
                            $selectedProfiles = json_decode($printProfileId);
                            if (!empty($selectedProfiles)) {
                                foreach ($selectedProfiles as $ppId) {
                                    $printProfileInit = new \App\Modules\PrintProfiles\Models\PrintProfileAssetsCategoryRel();
                                    $recordCount = $printProfileInit->where([
                                        'print_profile_id' => $ppId,
                                        'asset_type_id' => 11,
                                        'category_id' => $tempCatID
                                    ])->count();
                                    if ($recordCount < 1) {
                                        $printProfileInit->print_profile_id = $ppId;
                                        $printProfileInit->asset_type_id = 11;
                                        $printProfileInit->category_id = $tempCatID;
                                        $printProfileInit->save();
                                    }
                                    $savePrintProfileData = ['template_id' => $templateLastId, 'print_profile_id' => $ppId];
                                    $tempPrintProfRelInit = new TemplateModel\TemplatePrintProfileRel($savePrintProfileData);
                                    $tempPrintProfRelInit->save();
                                }
                            }
                            // save tags
                            if (!empty($tagId)) {
                                $this->_saveTemplateTags(
                                    $getStoreDetails['store_id'],
                                    $templateLastId,
                                    $tagId
                                );
                            }
                        }
                    } else {
                        $getTemplatesByName = $templateInit->where(['name' => $iTemplate['name'], 'is_imported' => 1]);
                        $getTemplatesByName->update($templatesArray);
                    }
                }
            }

            $assetParams['categories'] = '[' . $tempCatID . ']';

            //Flush Memcached
            $this->memcache('deleteMulti', '', '', 'template');

            $type = $allPostPutVars['is_easy_edit'] ? $allPostPutVars['is_easy_edit'] : 0;
            $is_cms = $allPostPutVars['is_cms'] ? $allPostPutVars['is_cms'] : 0;

            $this->updateAssetCache($storeId, $templateLastId, $assetParams, 'template_is_ed_' . $type."_is_cms_". $is_cms);

            $categoryIds = $assetParams['categories'];
            $this->memcache('deleteMulti', '', '', "templates_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, 'cliparts', $request, $response);
                }
            }
            if (!empty($onlyData)) {
                $jsonResponse = [
                    'status' => 1,
                    'total_records' => count($onlyData),
                    'data' => $onlyData
                ];
            }
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Save import temaplates'
                ]
            ]);
        }

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

    /**
     * GET: Fetch template data 
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author soam@imprintnext.com
     * @date   06 Aug 2021
     * @return json format
     */

    public function fetchImportTemaplates($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 1,
            'total_records' => 0,
            'records' => 0,
            'data' => [],
            'message' => message('Template', 'not_found'),
        ];

        try {
            $catPage = $request->getQueryParam('cat_page');
            $catPerpage = $request->getQueryParam('cat_perpage');
            $catOrder = (!empty($request->getQueryParam('cat_order')) ? $request->getQueryParam('cat_order') : 'desc');
            $categoryId = $request->getQueryParam('cat_id');
            $searchKey = '';

            // get the template data from the central server
            $endPoint = CENTRAL_ASSETS_BASEURL . "api/v1/import-template";
            $allCategory = api_call_by_curl([
                "cat_id" => $categoryId,
                "cat_page" => $catPage,
                "cat_perpage" => $catPerpage,
                "cat_order" => $catOrder,
                "sub_cat" => "false",
                "search_cat_name" => $searchKey
            ], $endPoint, false, false);

            $allCategoryArray = $allCategory['data'];

            // remove the unnecessary keys
            array_walk($allCategoryArray, function (&$val) {
                $val['id'] = $val['xe_id'];
                unset(
                    $val['xe_id'],
                    $val['parent_id'],
                    $val['asset_type_id'],
                    $val['sort_order'],
                    $val['is_disable'],
                    $val['is_default'],
                    $val['created_at'],
                    $val['updated_at'],
                    $val['is_defined']
                );
            });

            if (!empty($allCategoryArray)) {
                foreach ($allCategoryArray as $key => $cat) {
                    $categoryInit = new Category();
                    $result = $categoryInit->where('import_id', '=', $allCategoryArray[$key]['id'])->get();
                    if ($result->count() > 0) {
                        $allCategoryArray[$key]['is_imported'] = '1';
                    } else {
                        $allCategoryArray[$key]['is_imported'] = '0';
                    }
                }
                $jsonResponse = [
                    'status' => 1,
                    'records' => count($allCategoryArray),
                    'total_records' => $allCategory['total_records'],
                    'data' => $allCategoryArray
                ];
            }
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Fetch category'
                ]
            ]);
        }

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

    /**
     * fetch All category from central server to client's server.
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author soam@imprintnext.com
     * @date   24 Aug 2021
     * @return json
     */

    public function fetchCategory($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 1,
            'data' => [],
            'message' => message('Category', 'not_found')
        ];
        try {
            $searchKey = $request->getQueryParam('search_cat_name');
            $catPage = $request->getQueryParam('cat_page');
            $catPerpage = $request->getQueryParam('cat_perpage');
            $catOrder = (!empty($request->getQueryParam('cat_order')) ? $request->getQueryParam('cat_order') : 'desc');

            // get the template from the central server
            $endPoint = CENTRAL_ASSETS_BASEURL . "api/v1/import-template";
            $allCategory = api_call_by_curl([
                "cat_page" => $catPage,
                "cat_perpage" => $catPerpage,
                "cat_order" => $catOrder,
                "sub_cat" => "false",
                "search_cat_name" => $searchKey
            ], $endPoint, false, false);

            $allCategoryArray = $allCategory['data'];

            // remove the unnecessary keys
            array_walk($allCategoryArray, function (&$val) {
                $val['id'] = $val['xe_id'];
                unset(
                    $val['xe_id'],
                    $val['parent_id'],
                    $val['asset_type_id'],
                    $val['sort_order'],
                    $val['is_disable'],
                    $val['is_default'],
                    $val['created_at'],
                    $val['updated_at'],
                    $val['is_defined']
                );
            });

            if (!empty($allCategoryArray)) {
                foreach ($allCategoryArray as $key => $cat) {
                    $categoryInit = new Category();
                    $result = $categoryInit->where('import_id', '=', $allCategoryArray[$key]['id'])->get();
                    if ($result->count() > 0) {
                        $allCategoryArray[$key]['is_imported'] = '1';
                    } else {
                        $allCategoryArray[$key]['is_imported'] = '0';
                    }
                }
                //print_r( $allCategoryArray);exit;
                $jsonResponse = [
                    'status' => 1,
                    'records' => count($allCategoryArray),
                    'total_records' => $allCategory['total_records'],
                    'data' => $allCategoryArray,
                ];
            }
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Fetch category'
                ]
            ]);
        }

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

    /**
     * fetch category from central server to client's server when cat id is provided.
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author soam@imprintnext.com
     * @date   25 Aug 2021
     * @return Array
     */
    private function getTemplatesByCatId($categoryId, $printProfileId)
    {
        $catId = explode(",", $categoryId);
        $categoryInit = new Category();
        $getCategory = $categoryInit->where(['asset_type_id' => 11, 'parent_id' => $catId]);
        $getCategoryArray = $getCategory->get()->toArray();

        foreach ($getCategoryArray as $sub => $subCat) {

            $catIdArray = explode(",", $subCat['xe_id']);

            $templateInit = new Template();
            $getTemplates = $templateInit->where('xe_id', '>', 0)
                ->whereHas('templateCategory', function ($q) use ($catIdArray) {
                    return $q->whereIn('category_id', $catIdArray);
                });

            $templateArreay = $getTemplates->get()->toArray();
            $designStateInit = new \App\Components\Models\DesignStates();
            $catagoryInit = new TemplateCategoryRel();
            $printProfileInit = new PrintProfile();

            foreach ($templateArreay as $key => $value) {
                $templateId = $value['xe_id'];
                $designId = $value['ref_id'];

                // get the design states
                $getDesignState = $designStateInit->where('xe_id', $designId);
                $designStateArray = $getDesignState->get()->toArray();

                $templateArreay[$key]['design_data'] = $designStateArray;
                $templateArreay[$key]['product_id'] = $designStateArray ? $designStateArray[0]['product_id'] : '';

                // get the captured images
                $getAssocCaptures = $this->getCaptureImages($designId, false, true);
                $templateArreay[$key]['capture_images'] = $getAssocCaptures;

                // get the category ids from template category rel
                $getCatagory = $catagoryInit->where('template_id', $templateId);
                $getrelCatIds = $getCatagory->get()->pluck('category_id')->toArray();

                $templateArreay[$key]['catagories'] = json_encode($getrelCatIds);

                //printprofile
                if (!empty($printProfileId)) {
                    $printProfileIds = explode(",", $printProfileId);
                    $getPrintProfile = $printProfileInit->whereIn('xe_id', $printProfileIds);
                    $getPrintProfileArray = $getPrintProfile->select('xe_id as id', 'name')->get()->toArray();
                    $templateArreay[$key]['print_profiles'] = $getPrintProfileArray;
                } else {
                    $templateArreay[$key]['print_profiles'] = $this->templateToPrintProfile($templateId);
                }

                // tags
                $tempTagRelObj = new TemplateModel\TemplateTagRel();
                $tagNameList = $tempTagRelObj->with('tag')->where('template_id', $templateId)->get()->pluck('tag.name');

                $templateArreay[$key]['tag'] = $tagNameList;
            }
            $getCategoryArray[$sub]['totaltemplates'] = count($templateArreay);
            $getCategoryArray[$sub]['template'] = $templateArreay;
        }

        return $getCategoryArray;
    }

    /**
     * GET: Get Template Details By design Id
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author mike@imprintnext.com
     * @date   11 March 2024
     * @return Json Response
     *
     */
    public function getTemplateByDesignId($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 1,
            'total_records' => 0,
            'records' => 0,
            'data' => [],
            'message' => message('Template', 'not_found')
        ];
        try {
            // get the store id
            $storeId =  $request->getQueryParam('store_id');
            if (empty($storeId)) {
                $getStoreDetails = get_store_details($request);
                $storeId['store_id'] = $getStoreDetails['store_id'];
            }

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

            if (!empty($designID)) {
                $templateData = [];
                $urlPath = "";
                $templateDesignStInit = new DesignStates();
                $designStateData = $templateDesignStInit->where('xe_id', $designID)->first();
                if (!empty($designStateData)) {
                    // other type of template
                    $type = '';
                    switch ($designStateData->type) {
                        case 'cart':
                            $type = 'carts';
                            break;
                        case 'predecorator':
                            $type = 'predecorators';
                            break;
                        case 'quote':
                            $type = 'quotes';
                            break;
                        case 'share':
                            $type = 'shares';
                            break;
                        case 'user_design':
                            $type = 'user_designs';
                            break;
                        case 'artwork':
                            $type = 'artworks';
                            break;
                        case 'template':
                            $type = 'templates';
                            break;
                        default:
                            break;
                    }
                    // Get Associated product Details
                    $assocProductId = $this->getAssocProductId($designID, true); // true = store product
                    if ($assocProductId) {
                        $designData = [
                            'product_id' => $assocProductId['conditional_products_id'],
                            'product_name' => $assocProductId['product_name'],
                            'variant_id' => $assocProductId['product_variant_id'],
                            'product_name' => $assocProductId['product_name'],
                            'design_data' => $this->getSVGFile($designID, $type)
                        ];
                        // get the svg file
                        $svgJsonPath = path('abs', 'design_state') . $type . '/' . $designID . '.json';
                        if (file_exists($svgJsonPath)) {
                            $urlPath = path('read', 'design_state') . $type . '/' . $designID . '.json';
                            // read the svg data
                            $svgData = read_file($svgJsonPath);
                            $svgDecodedData = json_clean_decode($svgData, true);
                            $designData['layer_data'] = $svgDecodedData['layer_data'];
                        }
                        $templateArr = ["template", "templates"];
                        if (in_array($designStateData->type, $templateArr)) {
                            $getAssocCaptures = $this->getCaptureImages($designID, $storeId, false, false); // 0 = not imported
                            $designData['capture_images'] = $getAssocCaptures;
                            $getDesignState = (new TemplateModel\TemplateDesignStates())->where('xe_id', '=', $designID)->get()->first();
                            $designData['get_design_state'] = $getDesignState;
                            $templateInit = new TemplateModel\Template();
                            $getTemplates = $templateInit->where([['ref_id', '=', $designID], ['is_imported', '=', '0']]);
                            if ($getTemplates->count() > 0) {
                                $getTemplatesData = $getTemplates->get()->first()->toArray();
                                $designData['is_easy_edit'] = $getTemplatesData['is_easy_edit'];
                            } else {
                                $designData['is_easy_edit'] = 0;
                            }
                        }
                    }
                    $templateData = [$designData];
                } else {
                    //get this template data
                    $templateInit = new Template();
                    $thisTemplate = $templateInit->where([['ref_id', '=', $designID], ['is_imported', '=', '1']])->first()->toArray();
                    $isImportedFromIN = $thisTemplate['is_imported'];
                    if($isImportedFromIN == 0){
                        $thisTemplate = $templateInit->where([['ref_id', '=', $designID], ['is_imported', '=', '0']])->first()->toArray();
                    }
                    $result = $this->getTemplateDetail($thisTemplate, $storeId);
                    $urlPath = $result['urlPath'];
                    $templateData = $result['template'];
                }
                if ($templateData) {
                    $jsonResponse = [
                        'status' => 1,
                        'records' => 1,
                        'total_records' => 1,
                        'data' => $templateData,
                        'design_url' => $urlPath
                    ];
                }
            }

            return response($response, [
                'data' => $jsonResponse,
                'status' => $serverStatusCode
            ]);
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Fetch template By Design Id'
                ]
            ]);
        }
    }

        /**
	 * Get all template for designer Tool
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author steve@imprintnext.com
	 * @date   11th June 2024
	 * @return json
	 */
    public function _getTemplatesForTool($request, $response, $args)
    {
        // get the filters
        $storeId =  $request->getQueryParam('store_id');
        if (empty($storeId)) {
            $getStoreDetails = get_store_details($request);
            $storeId = $getStoreDetails['store_id'];
        }
        $jsonResponse = [];
        $isAdmin = $request->getQueryParam('is_admin');
        $name = $request->getQueryParam('name');
        $page = $request->getQueryParam('page');
        $order = $request->getQueryParam('order');
        $perpage = $request->getQueryParam('perpage');
        $printProfileId = $request->getQueryParam('print_profile');
        $catagoryId = $request->getQueryParam('category');
        $colorUsed = $request->getQueryParam('color_used'); // number of colors
        $tagId = $request->getQueryParam('tag');
        $sortBy = $request->getQueryParam('sortby');
        $is_easy_edit = $request->getQueryParam('is_easy_edit',0);

        try{
            $show_in_tool = intval($request->getQueryParam('show_in_tool', 1));
            //customer group
            $customerId = $request->getQueryParam('customer') ? (int) $request->getQueryParam('customer') : 0;

            // ************not received filters***********
            $type = $request->getQueryParam('type', 0);
            // ************not received filters end*******

            $jsonResponse = ['status' => 1, 'data' => [], 'message' => message('Template', 'not_found')];

            // this block will get the templates assigned for selected product categories.
            $args['assets_name'] = 'templates';
            $totalRecords = 0;
            $categoriesList = []; // returned category data - default blank

            $is_cms = $request->getQueryParam('is_cms', 0);

            //read from asset cache
            $cat_page = $request->getQueryParam('cat_page');
            $cat_perpage = $request->getQueryParam('cat_perpage');

            $assetCacheData = [];
            if ( (!empty($printProfileId || $is_cms)) && $cat_page == 1 && $name == '' and empty($catagoryId) and ($customerId == 0)) {
                $assetCacheData = $this->getAssetCache($storeId, $printProfileId, $cat_page, $cat_perpage, 'template_is_ed_' . $type."_is_cms_". $is_cms);
            }
            
            //GET MEMCACHEDATA
            $memcacheData = [];
            if (IS_MEMCACHE and empty($name) and (!empty($printProfileId || $is_cms)) and ($customerId == 0)) {
                //MEMCACHED KEY
                $thisCacheKey = "template" . "_page" . $cat_page . "_order" . $order . "_perpage" . $cat_perpage . "_pp" . $printProfileId . "_s" . $storeId . "_type" . $type . "_is_cms" . $is_cms;

                //Register MEMCACHED KEY in Local Cache
                $this->createUpdateMemCacheGroup('template', $thisCacheKey, 'SET');
                $memcacheData = $this->memcache("get", $thisCacheKey);
            }
            
            if (empty($memcacheData)) {
                if (empty($assetCacheData)) {
                    $templateCategoryList = $this->getTemplateCategoryByPrintProfileId($request, $response, $args);

                    if (!empty($templateCategoryList) && !empty($templateCategoryList['data'])) {
                        $totalRecords = $templateCategoryList['total_records'];
                        foreach ($templateCategoryList['data'] as $category) {

                            if (empty($category['id'])) {
                                continue;
                            }
                            $templateInit = new TemplateModel\Template();
                            $getTemplates = $templateInit->where('xe_id', '>', 0);
                            $fields = [
                                'xe_id as id',
                                'xe_id',
                                'name',
                                'ref_id',
                                'no_of_colors',
                                'is_easy_edit',
                                'is_blank_canvas',
                                'is_imported',
                                'is_blank_canvas'
                            ];

                            if (!$isAdmin) {
                                $fields[]  = 'color_hash_codes';
                            }
                            // For multiple Shape data
                            $getTemplates->select($fields);


                            // This is derived from import template section.
                            // Filter Search as per type
                            if (isset($type) && $type != "" and ($is_cms == 0) ) {
                                $getTemplates->where('is_easy_edit', '=', $type);
                            }

                            $getTemplates = $getTemplates->where('show_in_tool', '=', $show_in_tool);
                            // Filter by customer group asset
                            if (STORE_NAME != 'Opencart') {
                                if ($customerId > 0) {
                                    $customerGroupControllerInit = new CustomerGroup();
                                    $customerGroupId = $customerGroupControllerInit->getGroupIdBycustomerId($customerId);
                                    if ($customerGroupId != '') {
                                        $assetTypeArr = $this->assetsTypeId('templates');
                                        $assetTypeId = $assetTypeArr['asset_type_id'];
                                        $catIds = $customerGroupControllerInit->getAssetsBygroupId($customerGroupId, $assetTypeId, $storeId);
                                        if (!empty($catIds)) {
                                            $getTemplates->whereHas('templateCategory', function ($q) use ($catIds) {
                                                return $q->whereIn('category_id', $catIds);
                                            });
                                        }
                                    }
                                }

                                // end filter customer group
                                $totalCounts = $getTemplates->count();

                                if ($totalCounts > 0) {

                                    // match with store id
                                    if (!empty($storeId)) {
                                        $getTemplates->where('store_id', $storeId);
                                    }

                                    // Color used Filter
                                    if (!empty($colorUsed)) {
                                        $getTemplates->where('no_of_colors', $colorUsed);
                                    }

                                    // Filter by Category IDs

                                    if (!empty($category['id'])) {
                                        $searchCategories = json_clean_decode($catagoryId, true);
                                        if (!empty($searchCategories)) {
                                            $getTemplates->whereHas('templateCategory', function ($q) use ($searchCategories) {
                                                return $q->whereIn('category_id', $searchCategories);
                                            });
                                        } else {
                                            $getTemplates->whereHas('templateCategory', function ($q) use ($category) {
                                                return $q->where('category_id', $category['id']);
                                            });
                                        }
                                    }

                                    // Filter by Tag IDs
                                    if (!empty($tagId)) {
                                        $searchTags = json_clean_decode($tagId, true);
                                        if (!empty($searchTags)) {
                                            $getTemplates->whereHas('templateTags', function ($q) use ($searchTags) {
                                                return $q->whereIn('tag_id', $searchTags);
                                            });
                                        }
                                    }

                                    // Filter by Print Profile
                                    if (!empty($printProfileId)) {
                                        $searchPrintProfiles = json_clean_decode($printProfileId, true);
                                        if (!empty($searchPrintProfiles)) {
                                            $getTemplates->whereHas('templatePrintProfiles', function ($q) use ($searchPrintProfiles) {
                                                return $q->whereIn('print_profile_id', $searchPrintProfiles);
                                            });
                                        }
                                    }

                                    // Multiple Table search for name attribute (multiple)
                                    if (!empty($name)) {
                                        $catTempIdArr = $tempIdArr = [];
                                        $tagsInit = new Tag();
                                        $tagData = $tagsInit->join(
                                            'template_tag_rel',
                                            'tags.xe_id',
                                            '=',
                                            'template_tag_rel.tag_id'
                                        )
                                            ->select('template_tag_rel.template_id')->where('tags.name',  'LIKE', '%' . $name . '%');
                                        if ($tagData->count() > 0) {
                                            $getTagData = $tagData->get()->toArray();
                                            $tempIdArr = array_column($getTagData, 'template_id');
                                        }
                                        $categoryInit = new CommonCategory();
                                        $catData = $categoryInit->join(
                                            'template_category_rel',
                                            'categories.xe_id',
                                            '=',
                                            'template_category_rel.category_id'
                                        )
                                            ->select('template_category_rel.template_id')->where('categories.name',  'LIKE', '%' . $name . '%');
                                        if ($catData->count() > 0) {
                                            $getCatData = $catData->get()->toArray();
                                            $catTempIdArr = array_column($getCatData, 'template_id');
                                        }
                                        $getTemplates->where('name', 'LIKE', '%' . $name . '%')
                                            ->orWhereIn('xe_id', $tempIdArr)
                                            ->orWhereIn('xe_id', $catTempIdArr);
                                    }

                                    // Total records including all filters
                                    $getTotalPerFilters = $getTemplates->count();

                                    // Get pagination data
                                    if (!empty($page)) {
                                        $totalItem = empty($perpage) ? PAGINATION_MAX_ROW : $perpage;
                                        $offset = $totalItem * ($page - 1);
                                        $getTemplates->skip($offset)->take($totalItem);
                                    }

                                    // Sorting by column name and sort order parameter
                                    if (!empty($sortBy) && !empty($order) && !empty($catTempIdArr)) {
                                        $getTemplates->orderBy($sortBy, $order)
                                            ->orWhereIn('xe_id', $catTempIdArr);
                                    }
                                    if (!empty($tempIdArr)) {
                                        if ($type == 0) {
                                            $getTemplates->where('name', 'LIKE', '%' . $name . '%')
                                                ->orWhereIn('xe_id', $tempIdArr);
                                        } else {
                                            $getTemplates->where('name', 'LIKE', '%' . $name . '%')
                                                ->orWhereIn('xe_id', $tempIdArr)
                                                ->orWhereIn('xe_id', $catTempIdArr);
                                        }
                                    }
                                }

                                // get the template data
                                $templateData = $getTemplates->orderBy('xe_id', 'DESC')
                                ->with('getDesignState')->get()->toArray();

                                // format, pupulate other fields
                                foreach ($templateData as $key => $template) {
                                    // Create template_id from xe_id
                                    $templateId = $templateData[$key]['id'] = $templateData[$key]['template_id'] = $template['xe_id'];
                                    $referenceId = $templateData[$key]['xe_id'] = $template['ref_id'];
                                    unset($templateData[$key]['xe_id']);

                                    if (!empty($templateId)) {
                                        // Get Associated Tags and Categories
                                        $getTagCategories = $this->getAssocCategoryTag($templateId);
                                        $templateData[$key]['categories'] = $getTagCategories['categories'];
                                        $templateData[$key]['tags'] = $getTagCategories['tags'];

                                        // Get Associated Print profiles
                                        $templateData[$key]['print_profiles'] = $this->templateToPrintProfile($templateId);

                                        if ($template['is_imported'] == 1) {

                                            // Get template Images
                                            $imagePath = CENTRAL_ASSETS_BASEURL . 'assets/design_previews/templates/';
                                            $getAssocCaptures =  [
                                                "without_product_file" => [
                                                    ["src" => "{$imagePath}template_{$referenceId}_wp.jpeg", "thumb" =>  "{$imagePath}thumb_template_{$referenceId}_wp.jpeg"]
                                                ],
                                                "with_product_file" => [
                                                    ["src" => "{$imagePath}template_{$referenceId}.png", "thumb" =>  "{$imagePath}thumb_template_{$referenceId}.png"]
                                                ]
                                            ];
                                        } else {
                                            // Get Associated product Details
                                            $assocProductId = $this->getAssocProductId($referenceId, false);

                                            $templateData[$key]['product_id'] = $assocProductId['conditional_products_id'];

                                            // Get template Images
                                            $getAssocCaptures = $this->getCaptureImages($referenceId, $storeId, false, false);
                                        }
                                        $templateData[$key]['capture_images'] = $getAssocCaptures;
                                    }
                                }
                            }

                            $categoriesList[] = [
                                'id' => $category['id'],
                                'name' => $category['name'],
                                'image_path' => !empty($category['file_name']) ? ASSETS_PATH_R . 'categories/' . 'thumb_' . $category['file_name'] : '',
                                'order' => $category['order'],
                                'is_disable' => $category['is_disable'],
                                'is_default' => $category['is_default'],
                                'description' => $category['description'],
                                'no_of_colors' => $category['no_of_colors'],
                                'print_profiles_match' => $category['print_profiles_match'],
                                'templates' => $templateData,
                                'records' => count($templateData),
                                'total_records' => $getTotalPerFilters
                            ];
                        }
                    }
                    if (!empty($categoriesList)) {
                        $jsonResponse = [
                            'status' => 1,
                            'records' => count($categoriesList),
                            'total_records' => $totalRecords,
                            'data' => $categoriesList,
                        ];
                    }


                    if ( (!empty($printProfileId || $is_cms)) && $cat_page == 1 && $name == '' and empty($catagoryId) and ($customerId == 0) ) {                  
                        $this->createAssetCache('template_is_ed_' . $type."_is_cms_". $is_cms, $storeId, $printProfileId, $jsonResponse, $cat_page);
                    }

                } else {
                    $jsonResponse = $assetCacheData;
                }

                //SET IN MEMCACHED
                if (IS_MEMCACHE and empty($name) and (!empty($printProfileId || $is_cms)) and isset($thisCacheKey) and ($customerId == 0)) {
                    $this->memcache("set", $thisCacheKey, $jsonResponse);
                }
            } else {
                $jsonResponse = $memcacheData;
                if (MEM_MODE) {
                    $jsonResponse['mode'] = 'memcache';
                }
            }
        }catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('template', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'save template'
                ]
            ]);
        }
        

        return $jsonResponse;
    }

    /**
	 * 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 steve@riaxe.com
	 * @date   11th June 2024
	 * @return json
	 */

	public function getTemplateCategoryByPrintProfileId($request, $response, $args) {
		//All Filter columns from url
		$categoryId = $request->getQueryParam('category');
		$page = $request->getQueryParam('cat_page');
		$perpage = $request->getQueryParam('cat_perpage');
        $is_cms = $request->getQueryParam('is_cms', 0);
        $customerId = $request->getQueryParam('customer') ? (int) $request->getQueryParam('customer') : 0;
        
		if(!empty($request->getQueryParam('print_profile_id'))){
			$printProfileId = $request->getQueryParam('print_profile_id');
		} else {
			$printprofile = $request->getQueryParam('print_profile');
			$printProfileId = (is_string($printprofile) && strlen($printprofile) > 1) ? json_decode($printprofile, true) : $printprofile;
			if (is_array($printProfileId)) {
				$printProfileId = $printProfileId[0];
			}
		}
		$primaryCategory = ( !empty($request->getQueryParam('primary_cat')) && $request->getQueryParam('primary_cat') != null
		) ? $request->getQueryParam('primary_cat') : 0;
		$name = $request->getQueryParam('name');

		// get the store details
		$getStoreDetails = get_store_details($request);
		$clipartsCategories = $primaryCategoryArr  = $clipartsCategoriesData = [];
		// get the asset type
		$assetsName = $args['assets_name'];
		$assetTypeArr = $this->assetsTypeId($assetsName);
        $storeId = $request->getQueryParam('store_id');

		if (($printProfileId > 0  || $is_cms)  && !empty($assetTypeArr) && $assetTypeArr['status'] == 1 ) {
			// Getting Assets module id
			$assetTypeId = $assetTypeArr['asset_type_id']; 
			### primary category remains empty on api calls - need to check
			if (!empty($primaryCategory) && $page == 1) {
				$getPrimaryProfileCat = DB::table('print_profile_assets_category_rel as ppac')
				->leftjoin('clipart_category_rel as ccr', 'ppac.category_id', '=', 'ccr.category_id')
				->join('categories as cat', 'ppac.category_id', '=', 'cat.xe_id')
				->join('cliparts as c', 'ccr.clipart_id', '=', 'c.xe_id')
				->leftjoin('clipart_tag_rel as ct', 'c.xe_id', '=', 'ct.clipart_id')
				->leftjoin('tags as t', 'ct.tag_id', '=', 't.xe_id')
				->where('ppac.asset_type_id', $assetTypeId);

                if(!$is_cms){
                    $getPrimaryProfileCat->where('ppac.print_profile_id', $printProfileId);
                }

				$getPrimaryProfileCat->where('ppac.category_id', $primaryCategory)
				->select('cat.xe_id as id', 'cat.parent_id', 'cat.name', 'cat.sort_order', 'cat.is_disable', 'cat.is_default')
				->distinct('cat.xe_id');
				if ($getPrimaryProfileCat->count() > 0) {
					$primaryProfileCat = $getPrimaryProfileCat->get()->first();
					$primaryCategoryArr = [
						'id' => $primaryProfileCat->id,
						'name' => $primaryProfileCat->name,
						'order' => $primaryProfileCat->sort_order,
						'is_disable' => $primaryProfileCat->is_disable,
						'is_default' => $primaryProfileCat->is_default
					];
				}
			}
            


            // categories based on print profile
            $profileCat = DB::table('print_profile_assets_category_rel as ppac')
            ->leftjoin('template_category_rel as tcr', 'ppac.category_id', '=', 'tcr.category_id')
            ->join('categories as cat', 'ppac.category_id', '=', 'cat.xe_id')
            ->join('templates as t',
                'tcr.template_id',
                '=',
                't.xe_id'
            )
            ->leftjoin('template_tag_rel as tt', 't.xe_id', '=', 'tt.template_id')
            ->leftjoin('tags as tg',
                'tt.tag_id',
                '=',
                'tg.xe_id'
            )
            ->where('ppac.asset_type_id', $assetTypeId);
            if(!$is_cms){
                $profileCat->where('ppac.print_profile_id', $printProfileId);
            }
           
            $profileCat->where('t.store_id', $getStoreDetails['store_id'])
            ->where('cat.store_id', $getStoreDetails['store_id']);
			
			// add more filters
			if (!empty($categoryId)) {
				$searchCategories = json_clean_decode($categoryId, true);
				if ($searchCategories != '') {
					$profileCat = $profileCat->whereIn('ppac.category_id', $searchCategories);
				}
			}
			if (isset($name) && $name != "") {
				$profileCat->where(function ($query) use ($name) {
					$query->where('t.name', 'LIKE', '%' . $name . '%')
						->orWhere('cat.name', 'LIKE', '%' . $name . '%')
						->orWhere('tg.name', 'LIKE', '%' . $name . '%');
				});
			}

            if ($customerId > 0) {
                $customerGroupControllerInit = new CustomerGroup();
                $customerGroupId = $customerGroupControllerInit->getGroupIdBycustomerId($customerId);
                if ($customerGroupId != '') {
                    $catIds = $customerGroupControllerInit->getAssetsBygroupId($customerGroupId, $assetTypeId, $storeId);                    
                    if (!empty($catIds)) {
                        //$profileCat->whereHas('templateCategory', function ($q) use ($catIds) {
                            $profileCat->whereIn('cat.xe_id', $catIds);
                       // });
                    }
                }
            }   
			$profileCat->select('cat.xe_id as id', 'cat.parent_id', 'cat.name', 'cat.file_name',  'cat.sort_order', 'cat.is_disable', 'cat.is_default')->distinct('cat.xe_id');

			$getTotalPerFilters = $profileCat->count(); // get the total category records

			// pagination part
			if (!empty($page)) {
				$totalItem = empty($perpage) ? PAGINATION_MAX_ROW : $perpage;
				$offset = $totalItem * ($page - 1);
				$profileCat->orderBy('cat.sort_order', 'asc')->skip($offset)->take($totalItem);
			}


            //$profileCat->orderBy('cat.sort_order', 'asc');

			if ($getTotalPerFilters > 0) {
				$profileCategory = $profileCat->get()->toArray();
				foreach ($profileCategory as $value) {
					$clipartsCategoriesData[] = [
						'id' => $value->id,
						'name' => $value->name,
						'file_name' => $value->file_name,
						'order' => $value->sort_order,
						'is_disable' => $value->is_disable,
						'is_default' => $value->is_default,
					];
				}
				$allClipartCategory = array_merge($primaryCategoryArr, $clipartsCategoriesData);
                $keys = array_column($allClipartCategory, 'order');
			    //array_multisort($keys, SORT_ASC,$allClipartCategory);
				$clipartsCategories = [
					'records' => count($profileCategory),
					'total_records' => $getTotalPerFilters,
					'data' => array_map("unserialize", array_unique(array_map("serialize", $allClipartCategory)))
				];
			}

		}
		return $clipartsCategories;
	}

    /**
     * POST: Save template url to the DB
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author divya@imprintnext.com
     * @date   10 September 2024
     * @return Json Response
     *
     */
    public function saveTemplateURL($request, $response) {
        $serverStatusCode = OPERATION_OKAY;
        $allPostPutVars = $request->getParsedBody();
        $storeId = $allPostPutVars['store_id'];
        $templateID = to_int($allPostPutVars['template_id']);
        if (!empty($templateID)) {
            //get this template data
            $templateInit = new Template();
            $thisTemplate = $templateInit->where('xe_id', $templateID)->first()->toArray();
            $designId = $thisTemplate['ref_id'];
            $isImportedFromIN = $thisTemplate['is_imported'];
            if($isImportedFromIN == 0) {
            $templateDesignStInit = new DesignStates();
            $designStateData = $templateDesignStInit->where('xe_id', $designId)->first()->toArray();
            $productId = $designStateData['product_id'];
            $variantID = $designStateData['product_variant_id'];            
                if (empty($productId)) {
                    $productId = 0;
                    $variantID = 0;
                    $templateURL = API_URL . 'index.html?id=' . $productId . '&vid=' . $variantID .'&etid=' . $templateID . '&store_id=' . $storeId;
                } else {
                    $templateURL = API_URL . 'index.html?id=' . $productId . '&vid=' . $variantID .'&etid=' . $templateID . '&store_id=' . $storeId;
                }

            if(empty($thisTemplate['temp_token'])) {
                $token = $this->uniqueRandomString();
                $templateData = [
                    'template_url' => $templateURL,
                    'temp_token' => $token
                    ];
                $updateTemplateInit = $templateInit->where('xe_id', $templateID);
                $updateTemplateInit->update($templateData);
                $lastUpdatedTempData = $templateInit->select('temp_token')->where('ref_id', $designId)->first()->toArray();
                $tokenizeId = $lastUpdatedTempData['temp_token'];
                } else {
                $tokenizeId = $thisTemplate['temp_token'];
                }
            $designUrl = API_URL . 'template.html?' .$tokenizeId;
        }
             $jsonResponse = [
                    'status' => 1,
                    'data' => $designUrl
                ];
        }
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }

    /**
     * GET: Template url from the DB
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author divya@imprintnext.com
     * @date   10 September 2024
     * @return Json Response
     *
     */
    public function viewTemplate($request,$response, $args){
        $serverStatusCode = OPERATION_OKAY;
        $deviceType =  $request->getQueryParam('is_mobile');
        $templateInit = new Template();
        $tempUrl = $templateInit->select('template_url')->where('temp_token', $args['id'])->get()->toArray();
        $tempUrlData = $tempUrl[0]['template_url'];
        if (strtolower(STORE_NAME) == 'shopify') {
            $baseUrl = "https://" . SHOPIFY_SHOP . ".myshopify.com/pages/designer-studio";
        }
        if (strtolower(STORE_NAME) == strtolower('Bigcommerce')) {
            $storeProductInit = new StoreProductsController();
            $baseUrl = $storeProductInit->getStoreDatas() . "/designer-studio/";
        }
        if (strtolower(STORE_NAME) == strtolower('Woocommerce')) {
            $urlData = strstr(BASE_URL, '/designer', true);
            $baseUrl = $urlData . "/product-designer/";
        }
        if(strtolower(STORE_NAME) == 'magento') {
			if(strpos(BASE_URL, 'designer')) {
				$urlData = strstr(BASE_URL, '/designer', true);
				$baseUrl = $urlData . "/imprint-next";
			} 
		    if(strpos(BASE_URL, 'pub')) {
				$urlData = strstr(BASE_URL, '/pub', true);
				$baseUrl = $urlData . "/imprint-next";
			}
        }
        if (strtolower(STORE_NAME) == 'prestashop') {
            $storeProductInit = new StoreProductsController();
            $storeData = $storeProductInit->psDesignerPage();
            $baseUrl = strstr($storeData, '?', true);
        }
       
        $url_components = parse_url($tempUrlData);
        $paramString = $url_components['query'];
        $secretKey = call_curl([], 'secretkey', 'GET'); //Getting secret key
        $urlPath = $this->encryptionImpParam($paramString, $secretKey);
        if(!empty($tempUrl)) {
            $jsonResponse = [
                'status' => 1,
                'data' => $baseUrl. '?' . $urlPath
            ];
        } else {
            $jsonResponse = [
                'status' => 1,
                'data' => 'template not found'
            ];
        }
        
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }

    /**
     * Internal function to encrypt the url parameters
     * @author divya@imprintnext.com
     * @date   10 September 2024
     * @return encoded text
     *
     */
    public function uniqueRandomString()
    {
        static $generated = [];
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

        $str = substr(str_shuffle($chars), 0, 5);
        if (!isset($generated[$str])) {
            $generated[$str] = true;
            return $str;
        }
    }

    public function encryptionImpParam($string, $secretKey) {
        $encryptedVal = '';
        if ($string != '') {
            $key =  '5';
	        $encrypte = $string.$secretKey;
            for($i=0, $k= strlen($encrypte); $i<$k; $i++) {
                $char = substr($encrypte, $i, 1);
                $char = chr(ord($char)+ord($key));
                $encryptedVal .= $char;
            }
	        $encryptedVal = base64_encode($encryptedVal);
        }
        return $encryptedVal;
    }

    
}
