<?php
/**
 * 2007-2023 PrestaShop
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
 * versions in the future. If you wish to customize PrestaShop for your
 * needs please refer to http://www.prestashop.com for more information.
 *
 * @author    PrestaShop SA <contact@prestashop.com>
 * @copyright 2007-2023 PrestaShop SA
 * @license   http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 *  International Registered Trademark & Property of PrestaShop SA
 */

use PrestaShop\Module\AgileMultisellerPro\Controller\Front\AgileModuleFrontController;

if (!defined('_PS_VERSION_')) {
    exit;
}

class AgileMultiSellerProAjaxProductsModuleFrontController extends AgileModuleFrontController
{
    public $auth = false;

    public function init()
    {
        if (!isset(Context::getContext()->customer)
            || !Context::getContext()->customer->id
            || !Context::getContext()->customer->isLogged()
        ) {
            exit(json_encode(['status' => 'error', 'message' => $this->l('Permission denied')]));
        }

        parent::init();

        $id_seller = $this->sellerinfo->getIdSellerinfo();

        $id_product = (int) Tools::getValue('id_product');

        $action = Tools::getValue('action');

        if ($action == 'updateImagePosition') {
            exit($this->ajaxProcessUpdateImagePosition());
        }
        if ($action == 'deleteProductImage') {
            exit($this->ajaxProcessDeleteProductImage());
        }
        if ($action == 'UpdateCover') {
            exit($this->ajaxProcessUpdateCover());
        }
        if ($action == 'UpdateProductImageShopAsso') {
            exit($this->ajaxProcessUpdateProductImageShopAsso());
        }
        if ($action == 'DeleteSpecificPrice') {
            exit($this->ajaxProcessDeleteSpecificPrice());
        }
        if ($action == 'productQuantity') {
            exit($this->ajaxProcessProductQuantity());
        }
        if ($action == 'deleteProductAttribute') {
            exit($this->ajaxProcessDeleteProductAttribute());
        }
        if ($action == 'defaultProductAttribute') {
            exit($this->ajaxProcessDefaultProductAttribute());
        }
        if ($action == 'editProductAttribute') {
            exit($this->ajaxProcessEditProductAttribute());
        }
        if ($action == 'deleteVirtualProduct') {
            exit($this->ajaxDeleteVirtualProduct());
        }

        exit(json_encode(['status' => 'error', 'message' => $this->l('Unknown Request')]));
    }

    private function ajaxProcessProductQuantity()
    {
        if (!Tools::getValue('actionQty')) {
            return json_encode(['error' => $this->l('Undefined action')]);
        }
        $product = new Product((int) Tools::getValue('id_product'));
        switch (Tools::getValue('actionQty')) {
            case 'depends_on_stock':
                if (Tools::getValue('value') === false) {
                    return json_encode(['error' => $this->l('Undefined value')]);
                }
                if ((int) Tools::getValue('value') != 0 && (int) Tools::getValue('value') != 1) {
                    return json_encode(['error' => $this->l('Uncorrect value')]);
                }
                if (!$product->advanced_stock_management && (int) Tools::getValue('value') == 1) {
                    return json_encode([
                        'error' => $this->l('Not possible if advanced stock management is not enabled'),
                    ]);
                }
                if ($product->advanced_stock_management && Pack::isPack($product->id)) {
                    return json_encode([
                        'error' => $this->l('Not possible if the product is a pack'),
                    ]);
                }

                StockAvailable::setProductDependsOnStock($product->id, (int) Tools::getValue('value'));
                break;

            case 'out_of_stock':
                if (Tools::getValue('value') === false) {
                    return json_encode(['error' => $this->l('Undefined value')]);
                }
                if (!in_array((int) Tools::getValue('value'), [0, 1, 2])) {
                    return json_encode(['error' => $this->l('Uncorrect value')]);
                }

                StockAvailable::setProductOutOfStock($product->id, (int) Tools::getValue('value'));
                break;

            case 'set_qty':
                if (Tools::getValue('value') === false) {
                    return json_encode(['error' => $this->l('Undefined value')]);
                }
                if (Tools::getValue('id_product_attribute') === false) {
                    return json_encode(['error' => $this->l('Undefined id product attribute')]);
                }
                StockAvailable::setQuantity(
                    $product->id,
                    (int) Tools::getValue('id_product_attribute'),
                    (int) Tools::getValue('value')
                );
                break;
            case 'advanced_stock_management':
                if (Tools::getValue('value') === false) {
                    return json_encode(['error' => $this->l('Undefined value')]);
                }
                if ((int) Tools::getValue('value') != 1 && (int) Tools::getValue('value') != 0) {
                    return json_encode(['error' => $this->l('Uncorrect value')]);
                }
                if (!Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && (int) Tools::getValue('value') == 1) {
                    return json_encode([
                        'error' => $this->l('Not possible if advanced stock management is not enabled'),
                    ]);
                }
                if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && Pack::isPack($product->id)) {
                    return json_encode([
                        'error' => $this->l('Not possible if the product is a pack'),
                    ]);
                }

                $product->advanced_stock_management = (int) Tools::getValue('value');
                $product->save();
                if (StockAvailable::dependsOnStock($product->id) == 1 && (int) Tools::getValue('value') == 0) {
                    StockAvailable::setProductDependsOnStock($product->id, 0);
                }
                break;
        }

