<?php

/**
 * Manage Fonts
 *
 * PHP version 5.6
 *
 * @category  Fonts
 * @package   Assets
 * @author    Satyabrata <satyabratap@riaxe.com>
 * @copyright 2019-2020 Riaxe Systems
 * @license   http://www.php.net/license/3_0.txt  PHP License 3.0
 * @link      http://inkxe-v10.inkxe.io/xetool/admin
 */

namespace App\Modules\Fonts\Controllers;

use App\Components\Controllers\Component as ParentController;
use App\Dependencies\FontMeta as FontMeta;
use App\Modules\Fonts\Models\Font;
use App\Modules\Fonts\Models\FontStyle;
use App\Modules\Fonts\Models\FontCategory as Category;
use App\Modules\Fonts\Models\FontCategoryRelation;
use App\Modules\Fonts\Models\FontTagRelation;
use Illuminate\Database\Capsule\Manager as DB;
use App\Modules\PrintProfiles\Models as PrintProfileModels;
use App\Modules\PrintProfiles\Models\PrintProfileAssetsCategoryRel;

/**
 * Fonts Controller
 *
 * @category Fonts
 * @package  Assets
 * @author   Satyabrata <satyabratap@riaxe.com>
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @link     http://inkxe-v10.inkxe.io/xetool/admin
 */
