<?php
/**
 * Manage Configurator Pattern
 *
 * PHP version 5.6
 *
 * @category  ConfiguratorPattern
 * @package   Assets
 * @author    Dibya Jyoti <divya@imprintnext.com>
 * @copyright 2024-2025 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\ConfiguratorPatterns\Controllers;

use App\Components\Controllers\Component as ParentController;
use App\Modules\ConfiguratorPatterns\Models\ConfiguratorPattern;
use App\Modules\ConfiguratorPatterns\Models\ConfiguratorPatternCategory as PatternCategory;
use App\Modules\ConfiguratorPatterns\Models\ConfiguratorPatternCategoryRelationship as PatternCategoryRelation;

/**
 * Configutator Pattern Controller
 *
 * @category Class
 * @package  ConfiguratorPatterns
 * @author   Dibya Jyoti <divya@imprintnext.com>
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @link     http://inkxe-v10.inkxe.io/xetool/admin
 */
class ConfiguratorPatternController extends ParentController {
    /**
	 * POST: Get Configurator pattern images and other details
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 *
	 * @author divya@imprintnext.com
	 * @date   20th March 2024
	 * @return json response wheather data is saved or any error occured
	 */
    public function saveConfigPattern($request, $response, $args) {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = ['status' => 0, 'message' => message('ConfiguratorPatterns', 'error')];
        try {
            $allPostPutVars = $request->getParsedBody();
            $getStoreDetails = get_store_details($request);
            $isS3Enabled = $this->checkS3Settings($getStoreDetails['store_id']);
            $patternFileName = do_upload('config_pattern', path('abs', 'configurator_pattern'), [100], 'string');
            $saveConfigPatternData = [
                'name' => $allPostPutVars['name'],
                'price' => $allPostPutVars['price'],
                'file_name' => $patternFileName,
                'store_id' => $getStoreDetails['store_id'],
                'cloud_storage' => 0
            ];

            // S3 implementation
            if ($isS3Enabled) {
                $fileToUpload = path('abs', 'configurator_pattern') . $patternFileName;
                $this->uploadFileToS3("configurator_patterns", $fileToUpload, $getStoreDetails['store_id']);
                $saveConfigPatternData['cloud_storage'] = 1;
            }
            $configPatternInit = new ConfiguratorPattern($saveConfigPatternData);
            if($configPatternInit->save()) {
                $lastInsertId = $configPatternInit->xe_id;
                if (!empty($allPostPutVars['categories'])) {
                    $categoryIds = $allPostPutVars['categories'];
                    $this->savePatternCategories($lastInsertId, $categoryIds);
                }
            }
            $jsonResponse = [
                'status' => 1,
                'message' => message('ConfiguratorPatterns', 'saved'),
            ];
        } catch (\Exception $e) {
            $jsonResponse['message'] = $e->getMessage();
        }

         // Flush config pattern memcached
         $this->memcache('deleteMulti', '', '', 'config_pattern');

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

    /**
	 * Save Categories and Configurator Pattern-Category Relations
	 *
	 * @param $patternId 
	 * @param $categoryIds (in comma separated if multiple is there)
	 *
	 * @author divya@imprintnext.com
	 * @date   22nd March 2024
	 * @return boolean
	 */
    public function savePatternCategories($patternId, $categoryIds) {
        $getAllCategoryArr = json_clean_decode($categoryIds, true);
		foreach($getAllCategoryArr as $catId){
			$configCat = new PatternCategory();
			$categoriesData = $configCat->where('xe_id', '=', $catId)->get()->toArray();
			if($catId == $categoriesData[0]['xe_id']){
				$flagList = [ 'asset_available_flag' => 1];
                $configCat->where('xe_id', '=', $catId)->update($flagList);
			}
		}
        $configPatternInit = new ConfiguratorPattern();
		$findPattern = $configPatternInit->find($patternId);
		if ($findPattern->categories()->sync($getAllCategoryArr)) {
			return true;
		}
		return false;
    }
    
    /**
	 * GET: Get list of Configurator pattern images and other details
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 *
	 * @author divya@imprintnext.com
	 * @date   20th March 2024
	 * @return json response wheather data is saved or any error occured
	 */
    public function getConfigPatternList($request, $response, $args) {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = ['status' => 0, 'message' => message('ConfiguratorPatterns', 'not_found')];
        try {
            // Getting single configurator pattern details
            if (!empty($args['id'])) {
				$jsonResponse = $this->_getSingleConfigPattern($request, $args);
				return response($response, [
					'data' => $jsonResponse, 'status' => $serverStatusCode
				]);
			}
            $getStoreDetails = get_store_details($request);
            $storeId = $getStoreDetails['store_id'];

            //All required filter parameters
            $page = $request->getQueryParam('page');
            $perpage = $request->getQueryParam('perpage');
            $sortBy = !empty($request->getQueryParam('sortby'))
            && $request->getQueryParam('sortby') != ""
            ? $request->getQueryParam('sortby') : 'xe_id';
            $order = !empty($request->getQueryParam('order')) && $request->getQueryParam('order') != "" ? $request->getQueryParam('order') : 'desc';
            $name = $request->getQueryParam('name');

            //GET MEMCACHEDATA
            $memcacheData = [];
            if (IS_MEMCACHE and empty($name)) {
                //MEMCACHED KEY
                $thisCacheKey = "config_pattern" . "_page" . $page . "_order" . $order . "_perpage" . $perpage . "_s" . $storeId;
                //Register MEMCACHED KEY in Local Cache
                $this->createUpdateMemCacheGroup('config_pattern', $thisCacheKey, 'SET');
                $memcacheData = $this->memcache("get", $thisCacheKey);
            }

            if (empty($memcacheData)) {
            $configPatternInit = new ConfiguratorPattern();
            $getConfigPatternData = $configPatternInit->where([
                ['xe_id', '>', 0],
                ['store_id', '=', $storeId]
            ])->select([
                'xe_id', 'name', 'price', 'file_name', 'cloud_storage'
            ]);

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

            // Pagination Data
            if (isset($page) && $page != "") {
                $totalItem = empty($perpage) ? PAGINATION_MAX_ROW : $perpage;
                $offset = $totalItem * ($page - 1);
                $getConfigPatternData->skip($offset)->take($totalItem);
            }
            // Sorting All records by column name and sort by order parameter
            if (isset($sortBy) && $sortBy != "" && isset($order) && $order != "") {
                $getConfigPatternData->orderBy($sortBy, $order);
            }
            
            // Searching by name
            if (isset($name) && $name != '') {
                $name = '\\' . $name;
                $getConfigPatternData->where('name', 'LIKE', '%' . $name . '%');
            }
            
            // get pattern Data list
            $patternData = $getConfigPatternData->get()->toArray();

            // s3 implementations
            foreach ($patternData as $patternkey => $patternValue) {
                if ($patternValue['cloud_storage'] == 1) {
                    $thisFileName = $this->getS3URL($patternValue['file_name'], $storeId);
                    $patternData[$patternkey]['file_name'] = $thisFileName;
                }
            }
            $jsonResponse = [
                'status' => 1,
                'records' => count($patternData),
                'total_records' => $getTotalPerFilters,
                'data' => $patternData
            ];

                //SET IN MEMCACHED
                if (
                    IS_MEMCACHE and empty($name) and isset($thisCacheKey)
                ) {
                    $this->memcache("set", $thisCacheKey, $jsonResponse);
                }

            } else {
                $jsonResponse = $memcacheData;
                if (MEM_MODE) {
                    $jsonResponse['mode'] = 'memcache';
                }
            }
           
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('ConfiguratorPatterns', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Get Configurator Patterns'
                ]
            ]);
        }
        return response($response, [
            'data' => $jsonResponse, 'status' => $serverStatusCode
        ]);
    }

    /**
	 * GET: Get single Configurator pattern image and other details
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 *
	 * @author divya@imprintnext.com
	 * @date   22nd March 2024
	 * @return json response wheather data is saved or any error occured
	 */
    public function _getSingleConfigPattern($request, $args) {
        $jsonResponse = ['status' => 0, 'message' => message('ConfiguratorPatterns', 'not_found')];
        $getStoreDetails = get_store_details($request);
        $storeId = $getStoreDetails['store_id'];

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

        $configPatternInit = new ConfiguratorPattern();
        $getConfigPattern = $configPatternInit->where('xe_id', '>', 0)->where('store_id', '=', $storeId);

        $getConfigPattern->where('xe_id', $patternId)
            ->select('xe_id', 'name', 'price', 'file_name', 'store_id', 'cloud_storage');

        if ($getConfigPattern->count() > 0) {
            $getPatternData = $getConfigPattern->first()->toArray();
            if ($getPatternData['cloud_storage'] == 1) {
                $fileName =  $this->getS3URL($getPatternData['file_name'], $storeId);
                $getPatternData['file_name'] = $fileName;
            }
        }

        $getPatternData['categories'] = $this->getCategoriesById('ConfiguratorPatterns', 'ConfiguratorPatternCategoryRelationship', 'config_pattern_id', $patternId);

        $jsonResponse = [
            'status' => 1,
            'records' => 1,
            'data' => [$getPatternData]
        ];

        return $jsonResponse;

    }

     /**
	 * PUT: Update a single configurator pattern data
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author divya@imprintnext.com
	 * @date   21th March 2024
	 * @return json response wheather data is updated or not
	 */

    public function updateConfigPattern($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = ['status' => 0, 'message' => message('ConfiguratorPatterns', 'error')];
        try {
            $getStoreDetails = get_store_details($request);
            $storeId = $getStoreDetails['store_id'];
            $allPostPutVars = $updateData = $request->getParsedBody();
            $categoryIds = (isset($allPostPutVars['categories']) && $allPostPutVars['categories'] != "") ? $allPostPutVars['categories'] : NULL;
            $patternId = to_int($args['id']);

            if ($patternId) {
                $configPatternInit = new ConfiguratorPattern();
                $findPatternData = $configPatternInit->where('xe_id', $patternId);
                if (!$findPatternData->count()) {
                    throw new \Exception('Configurator pattern not found');
                }
                //getting old category details
                $getOldPatternData = $findPatternData->first()->toArray();
                $oldCategoryArr = explode(",", $getOldPatternData['category_id']);
                $newCategory = str_replace(array('\'', '"', '[', ']', '<', '>'), ' ', $categoryIds);
                $newCategoryArr = explode(",", $newCategory);
                $result = array_diff($oldCategoryArr, $newCategoryArr);
                //updating new category details
                foreach ($result as $res) {
                    $patternDataCount = new PatternCategoryRelation();
                    $countData = $patternDataCount->where('category_id', '=', $res)->get()->toArray();
                    $paternCategory = new PatternCategory();
                    if (count($countData) == 1) {
                        $flagList = ['asset_available_flag' => 0];
                        $paternCategory->where('xe_id', '=', $res)->update($flagList);
                    } else {
                        $flagList = ['asset_available_flag' => 1];
                        $paternCategory->where('xe_id', '=', $res)->update($flagList);
                    }
                }
                $updateData = [
                    'store_id' => $storeId,
                    'name' => $allPostPutVars['name'],
                    'price' => $allPostPutVars['price']
                ];
                if ($request->getUploadedFiles()) {
                    //Deletion of old file
                    $this->deleteOldFile('configurator_pattern', 'file_name', ['xe_id' => $patternId],  path('abs', 'configurator_pattern'));
                    $getUploadedFileName = do_upload('config_pattern', path('abs', 'configurator_pattern'), [100], 'string');
                    if (!empty($getUploadedFileName)) {
                        $updateData['file_name'] = $getUploadedFileName;
                    }

                    //S3 implemnetation
                    if ($getOldPatternData['cloud_storage'] == 1) {
                        if ($getOldPatternData['cloud_storage']) {
                            $this->deleteS3File($getOldPatternData['file_name'], $storeId); // delete old file from cloud
                        }
                        $updateData['cloud_storage'] = 1;
                        // upload new file to the s3
                        $fileToUpload = path('abs', 'configurator_pattern') . $getUploadedFileName;
                        $this->uploadFileToS3("vector", $fileToUpload, $storeId);
                    }
                }
                $configPatternInit = new ConfiguratorPattern();
                $configPatternInit->where('xe_id', '=', $patternId)->update($updateData);

                $jsonResponse = ['status' => 1, 'message' => message('ConfiguratorPatterns', 'updated')];

                //Category relationship updated
                if ($categoryIds) {
                    $this->savePatternCategories($patternId, $categoryIds);
                }
            }
        } catch (\Exception $e) {
            $serverStatusCode = EXCEPTION_OCCURED;
            create_log('ConfiguratorPatterns', 'error', [
                'message' => $e->getMessage(),
                'extra' => ['module' => 'Updating a clipart']
            ]);
        }

        // Flush config pattern memcached
        $this->memcache('deleteMulti', '', '', 'config_pattern');
        
        return response($response, [
            'data' => $jsonResponse, 'status' => $serverStatusCode
        ]);
    }

      /**
	 * DELETE: Delete a single/multiple configurator pattern and its categories
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author divya@imprintnext.com
	 * @date   22nd March 2024
	 * @return json response wheather data is updated or not
	 */

     public function deleteConfigPattern($request, $response, $args) {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = ['status' => 0, 'message' => message('ConfiguratorPatterns', 'error')];
        if (!empty($args['id'])) {
            try {
                $getStoreDetails = get_store_details($request);
                // Multiple Ids in json format
                $getDeleteIdsToArray = json_clean_decode(trim($args['id']), true);
                if (!empty($getDeleteIdsToArray)) {
                    $configPatternInit = new ConfiguratorPattern();
                    $getPatternInfo  = $configPatternInit->whereIn('xe_id', $getDeleteIdsToArray);

                    $patternDataCount = $getPatternInfo->count();
                    if (!$patternDataCount) {
                        throw new \Exception('Clipart not found'); # error when no clipart found
                    }
                    $success = 0;
                    $getPatterns  = $getPatternInfo->select('*')->get()->toArray();
                    foreach ($getPatterns as $patternVal) {
                        $categoryIdArr = explode(",", $patternVal['category_id']);
                        foreach ($categoryIdArr as $catId) {
                            $patternDataRel = new PatternCategoryRelation();
                            $countData = $patternDataRel->where('category_id', '=', $catId)->get()->toArray();
                            $paternCategory = new PatternCategory();
                            if (count($countData) == 1) {
                                $flagList = ['asset_available_flag' => 0];
                                $paternCategory->where('xe_id', '=', $catId)->update($flagList);
                            } else {
                                $flagList = ['asset_available_flag' => 1];
                                $paternCategory->where('xe_id', '=', $catId)->update($flagList);
                            }
                        }
                        // delete file from s3 (if enabled in the admin)
                        if ($patternVal['cloud_storage'] == 1) {
                            $this->deleteS3File($patternVal['file_name'], $getStoreDetails['store_id']);
                        }
                        // delete file from the server
                        $this->deleteOldFile('configurator_pattern', 'file_name', ['xe_id' => $patternVal['xe_id']], path('abs', 'configurator_pattern'), false);
                        $patternDataRel->where('config_pattern_id', $patternVal['xe_id'])->delete();
                        // delete the record
                        $configPatternInit->where('xe_id', $patternVal['xe_id'])->delete();
                        $success++;
                    }
                    if ($success) {
                        $totalCount = count($getDeleteIdsToArray);
                        $jsonResponse = [
                            'status' => 1,
                            'message' => $success . ' out of ' . $totalCount . ' Configurator pattern(s) deleted successfully',
                        ];
                    }
                }
            } catch (\Exception $e) {
                $serverStatusCode = EXCEPTION_OCCURED;
                create_log('ConfiguratorPatterns', 'error', [
                    'message' => $e->getMessage(),
                    'extra' => ['module' => 'Deleting a configurator pattern']
                ]);
            }
        }

        // Flush config pattern memcached
        $this->memcache('deleteMulti', '', '', 'config_pattern');

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

    /**
	 * Delete a category from the table
	 *
	 * @param $request  Slim's Request object
	 * @param $response Slim's Response object
	 * @param $args     Slim's Argument parameters
	 *
	 * @author divya@imprintnext.com
	 * @date   22nd March 2024
	 * @return Delete Json Status
	 */
	public function deleteCategory($request, $response, $args) {
		$serverStatusCode = OPERATION_OKAY;
		$jsonResponse = ['status' => 0,'message' => message('Category', 'error')];
		try{
			$getStoreDetails = get_store_details($request);
        	$storeId = $getStoreDetails['store_id'];
			if (!empty($args)) {
				$categoryId = $args['id'];
				$jsonResponse = $this->deleteCat(
					$storeId,'configurator-patterns', $categoryId, 'ConfiguratorPatterns', 'ConfiguratorPatternCategoryRelationship'
				);
			}
		} catch(\Exception $e){
			$jsonResponse['message'] = $e->getMessage();
		}

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