        return json_encode(['error' => false]);
    }

    private function ajaxProcessUpdateProductImageShopAsso()
    {
        if (($id_image = Tools::getValue('id_image')) && ($id_shop = (int) Tools::getValue('id_shop'))) {
            if (Tools::getValue('active') == 'true') {
                $res = Db::getInstance()->execute('INSERT INTO ' . _DB_PREFIX_ . 'image_shop (`id_image`, `id_shop`)
                        VALUES(' . (int) $id_image . ', ' . (int) $id_shop . ')');
            } else {
                $res = Db::getInstance()->execute('DELETE FROM ' . _DB_PREFIX_ . 'image_shop
                        WHERE `id_image`=' . (int) $id_image . ' && `id_shop`=' . (int) $id_shop);
            }
        }
        if ($res) {
            $json = ['status' => 'ok', 'message' => ''];
        } else {
            $json = ['status' => 'error', 'message' => $this->l('Error on picture shop association')];
        }

        return json_encode($json);
    }

    private function ajaxProcessUpdateCover()
    {
        Image::deleteCover((int) Tools::getValue('id_product'));
        $img = new Image((int) Tools::getValue('id_image'));
        $img->cover = 1;

        @unlink(_PS_TMP_IMG_DIR_ . 'product_' . (int) $img->id_product . '.jpg');
        @unlink(_PS_TMP_IMG_DIR_ . 'product_mini_' . (int) $img->id_product . '.jpg');

        if ($img->update()) {
            $json = ['status' => 'ok', 'message' => ''];
        } else {
            $json = ['status' => 'error', 'message' => $this->l('Error on updating product cover')];
        }

        return json_encode($json);
    }

    private function ajaxProcessDeleteProductImage()
    {
        $res = true;
        $image = new Image((int) Tools::getValue('id_image'));
        $res &= $image->delete();

        if (!Image::getCover($image->id_product)) {
            $res &= Db::getInstance()->execute('
                UPDATE `' . _DB_PREFIX_ . 'image`
                SET `cover` = 1
                WHERE `id_product` = ' . (int) $image->id_product . ' LIMIT 1');
        }

        if (file_exists(_PS_TMP_IMG_DIR_ . 'product_' . $image->id_product . '.jpg')) {
            $res &= @unlink(_PS_TMP_IMG_DIR_ . 'product_' . $image->id_product . '.jpg');
        }
        if (file_exists(_PS_TMP_IMG_DIR_ . 'product_mini_' . $image->id_product . '.jpg')) {
            $res &= @unlink(_PS_TMP_IMG_DIR_ . 'product_mini_' . $image->id_product . '.jpg');
        }

        if ($res) {
            $json = ['status' => 'ok', 'content' => ['id' => $image->id], 'message' => ''];
        } else {
            $json = ['status' => 'error', 'message' => $this->l('Error on deleting product image')];
        }

        return json_encode($json);
    }

    private function ajaxProcessUpdateImagePosition()
    {
        $res = false;
        if ($json = Tools::getValue('json')) {
            $res = true;
            $json = Tools::stripslashes($json);
            $images = json_decode($json, true);
            foreach ($images as $id => $position) {
                $img = new Image((int) $id);
                $img->position = (int) $position;
                $res &= $img->update();
            }
        }

        if ($res) {
            $json = ['status' => 'ok', 'message' => ''];
        } else {
            $json = ['status' => 'error', 'message' => $this->l('Error on moving picture')];
        }

        return json_encode($json);
    }

    private function ajaxProcessDeleteSpecificPrice()
    {
        $id_specific_price = (int) Tools::getValue('id_specific_price');
        if (!$id_specific_price || !Validate::isUnsignedId($id_specific_price)) {
            $error = $this->l('Invalid specific price ID');
        } else {
            $specificPrice = new SpecificPrice((int) $id_specific_price);
            if (!$specificPrice->delete()) {
                $error = $this->l('An error occurred while deleting the specific price');
            }
        }

        if (isset($error)) {
            $json = [
                'status' => 'error',
                'message' => $error,
            ];
        } else {
            $json = [
                'status' => 'ok',
                'message' => '',
            ];
        }

        return json_encode($json);
    }

    private function ajaxProcessDeleteProductAttribute()
    {
        if (!Combination::isFeatureActive()) {
            return;
        }

        $id_product = (int) Tools::getValue('id_product');
        $id_product_attribute = (int) Tools::getValue('id_product_attribute');
        if ($id_product && Validate::isUnsignedId($id_product)
            && Validate::isLoadedObject($product = new Product($id_product))
        ) {
            $product->deleteAttributeCombination((int) $id_product_attribute);
            $product->checkDefaultAttributes();
            if (!$product->hasAttributes()) {
                Db::getInstance()->update('product', [
                    'cache_default_attribute' => 0,
                ], 'id_product = ' . (int) $id_product);

                Db::getInstance()->update('product_shop', [
                    'cache_default_attribute' => 0,
                ], 'id_product = ' . (int) $id_product);
            } else {
                Product::updateDefaultAttribute($id_product);
            }
            $json = [
                'status' => 'ok',
                'message' => $this->l('Attribute deleted'),
            ];
        } else {
            $json = [
                'status' => 'error',
                'message' => $this->l('Cannot delete attribute'),
            ];
        }

        return json_encode($json);
    }

    private function ajaxProcessDefaultProductAttribute()
    {
        if (!Combination::isFeatureActive()) {
            return;
        }

        if (Validate::isLoadedObject($product = new Product((int) Tools::getValue('id_product')))) {
            $product->deleteDefaultAttributes();
            $product->setDefaultAttribute((int) Tools::getValue('id_product_attribute'));
            $json = [
                'status' => 'ok',
                'message' => $this->l('Default change success'),
            ];
        } else {
            $json = [
                'status' => 'error',
                'message' => $this->l('Cannot make default attribute'),
            ];
        }

        return json_encode($json);
    }

    private function ajaxProcessEditProductAttribute()
    {
        $id_product = (int) Tools::getValue('id_product');
        $id_product_attribute = (int) Tools::getValue('id_product_attribute');
        if ($id_product && Validate::isUnsignedId($id_product)
            && Validate::isLoadedObject($product = new Product((int) $id_product))
        ) {
            $combinations = $product->getAttributeCombinationsById(
                $id_product_attribute,
                Context::getContext()->language->id
            );
            foreach ($combinations as $key => $combination) {
                $combinations[$key]['attributes'][] = [
                    $combination['group_name'],
                    $combination['attribute_name'],
                    $combination['id_attribute'],
                ];
            }

            return json_encode($combinations);
        }
    }

    private function ajaxDeleteVirtualProduct()
    {
        if (!($id_product_download = ProductDownload::getIdFromIdProduct((int) Tools::getValue('id_product')))) {
            $json = [
                'status' => 'error',
                'message' => $this->l('Cannot retrieve file, please save it first!'),
            ];
        } else {
            $product_download = new ProductDownload((int) $id_product_download);
            if (!$product_download->deleteFile((int) $id_product_download)) {
                $json = [
                    'status' => 'error',
                    'message' => $this->l('Cannot delete file, please save it first!'),
                ];
            } else {
                $json = [
                    'status' => 'ok',
                    'message' => $this->l('Success'),
                ];
            }
        }

        return json_encode($json);
    }
}
