<?php
/**
 * Manage Product Image Sides
 *
 * PHP version 5.6
 *
 * @category  Product_Image
 * @package   Product
 * @author    Tanmaya Patra <tanmayap@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\Products\Controllers;

use App\Modules\Products\Models\ProductImage;
use App\Modules\Products\Models\ProductImageSides;
use App\Modules\Products\Models\ProductSide;
use App\Modules\Products\Models\ProductImageSettingsRel;
use ProductStoreSpace\Controllers\StoreProductsController;
use App\Components\Controllers\Component as ParentController;

/**
 * Product Image Controller
 *
 * @category Product_Image
 * @package  Product
 * @author   Tanmaya Patra <tanmayap@riaxe.com>
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @link     http://inkxe-v10.inkxe.io/xetool/admin
 */
class ProductImagesController extends ParentController
{
    private $storeController = null;
    /**
     * Get the instance of the store product controller
     */
    public function getStore() {
        if (!$this->storeController) {
            $this->storeController = new StoreProductsController();
        }
        return $this->storeController;
    }

    /**
     * Get: Getting List of All Product Images
     *
     * @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
     */
    public function getProductImages($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $getStoreDetails = get_store_details($request);
        $storeId = $getStoreDetails['store_id'];
        $perpage = $request->getQueryParam('perpage');
        $page = $request->getQueryParam('page_number');
        $name = $request->getQueryParam('name');
        
        $prodImgInit = new ProductImage();
        $productImageInfo = $prodImgInit->where('xe_id', '>', 0)->select([
            "xe_id", "name", "is_disable", "cloud_storage"
        ]);
        if (!empty($storeId)) {
            $productImageInfo->where(['store_id' => $storeId]);
        }
        if (!empty($args['product_image_id'])) {
            $productImageInfo->where('xe_id', $args['product_image_id']);
        }
        if (isset($name) && $name != "") {
            $productImageInfo->where('name', 'LIKE', '%' . $name . '%');
        }
        $productImageInfo->with(['sides' => function ($q) {
            $q->orderBy('sort_order', 'ASC');
        }]);
       
        $getTotalPerFilters = $productImageInfo->count();
        if ($page != "") {
            $totalItem = empty($perpage) ? 10 : $perpage;
            $offset = $totalItem * ($page - 1);
            $productImageInfo->skip($offset)->take($totalItem);
        }
       
        $productImageList = $productImageInfo->orderBy('xe_id', 'desc')->get()->toArray();
        foreach ($productImageList as $key1 => $value) {
            if ($value['cloud_storage'] == 1) {
                foreach ($value['sides'] as $key2 => $sides) {
                    $file = $sides['file_name'];
                    $url = $this->getS3URL($file, $storeId);
                    $productImageList[$key1]['sides'][$key2]['file_name'] = $url;

                    $thumbFile = $sides['thumbnail'];
                    $thumburl = $this->getS3URL($thumbFile, $storeId);
                    $productImageList[$key1]['sides'][$key2]['thumbnail'] = $thumburl;
                }
            }
        }
        $jsonResponse = [
            'status' => 1,
            'data' => $productImageList,
            'total_count' => $getTotalPerFilters
        ];

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

    /**
     * Post: Save Product Images
     *
     * @param $request  Slim's Request object
     * @param $response Slim's Response object
     *
     * @author tanmayap@riaxe.com
     * @date   5 Oct 2019
     * @return json
     */
    public function saveProductImages($request, $response)
    {
        $serverStatusCode = OPERATION_OKAY;
        // Get Store Specific Details from helper
        $store = get_store_details($request);
        $clouStorage = 0;
        $jsonResponse = [];
        $allPostPutVars = $request->getParsedBody();
        $productSidesJson = $allPostPutVars['product_sides'];
        $productSidesArray = json_clean_decode($productSidesJson, true);
        $isS3Enabled = $this->checkS3Settings($store['store_id']);
        if ($isS3Enabled) {
            $clouStorage = 1;
        }
        // Save Product Image Details
        if (!empty($productSidesArray['name'])) {
            $productImageData = [
                'name' => $productSidesArray['name'],
                'cloud_storage' => $clouStorage,
            ];
            $productImageData['store_id'] = $store['store_id'];
            $saveProductImage = new ProductImage($productImageData);
            $saveProductImage->save();
            $productImageInsertId = $saveProductImage->xe_id;

            // Save Product Image Sides
            if (!empty($productSidesArray['sides'])) {
                foreach ($productSidesArray['sides'] as $sideData) {
                    // Start saving each sides
                    $imageUploadIndex = $sideData['image_upload_data'];
                    // If image resource was given then upload the image into
                    // the specified folder
                    $getUploadedFileName = do_upload(
                        $imageUploadIndex,
                        path('abs', 'product'),
                        [150],
                        'string'
                    );
                    // Setup data for Saving/updating
                    $productImageSides = [
                        'product_image_id' => $productImageInsertId,
                        'side_name' => !empty($sideData['side_name'])
                        ? $sideData['side_name'] : null,
                        'sort_order' => $sideData['sort_order'],
                    ];
                    // If File was choosen from frontend then only save/update
                    // the image or skip the image saving
                    if (!empty($getUploadedFileName)) {
                        $productImageSides['file_name'] = $getUploadedFileName;

                        if ($isS3Enabled) {
                            $thumbFile = path('abs', 'product') . "thumb_" . $getUploadedFileName;
                            $fileToUpload = path('abs', 'product') . $getUploadedFileName;
                            $this->uploadFileToS3("product", $thumbFile, $store['store_id']);
                            $this->uploadFileToS3("product", $fileToUpload, $store['store_id']);
                        }
                    }
                    // Insert Product Image Sides
                    $saveProductImageSide = new ProductImageSides(
                        $productImageSides
                    );
                    if ($saveProductImageSide->save()) {
                        $jsonResponse = [
                            'status' => 1,
                            'product_image_id' => $productImageInsertId,
                            'message' => message('Product Image', 'saved'),
                        ];
                    } else {
                        $jsonResponse = [
                            'status' => 0,
                            'message' => message('Product Image', 'error'),
                        ];
                    }
                }
            }
        } else {
            $jsonResponse = [
                'status' => 0,
                'message' => message('Product Image', 'insufficient'),
            ];
        }

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

    /**
     * Put: Update Product Images
     *
     * @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
     */
    public function updateProductImages($request, $response, $args)
    {
        $jsonResponse = [
            'status' => 0,
            'message' => message('Product Image Side', 'error'),
        ];
        $serverStatusCode = OPERATION_OKAY;
        $storeId = get_store_details($request);
        $cloudStorage = 0;
        $allPostPutVars = $request->getParsedBody();
        $productSidesJson = isset($allPostPutVars['product_sides'])
        ? $allPostPutVars['product_sides'] : '{}';
        $productSidesArray = json_clean_decode($productSidesJson, true);
        $productImageId = $args['product_image_id'];

        // Save Product Image Details
        $prodImgInit = new ProductImage();
        $productImageInit = $prodImgInit->where('xe_id', $productImageId);
        $isS3Enabled = $this->checkS3Settings($storeId['store_id']);
        if($isS3Enabled){
            $cloudStorage = 1;
        }
        if (!empty($productSidesArray['name']) && $productImageInit->count() > 0) {
            // Update Product Image Details
            $updateProdImage = [
                'name' => $productSidesArray['name'],
                'cloud_storage' => $cloudStorage,
                'store_id' => $storeId['store_id']
            ];
            $productImageInit->update($updateProdImage);
            $productImageInsertId = $productImageId;
            // Save Product Image Sides
            if (!empty($productSidesArray['sides'])) {
                foreach ($productSidesArray['sides'] as $sideData) {
                    $productImageSides = [];
                    $getUploadedFileName = '';
                    // Start analysing each side
                    if (!empty($sideData['image_upload_data'])) {
                        // Case #1: If New File uploading requested
                        $requestedFileKey = $sideData['image_upload_data'];
                        $getUploadedFileName = do_upload(
                            $requestedFileKey, path('abs', 'product'), [150], 'string'
                        );

                        if (!empty($getUploadedFileName)) {
                            $productImageSides['file_name'] = $getUploadedFileName;

                            if ($isS3Enabled) {
                                $fileToUpload = path('abs', 'product') . $getUploadedFileName;
                                $this->uploadFileToS3("product", $fileToUpload, $storeId['store_id']);
                                $thumFile = path('abs', 'product') . "thumb_" . $getUploadedFileName;
                                $this->uploadFileToS3("product", $thumFile, $storeId['store_id']);
                            }
                        }

                        // Case #1 : If New file added, then again 2 cases will
                        // arrise. 1. Save new record and 2. Update existing
                        $productImageSides += [
                            'product_image_id' => $productImageInsertId,
                            'side_name' => $sideData['side_name'],
                            'sort_order' => $sideData['sort_order'],
                        ];
                        $prodImgSideInit = new ProductImageSides();
                        $checkIdDataExist = $prodImgSideInit->where(
                            'xe_id', $sideData['xe_id']
                        );
                        if ($checkIdDataExist->count() > 0) {
                            // Update Record
                            $checkIdDataExist->update($productImageSides);
                        } else {
                            // Save New
                            $saveSide = new ProductImageSides($productImageSides);
                            $saveSide->save();
                        }
                    } elseif (!empty($sideData['is_trash'])) {
                        // Case #2: Image Side will be deleted from the Product
                        $prodImgSideInit = new ProductImageSides();
                        $trashSide = $prodImgSideInit->where([
                            'xe_id' => $sideData['xe_id'],
                            'product_image_id' => $productImageInsertId,
                        ]);
                        $trashSideArr = $trashSide->get()->toArray();
                        foreach ($trashSideArr as $side) {
                            if ($isS3Enabled) {
                                $file = $side['file_name'];
                                $store = $storeId['store_id'];
                                $thumbFile = $side['thumbnail'];
                                //delete old file in S3
                                $this->deleteS3File($file, $store);
                                $this->deleteS3File($thumbFile, $store);
                            }
                            if ($trashSide->delete()) {
                                $prodSideInit = new ProductSide();
                                $trashProdSide = $prodSideInit->where([
                                    'product_image_side_id' => $sideData['xe_id']
                                ]);
                                $trashProdSide->delete();
                            }
                        }
                        
                    } else {
                        // Case #3: Existing Image Side will be Updated
                        $productImageSides = [
                            'side_name' => $sideData['side_name'],
                            'sort_order' => $sideData['sort_order'],
                        ];
                        $prodImgSideInit = new ProductImageSides();
                        $updateSide = $prodImgSideInit->where([
                            'xe_id' => $sideData['xe_id'], 'product_image_id' => $productImageInsertId
                        ]);
                        $updateSide->update($productImageSides);
                    }
                }
            }
            $jsonResponse = [
                'status' => 1,
                'message' => message('Product Image Side', 'updated'),
            ];
        }

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

    /**
     * Delete: Delete Product Image(s)
     *
     * @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
     */
    public function productImageDelete($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 0,
            'message' => message('Product side image', 'error'),
        ];
        
        // If user wants to delete Product Image(s)
        if (!empty($args['ids'])) {
            $getStoreDetails = get_store_details($request);
            $isS3Enabled = $this->checkS3Settings($getStoreDetails['store_id']);
            $getProductImagesId = json_clean_decode($args['ids'], true);
            $prodImgInit = new ProductImage();
            $getSelectedItems = $prodImgInit->whereIn('xe_id', $getProductImagesId);

            if ($getSelectedItems->count() > 0) {
                // Get Existing Data for further processing
                $getExistingData = $getSelectedItems->with('sides')->get()->toArray();

                if ($getSelectedItems->delete()) {
                    // Delete product-image-setting-relation Records
                    $prodImgSettRelObj = new ProductImageSettingsRel();
                    $prodImgSettRelGet = $prodImgSettRelObj->where(
                        'product_image_id',
                        $getProductImagesId
                    );
                    $prodImgSettRelGet->delete();
                    // Get existing Images and Delte those from directory
                    foreach ($getExistingData as $selectedValue) {
                        if (!empty($selectedValue['sides'])) {
                            foreach ($selectedValue['sides'] as $singleSide) {
                                if ($selectedValue['cloud_storage'] && $isS3Enabled) {
                                    $file = $singleSide['file_name'];
                                    $this->deleteS3File($file, $getStoreDetails['store_id']);
                                    $thumbFile = $singleSide['thumbnail'];
                                    $this->deleteS3File($thumbFile, $getStoreDetails['store_id']);
                                }
                                $rawFileLocation = PRODUCT_FOLDER . $singleSide['file_name'];
                                // Delete file from the directory
                                if (file_exists($rawFileLocation)) {
                                    unlink($rawFileLocation);
                                }
                            }
                        }
                    }
                    $jsonResponse = [
                        'status' => 1,
                        'message' => message('Product side image', 'deleted')
                    ];
                }
            }
        }

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

    /**
     * Get: Enable/Disable Product Image
     *
     * @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
     */
    public function disableProductImage($request, $response, $args)
    {
        $serverStatusCode = OPERATION_OKAY;
        $jsonResponse = [
            'status' => 1,
            'data' => [],
            'message' => message('Disabling product image', 'error'),
        ];
        // If user wants to delete Product Image(s)
        if (!empty($args['id'])) {
            $getProductImageId = to_int($args['id']);
            $prodImgInit = new ProductImage();
            $getSelectedItems = $prodImgInit->find($getProductImageId);
            $checkCount = count(object_to_array($getSelectedItems));
            if (!empty($getSelectedItems) && $checkCount > 0) {
                $getSelectedItems->is_disable = !$getSelectedItems->is_disable;
                if ($getSelectedItems->save()) {
                    $jsonResponse = [
                        'status' => 1,
                        'message' => message('Product Image', 'updated'),
                    ];
                }
            }
        }

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