class FontController extends ParentController
{
    /**
     * POST: Save Font
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     *
     * @author satyabratap@riaxe.com
     * @date   23 oct 2019
     * @modified by lawren@imprintnext.com
     * @return json response wheather data is saved or any error occured
     */
    public function saveFonts($request, $response)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Font', 'error')
        ];
        try {
            $allPostPutVars = $request->getParsedBody();
            $getStoreDetails = get_store_details($request);

            $getFontNames = [];
            if (count(array_keys($_FILES)) == 1 && array_key_first($_FILES) == 'upload') {
                $getFontNames = do_upload('upload', path('abs', 'font'), [150], 'array');
                if (!empty($getFontNames)) {
                    $uploadingFilesNo = count($getFontNames); // number of uploaded files
                    $success = 0; // number of success records
                    foreach ($getFontNames as $font) {
                        // get font detail from the dependency
                        $fontFullPath = path('abs', 'font') . '/' . $font;
                        $ttfInfo = new FontMeta();
                        $ttfInfo->setFontFile($fontFullPath);
                        $getFontInfo = $ttfInfo->getFontInfo();

                        $saveRecords = [
                            'store_id' => $getStoreDetails['store_id'],
                            'name' => $allPostPutVars['name'],
                            'price' => to_decimal($allPostPutVars['price']),
                            'file_name' => $font,
                            'cloud_storage' => 0,
                            'font_family' => $getFontInfo[1]
                        ];

                        // upload to cloud if enabled
                        $isS3Enabled = $this->checkS3Settings($getStoreDetails['store_id']);
                        if ($isS3Enabled) {
                            $fileToUpload = path('abs', 'font') . $font;
                            $this->uploadFileToS3("font", $fileToUpload, $getStoreDetails['store_id']);
                            $saveRecords['cloud_storage'] = 1;
                        }

                        $fontInit = new Font($saveRecords);
                        if ($fontInit->save()) {
                            $fontId = $fontInit->xe_id;
                            /**
                             * Save category and subcategory data
                             * Category id format: [4,78,3]
                             */
                            if (
                                isset($allPostPutVars['categories'])
                                && $allPostPutVars['categories'] != ""
                            ) {
                                $categoryIds = $allPostPutVars['categories'];
                                $this->_saveFontCategories($fontId, $categoryIds);
                            }
                            /**
                             * Save tags
                             * Tag Names format : tag1,tag2,tag3
                             */
                            $tags = !empty($allPostPutVars['tags']) ? $allPostPutVars['tags'] : "";
                            $this->saveFontTags($getStoreDetails['store_id'], $fontId, $tags);
                            $success++;
                        }
                        //Clear font Cache
                        $this->updateAssetCache($getStoreDetails['store_id'], $fontId, $allPostPutVars, 'font');

                        $this->memcache('deleteMulti', '', '', "fonts_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, 'fonts', $request, $response);
                            }
                        }
                    }
                    if (!empty($success)) {
                        $jsonResponse = [
                            'status' => 1,
                            'message' => $success . ' out of ' . $uploadingFilesNo
                                . ' Font(s) uploaded successfully',
                        ];
                    }
                    // Flush font memcached
                    $this->memcache('deleteMulti', '', '', 'font');
                    return response($response, [
                        'data' => $jsonResponse,
                        'status' => $serverStatusCode
                    ]);
                }
            }
            foreach ($_FILES as $key => $value) {
                if ($key == 'upload') {
                    $getFontNames += [$key => do_upload($key, path('abs', 'font'), [150], 'array')[0]];
                    continue;
                }
                if (!$_FILES[$key]['error']) {
                    // upload the file to the server
                    $getFontNames += [$key => do_upload($key, path('abs', 'font'), [150], 'string')];
                }
            }
            $fontId = 0;
            if (!empty($getFontNames)) {
                $uploadingFilesNo = count($getFontNames); // number of uploaded files
                $success = 0; // number of success records
                foreach ($getFontNames as $key => $font) {
                    // get font detail from the dependency
                    $fontFullPath = path('abs', 'font') . '/' . $font;
                    $ttfInfo = new FontMeta();
                    $ttfInfo->setFontFile($fontFullPath);
                    $getFontInfo = $ttfInfo->getFontInfo();

                    // upload to cloud if enabled
                    $cloud_storage = 0;
                    $isS3Enabled = $this->checkS3Settings($getStoreDetails['store_id']);
                    if ($isS3Enabled) {
                        $fileToUpload = path('abs', 'font') . $font;
                        $this->uploadFileToS3("font", $fileToUpload, $getStoreDetails['store_id']);
                        $cloud_storage = 1;
                    }

                    if ($key == 'upload') {
                        $saveRecords = [
                            'store_id' => $getStoreDetails['store_id'],
                            'name' => $allPostPutVars['name'],
                            'price' => to_decimal($allPostPutVars['price']),
                            'file_name' => $font,
                            'cloud_storage' => $cloud_storage,
                            'font_family' => $getFontInfo[1]
                        ];

                        $fontInit = new Font($saveRecords);
                        if ($fontInit->save()) {
                            $fontId = $fontInit->xe_id;
                            /**
                             * Save category and subcategory data
                             * Category id format: [4,78,3]
                             */
                            if (
                                isset($allPostPutVars['categories'])
                                && $allPostPutVars['categories'] != ""
                            ) {
                                $categoryIds = $allPostPutVars['categories'];
                                $this->_saveFontCategories($fontId, $categoryIds);
                            }
                            /**
                             * Save tags
                             * Tag Names format : tag1,tag2,tag3
                             */
                            $tags = !empty($allPostPutVars['tags']) ? $allPostPutVars['tags'] : "";
                            $this->saveFontTags($getStoreDetails['store_id'], $fontId, $tags);
                            $success++;
                        }
                        //Clear font Cache
                        $this->updateAssetCache($getStoreDetails['store_id'], $fontId, $allPostPutVars, 'font');

                        $this->memcache('deleteMulti', '', '', "fonts_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, 'fonts', $request, $response);
                            }
                        }
                    } else {
                        $fontStyleInit = new FontStyle();
                        $fontStyleInit->style = $key;
                        $fontStyleInit->file_name = $font;
                        $fontStyleInit->font_family = $getFontInfo[4];
                        $fontStyleInit->font_id = $fontId;
                        if ($fontStyleInit->save()) {
                            $success++;
                        }
                    }
                }
                if (!empty($success)) {
                    $jsonResponse = [
                        'status' => 1,
                        'message' => $success . ' out of ' . $uploadingFilesNo
                            . ' Font(s) uploaded successfully',
                    ];
                }
            }
        } catch (\Exception $e) {
            // Store exception in logs
            create_log('Assets', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Fonts'
                ]
            ]);
        }
        // Flush font memcached
        $this->memcache('deleteMulti', '', '', 'font');
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }

    /**
     * Save categories w.r.t font
     *
     * @param $fontId      Font ID
     * @param $categoryIds (in  an array with comma separated)
     *
     * @author satyabratap@riaxe.com
     * @date   4th Nov 2019
     * @return boolean
     */
    private function _saveFontCategories($fontId, $categoryIds)
    {
        $getAllCategoryArr = json_clean_decode($categoryIds, true);
        foreach ($getAllCategoryArr as $catId) {
            $shapeCat = new Category();
            $categoriesData = $shapeCat->where('xe_id', '=', $catId)->get()->toArray();
            if ($catId == $categoriesData[0]['xe_id']) {
                $flagList = ['asset_available_flag' => 1];
                $shapeCat->where('xe_id', '=', $catId)->update($flagList);
            }
        }
        // SYNC Categories to the Font_Category Relationship Table
        $fontsInit = new Font();
        $findFont = $fontsInit->find($fontId);
        if ($findFont->categories()->sync($getAllCategoryArr)) {
            return true;
        }
        return false;
    }

    /**
     * Save tags w.r.t font
     *
     * @param $storeId Store ID
     * @param $fontId  Font ID
     * @param $tags    Multiple Tags
     *
     * @author satyabratap@riaxe.com
     * @date   4th Nov 2019
     * @return boolean
     */
    protected function saveFontTags($storeId, $fontId, $tags)
    {
        // Save Font and tags relation
        if (!empty($tags)) {
            $getTagIds = $this->saveTags($storeId, $tags);
            // SYNC Tags into Relationship Table
            $fontsInit = new Font();
            $findFont = $fontsInit->find($fontId);
            if ($findFont->tags()->sync($getTagIds)) {
                return true;
            }
        } else {
            // Clean relation in case no tags supplied
            $tagRelInit = new FontTagRelation();
            $fontTags = $tagRelInit->where('font_id', $fontId);
            if ($fontTags->delete()) {
                return true;
            }
        }
        return false;
    }

    /**
     * GET: Single font
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author dan@imprintnext.com
     * @date   13 July 2022
     * @modified by lawren@imprintnext.com
     * @return Single Fonts List
     */
    public function getSingleFont($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 1,
            'data' => [],
            'message' => message('Font', 'not_found')
        ];
        try {
            // get the store id
            $storeId = $request->getQueryParam('store_id');
            if (empty($storeId)) {
                $getStoreDetails = get_store_details($request);
                $storeId = $getStoreDetails['store_id'];
            }
            if (!empty($args['id'])) {
                $fontId = to_int($args['id']);

                // get the font detail
                $fontsInit = (new Font());
                $getFonts = $fontsInit->with('font_styles')->select([
                    'xe_id',
                    'name',
                    'price',
                    'font_family',
                    'file_name',
                    'cloud_storage'
                ])->where([
                    ['xe_id', '=', $fontId],
                    ['store_id', '=', $storeId]
                ])->orderBy('xe_id', 'DESC');

                // remove the unused appends and get the data
                $fontsData = $getFonts->first()->setAppends([])->toArray();
                foreach ($fontsData['font_styles'] as &$font_style) {
                    $font_type_id = ['font_type_id' => $font_style['xe_id']];
                    unset($font_style['xe_id']);
                    $font_type_id += $font_style;
                    $font_style = $font_type_id;
                }
                unset($font_style);

                // get the file from the cloud
                if ($fontsData['cloud_storage'] == 1) {
                    $fontsData['file_name'] =  $this->getS3URL($fontsData['file_name'], $storeId);
                    if (!empty($fontsData['font_styles'])) {
                        foreach ($fontsData['font_styles'] as $font_style) {
                            $font_style['file_name'] = $this->getS3URL($font_style['file_name'], $storeId);
                        }
                    }
                }
                // Get Category Ids
                $getCategories = $this->getCategoriesById(
                    'Fonts',
                    'FontCategoryRelation',
                    'font_id',
                    $args['id']
                );
                $fontsData['categories'] = !empty($getCategories) ? $getCategories : [];

                // Get Tag names
                $getTags = $this->getTagsById(
                    'Fonts',
                    'FontTagRelation',
                    'font_id',
                    $args['id']
                );
                $fontsData['tags'] = !empty($getTags) ? $getTags : [];

                $jsonResponse = [
                    'status' => 1,
                    'records' => 1,
                    'data' => [$fontsData]
                ];
            }
        } catch (\Exception $e) {
            // Store exception in logs
            create_log('Assets', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Fonts'
                ]
            ]);
        }

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

    /**
     * GET: List of fonts
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author satyabratap@riaxe.com
     * @date   23 oct 2019
     * @modified by lawren@imprintnext.com
     * @return All/Single Fonts List
     */
    public function getFonts($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 1,
            'data' => [],
            'message' => message('Font', 'not_found')
        ];

        // Collect all Filter columns from url
        $printProfileKey = $request->getQueryParam('print_profile_id');
        $page = $request->getQueryParam('page');
        $perpage = $request->getQueryParam('perpage');
        $order = $request->getQueryParam('order');
        $name = $request->getQueryParam('name');
        // get the store id
        $storeId = $request->getQueryParam('store_id');
        if (empty($storeId)) {
            $getStoreDetails = get_store_details($request);
            $storeId = $getStoreDetails['store_id'];
        }
        $cacheCond = !empty($printProfileKey) && $page <= 2 && $name == '';
        $assetCacheData = $cacheCond ? $this->getAssetCache($storeId, $printProfileKey, $page, $perpage, 'font') : [];

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

        if (!empty($memcacheData)) {
            $jsonResponse = $memcacheData;
            if (MEM_MODE) {
                $jsonResponse['mode'] = 'memcache';
            }
        } elseif (!empty($assetCacheData)) {
            $jsonResponse = [
                'status' => 1,
                'total_records' => $assetCacheData['total_records'],
                'records' => count($assetCacheData['data']),
                'data' => $assetCacheData['data']
            ];
        } else {
            $fontsInit = new Font();
            $getFonts = $fontsInit->with('font_styles')->where('xe_id', '>', 0)->where('store_id', '=', $storeId);
            // proceed if record exists
            if ($getFonts->exists()) {
                // Collect all Filter columns from url
                $sortBy = $request->getQueryParam('sortby');
                $categoryIds = !empty($request->getQueryParam('category')) ?
                    json_clean_decode($request->getQueryParam('category'), true) : [];

                // For multiple Font data
                $getFonts->select([
                    'xe_id',
                    'name',
                    'price',
                    'font_family',
                    'file_name',
                    'cloud_storage',
                ]);

                // Searching as per name, tag name
                if (!empty($name)) {
                    $getFonts = $getFonts->where(function ($query) use ($name) {
                        $query->where('name', 'LIKE', '%' . $name . '%')
                            ->orWhereExists(function ($q) use ($name) {
                                $q->select(DB::raw(1))->from('font_tag_rel as ftr')->join('tags as tg', 'ftr.tag_id', '=', 'tg.xe_id')
                                    ->whereRaw('ftr.font_id = fonts.xe_id')
                                    ->where('tg.name', '=', $name);
                            });
                    });
                }
                // Filter By Print Profile's asset category Id
                if (!empty($printProfileKey)) {
                    $assetTypeArr = $this->assetsTypeId('fonts');
                    // get the asset category from print profile
                    $profileCatRelObj = new \App\Modules\PrintProfiles\Models\PrintProfileAssetsCategoryRel();
                    $profileCatRelDetails = $profileCatRelObj->where([
                        ['asset_type_id', '=', $assetTypeArr['asset_type_id']],
                        ['print_profile_id', '=', $printProfileKey]
                    ])->select('category_id');

                    // merge profile categories with filter category_ids
                    if ($profileCatRelDetails->exists()) {
                        $profileCatIds = $profileCatRelDetails->get()->pluck('category_id')->toArray();
                        $categoryIds = array_merge($categoryIds, $profileCatIds);
                    }
                }
                // apply filter for category ids
                if ($categoryIds) {
                    $getFonts->whereHas('fontCategory', function ($q) use ($categoryIds) {
                        return $q->whereIn('category_id', $categoryIds);
                    });
                }
                // Total records including all filters
                $getTotalPerFilters = $getFonts->count();

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

                // Sorting by column name and sord order parameter
                if (!empty($sortBy) && !empty($order)) {
                    $getFonts->orderBy($sortBy, $order);
                }

                $fontsData = $getFonts->orderBy('xe_id', 'DESC')->get()->toArray();

                foreach ($fontsData as &$font) {
                    foreach ($font['font_styles'] as &$value) {
                        $font_type_id = ['font_type_id' => $value['xe_id']];
                        unset($value['xe_id']);
                        $font_type_id += $value;
                        $value = $font_type_id;
                    }
                    unset($value);
                }
                unset($font);

                // file should come from the cloud if 'cloud_storage' flag is turned on
                foreach ($fontsData as $fontKey => $value) {
                    if ($storeId > 1) {
                        $hostname = parse_url($value['file_name'], PHP_URL_HOST); // hostname
                        $fontsData[$fontKey]['file_name'] = str_replace($hostname, $currentStoreUrl, $value['file_name']);
                    }
                    if ($value['cloud_storage'] == 1) {
                        $fontsData[$fontKey]['file_name'] = $this->getS3URL($value['file_name'], $storeId);
                        if (!empty($value['font_styles'])) {
                            foreach ($value['font_styles'] as $styleKey => $style) {
                                $fontsData[$fontKey]['font_styles'][$styleKey]['file_name'] = $this->getS3URL($style['file_name'], $storeId);
                            }
                        }
                    }
                }

                $jsonResponse = [
                    'status' => 1,
                    'records' => count($fontsData),
                    'total_records' => $getTotalPerFilters,
                    'data' => $fontsData
                ];
                if ($cacheCond) {
                    $assetData = $page == 1 ?
                        [
                            'total_records' => $getTotalPerFilters,
                            'data' => $fontsData
                        ] : $fontsData;
                    $this->createAssetCache('font', $storeId, $printProfileKey, $assetData, $page);
                }
                //SET IN MEMCACHED
                if (isset($thisCacheKey)) {
                    $this->memcache("set", $thisCacheKey, $jsonResponse);
                }
            }
        }
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }

    /**
     * PUT: Update a single font
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author satyabratap@riaxe.com
     * @date   23 oct 2019
     * @modified by lawren@imprintnext.com
     * @return json response wheather data is updated or not
     */
    public function updateFont($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Category', 'error')
        ];
        try {
            $allPostPutVars = $updateData = $request->getParsedBody();
            $getStoreDetails = get_store_details($request);
            if (!empty($args['id'])) {
                $fontsInit = new Font();
                $getOldFont = $fontsInit->where('xe_id', '=', $args['id'])->get()->toArray();
                $oldCategoryArr = explode(",", $getOldFont[0]['category_id']);
                $newCategory = str_replace(array('\'', '"', '[', ']', '<', '>'), ' ', $allPostPutVars['categories']);
                $newCategoryArr = explode(",", $newCategory);
                $result = array_diff($oldCategoryArr, $newCategoryArr);
                foreach ($result as $res) {
                    $fontCount = new FontCategoryRelation();
                    $countData = $fontCount->where('category_id', '=', $res)->get()->toArray();
                    $newCategory = new Category();
                    if (count($countData) == 1) {
                        $flagList = ['asset_available_flag' => 0];
                        $newCategory->where('xe_id', '=', $res)->update($flagList);
                    } else {
                        $flagList = ['asset_available_flag' => 1];
                        $newCategory->where('xe_id', '=', $res)->update($flagList);
                    }
                }
                if (!empty($getOldFont)) {
                    unset(
                        $updateData['id'],
                        $updateData['tags'],
                        $updateData['categories'],
                        $updateData['upload'],
                        $updateData['fontId'],
                        $updateData['bold'],
                        $updateData['italic'],
                        $updateData['bold-italic'],
                        $updateData['bold_id'],
                        $updateData['italic_id'],
                        $updateData['bold-italic_id'],
                        $updateData['delete_font_styles'],
                    );
                    if ($request->getUploadedFiles()) {
                        $uploaded_font_files = [];
                        foreach ($request->getUploadedFiles() as $key => $file) {
                            if ($key == 'upload') {
                                // replace old file with new upload
                                $this->deleteOldFile(
                                    "fonts",
                                    "file_name",
                                    ['xe_id' => $args['id']],
                                    path('abs', 'font')
                                );
                                $getUploadedFileName = do_upload('upload', path('abs', 'font'), [150], 'string');
                                if (!empty($getUploadedFileName)) {
                                    $updateData['file_name'] =  $getUploadedFileName;
                                }

                                // replace the old file with new in the cloud if enabled
                                if ($getOldFont['cloud_storage'] == 1) {
                                    // delete the file from the cloud
                                    $this->deleteS3File($getOldFont->file_name, $getStoreDetails['store_id']);
                                    $fileToUpload = path('abs', 'font') . $getUploadedFileName;

                                    // upload the new file to the cloud
                                    $this->uploadFileToS3("font", $fileToUpload, $getStoreDetails['store_id']);
                                }
                            } else {
                                $uploaded_font_files += [$key => do_upload($key, path('abs', 'font'), [150], 'string')];
                            }
                        }
                    }
                    // Update record
                    $fontsInit->where('xe_id', '=', $args['id'])->update($updateData);

                    if (!empty($uploaded_font_files)) {
                        $modified_styles = [];
                        foreach ($uploaded_font_files as $key => $file) {
                            $modified_styles += [$allPostPutVars[$key . '_id'] ?? $key => [$key => $file]];
                        }
                        // Update font styles
                        foreach ($modified_styles as $key => $style) {
                            if (preg_match('/^[1-9]\d*$/', $key)) {
                                // remove the old file
                                $this->deleteOldFile(
                                    "font_styles",
                                    "file_name",
                                    ['xe_id' => $key],
                                    path('abs', 'font')
                                );
                                $style_data = ['style' => array_key_first($style), 'file_name' => $style[array_key_first($style)]];
                                $font_style_init = new FontStyle();
                                $font_style = $font_style_init->where('xe_id', '=', $key)->first();

                                // replace the old file with new in the cloud if enabled
                                if ($getOldFont['cloud_storage'] == 1) {
                                    // delete the file from the cloud
                                    $this->deleteS3File($font_style->file_name, $getStoreDetails['store_id']);
                                    $fileToUpload = path('abs', 'font') . $style[array_key_first($style)];

                                    // upload the new file to the cloud
                                    $this->uploadFileToS3("font", $fileToUpload, $getStoreDetails['store_id']);
                                }

                                // get font detail from the dependency
                                $fontFullPath = path('abs', 'font') . '/' . $style_data['file_name'];
                                $ttfInfo = new FontMeta();
                                $ttfInfo->setFontFile($fontFullPath);
                                $getFontInfo = $ttfInfo->getFontInfo();

                                $font_style->style = $style_data['style'];
                                $font_style->file_name = $style_data['file_name'];
                                $font_style->font_family = $getFontInfo[4];
                                $font_style->save();
                            } else {
                                // Upload to cloud if enabled
                                if ($getOldFont['cloud_storage'] == 1) {
                                    $fileToUpload = path('abs', 'font') . $style[array_key_first($style)];
                                    // upload the new file to the cloud
                                    $this->uploadFileToS3("font", $fileToUpload, $getStoreDetails['store_id']);
                                }
                                $style_data = ['style' => array_key_first($style), 'file_name' => $style[array_key_first($style)]];

                                // get font detail from the dependency
                                $fontFullPath = path('abs', 'font') . '/' . $style_data['file_name'];
                                $ttfInfo = new FontMeta();
                                $ttfInfo->setFontFile($fontFullPath);
                                $getFontInfo = $ttfInfo->getFontInfo();

                                $font_style_init = new FontStyle();
                                $font_style_init->font_id = $args['id'];
                                $font_style_init->style = $style_data['style'];
                                $font_style_init->file_name = $style_data['file_name'];
                                $font_style_init->font_family = $getFontInfo[4];
                                $font_style_init->save();
                            }
                        }
                    }
                    $styles = [];
                    foreach ($allPostPutVars as $style => $id) {
                        if (preg_match('/_id$/', $style) && $style != 'store_id') {
                            $styles += [$id => substr($style, 0, strpos($style, '_id'))];
                        }
                    }
                    if (!empty($styles)) {
                        foreach ($styles as $key => $value) {
                            $font_style_init = new FontStyle();
                            $font_style = $font_style_init->where('xe_id', '=', $key)->first();
                            $font_style->style = $value;
                            $font_style->save();
                        }
                    }

                    // Delete font styles
                    if (isset($allPostPutVars['delete_font_styles'])) {
                        $delete_style_ids = explode(',', str_replace(array('[', ']'), '', $allPostPutVars['delete_font_styles']));
                        foreach ($delete_style_ids as $style_id) {
                            // Delete files from server
                            $this->deleteOldFile(
                                "font_styles",
                                "file_name",
                                ['xe_id' => $style_id],
                                path('abs', 'font'),
                                false
                            );
                            // Delete file in the cloud if enabled
                            if ($getOldFont['cloud_storage'] == 1) {
                                $font_style_init = new FontStyle();
                                $font_style = $font_style_init->where('xe_id', '=', $style_id)->get()->toArray();
                                // delete the file from the cloud
                                $this->deleteS3File($font_style->file_name, $getStoreDetails['store_id']);
                            }
                        }
                        $font_style_init = new FontStyle();
                        $font_style_init->whereIn('xe_id', $delete_style_ids)->delete();
                    }

                    /**
                     * Save category
                     * Parameter: categories
                     */
                    if (!empty($allPostPutVars['categories'])) {
                        $categoryIds = $allPostPutVars['categories'];
                        // Save Categories
                        $this->_saveFontCategories($args['id'], $categoryIds);
                    }
                    /**
                     * Save tags
                     * Tag Names format : tag1,tag2,tag3
                     */
                    $tags = !empty($allPostPutVars['tags']) ? $allPostPutVars['tags'] : "";
                    $this->saveFontTags($getStoreDetails['store_id'], $args['id'], $tags);
                    //Clear fonts cache
                    $this->updateAssetCache($getStoreDetails['store_id'], $updateData['fontId'], $allPostPutVars, 'font');

                    $this->memcache('deleteMulti', '', '', "fonts_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, 'fonts', $request, $response);
                        }
                    }
                    $jsonResponse = [
                        'status' => 1,
                        'message' => message('Font', 'updated')
                    ];
                }
            }
        } catch (\Exception $e) {
            // Store exception in logs
            create_log('Assets', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Fonts'
                ]
            ]);
        }
        // Flush font memcached
        $this->memcache('deleteMulti', '', '', 'font');
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }

    /**
     * DELETE: Delete single/multiple font
     *
     * @param $request  Slim's Argument parameters
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author satyabratap@riaxe.com
     * @date   23 oct 2019
     * @modified by lawren@imprintnext.com
     * @return json response wheather data is deleted or not
     */
    public function deleteFont($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Font', 'error'),
        ];
        try {
            $getDeleteIdsToArray = !empty($args['id']) ? json_clean_decode($args['id'], true) : null;
            if ($getDeleteIdsToArray) {
                $getStoreDetails = get_store_details($request);
                $storeId = $getStoreDetails['store_id'];
                $fontsInit = new Font();
                $getFontDetails = $fontsInit->with('font_styles')->whereIn('xe_id', $getDeleteIdsToArray);
                $totalCount = $getFontDetails->count();
                if ($totalCount > 0) {
                    // Fetch Font details
                    $getFontDetails = $getFontDetails->get()->toArray();
                    $success = 0;
                    foreach ($getFontDetails as $fontFile) {
                        $categoryIdArr = explode(",", $fontFile['category_id']);
                        foreach ($categoryIdArr as $fontCatId) {
                            $fontCount = new FontCategoryRelation();
                            $countData = $fontCount->where('category_id', '=', $fontCatId)->get()->toArray();
                            $newCategory = new Category();
                            if (count($countData) == 1) {
                                $flagList = ['asset_available_flag' => 0];
                                $newCategory->where('xe_id', '=', $fontCatId)->update($flagList);
                            } else {
                                $flagList = ['asset_available_flag' => 1];
                                $newCategory->where('xe_id', '=', $fontCatId)->update($flagList);
                            }
                        }
                        if ($fontFile['cloud_storage'] == 1) {
                            $file = $fontFile['file_name'];
                            $this->deleteS3File($file, $storeId);
                            if (!empty($fontFile['font_styles'])) {
                                foreach ($fontFile['font_styles'] as $style) {
                                    $this->deleteS3File($style['file_name'], $storeId);
                                }
                            }
                        }
                        $this->deleteOldFile(
                            "fonts",
                            "file_name",
                            ['xe_id' => $fontFile['xe_id']],
                            path('abs', 'font'),
                            false
                        ); // false = skip check new upload
                        // Delete Corresponding font style files
                        $this->deleteOldFile(
                            "font_styles",
                            "file_name",
                            ['font_id' => $fontFile['xe_id']],
                            path('abs', 'font'),
                            false
                        );
                        $fontDelInit = new Font();
                        $font = $fontDelInit->find($fontFile['xe_id']);
                        $font->font_styles()->delete();
                        $fontCount->where('font_id', $fontFile['xe_id'])->delete();
                        $fontDelInit->where('xe_id', $fontFile['xe_id'])->delete();
                        $success++;
                    }
                    //Clear fonts cache
                    $this->updateAssetCache($storeId, $getDeleteIdsToArray, $categoryIdArr, 'font');

                    $this->memcache('deleteMulti', '', '', "fonts_cat");
                    if (!empty($categoryIdArr)) {
                        foreach ($categoryIdArr as $categoryId) {
                            $ppAssetCatRelGtInit = new PrintProfileModels\PrintProfileAssetsCategoryRel();
                            $printProfileIds = $ppAssetCatRelGtInit->where('category_id', $categoryId)->pluck('print_profile_id');
                            $this->createUpdateAssetJsonCache($getStoreDetails['store_id'], $printProfileIds, 'fonts', $request, $response);
                        }
                    }
                    if ($success > 0) {
                        $jsonResponse = [
                            'status' => 1,
                            'message' => $success . ' out of ' . $totalCount
                                . ' Font(s) deleted successfully',
                        ];
                    }
                }
            }
        } catch (\Exception $e) {
            // Store exception in logs
            create_log('Assets', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Fonts'
                ]
            ]);
        }
        // Flush font memcached
        $this->memcache('deleteMulti', '', '', 'font');
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }

    /**
     * Delete a category from the table
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     * @param $args     Slim's Argument parameters
     *
     * @author satyabratap@riaxe.com
     * @date   20 Jan 2020
     * @return Delete Json Status
     */
    public function deleteCategory($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Category', 'error'),
        ];
        try {
            $getStoreDetails = get_store_details($request);
            $storeId = $getStoreDetails['store_id'];
            if (!empty($args['id'])) {
                $categoryId = $args['id'];
                $jsonResponse = $this->deleteCat(
                    $storeId,
                    'fonts',
                    $categoryId,
                    'Fonts',
                    'FontCategoryRelation'
                );
            }
            $this->memcache('deleteMulti', '', '', "fonts_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, "fonts", $request, $response);
            }
        } catch (\Exception $e) {
            // Store exception in logs
            create_log('Assets', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Fonts'
                ]
            ]);
        }
        return response($response, [
            'data' => $jsonResponse,
            'status' => $serverStatusCode
        ]);
    }

    /**
     * Get most used fonts
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     *
     * @author debashrib@riaxe.com
     * @date   30 Jan 2020
     * @return A JSON Response
     */
    public function mostUsedFonts($request, $response)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Fonts', 'error')
        ];
        try {
            $getStoreDetails = get_store_details($request);
            $page = $request->getQueryParam('page');
            $perpage = $request->getQueryParam('perpage');

            // get the font data
            $fontsInit = new Font();
            $getFonts = $fontsInit->where(['store_id' => $getStoreDetails['store_id']])
                ->select('xe_id', 'name', 'font_family', 'file_name');

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

                // get the most used first
                $fontsData = $getFonts->orderBy('total_used', 'DESC')->get();

                $jsonResponse = [
                    'status' => 1,
                    'total_records' => $totalCounts,
                    'records' => count($fontsData),
                    'data' => $fontsData
                ];
            }
        } catch (\Exception $e) {
            // Store exception in logs
            create_log('Assets', 'error', [
                'message' => $e->getMessage(),
                'extra' => [
                    'module' => 'Fonts'
                ]
            ]);
        }

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