<?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
 */

namespace PrestaShop\Module\AgileMultisellerPro\Helper\Form;

use PrestaShop\Module\AgileMultisellerPro\Adapter\SellerInfoAdapter;
use PrestaShop\Module\AgileMultisellerPro\Entity\Sellerinfo;
use PrestaShop\Module\AgileMultisellerPro\Entity\SellerinfoAttachment;
use PrestaShop\Module\AgileMultisellerPro\Entity\SellerinfoCategory;
use PrestaShop\Module\AgileMultisellerPro\Form\Configuration\DataConfiguration;
use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductType;

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

class ProductForm extends AbstractForm
{
    private $sellerinfo;
    private $product;
    private $entityManager;

    const PRODUCT_MENU = [
        1 => 'informations',
        2 => 'images',
        'addImages' => 'addImages',
        'updateLegends' => 'updateLegends',
        3 => 'features',
        4 => 'associations',
        5 => 'prices',
        6 => 'quantites',
        7 => 'combinations',
        8 => 'virtualproduct',
        9 => 'shipping',
        10 => 'attachments',
        'addAttachments' => 'addAttachments',
        11 => 'producttags',
        12 => 'description',
        13 => 'options',
    ];

    public function __construct(Sellerinfo $sellerinfo, \Product $product, $entityManager)
    {
        parent::__construct();

        $this->sellerinfo = $sellerinfo;
        $this->product = $product;
        $this->entityManager = $entityManager;
    }

    protected function getFieldsByType($typeMenu): array
    {
        $fields = [];
        $methodName = '';

        if (isset(self::PRODUCT_MENU[$typeMenu])) {
            $methodName = 'get' . ucfirst(self::PRODUCT_MENU[$typeMenu]) . 'Fields';
        }

        if (true === method_exists($this, $methodName)) {
            $fields = $this->$methodName();
        }

        return $fields;
    }

    private function getInformationsFields()
    {
        $defaultCurrency = \Currency::getDefaultCurrency();

        $categories = $this->entityManager->getRepository(SellerinfoCategory::class)
            ->getSellerCategories($this->sellerinfo->getIdSellerinfo());

        if (!$categories) {
            $category = new \Category(
                \Configuration::get(DataConfiguration::AGILE_MS_DEFAULT_CATEGORY),
                $this->context->language->id
            );

            if (\Validate::isLoadedObject($category)) {
                $categories[$category->id] = $category->name;
            }
        }

        $formFields = [
            [
                'fieldName' => 'active',
                'options' => [
                    'label' => $this->translator->trans('Status', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'required' => true,
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['select'],
                        'availableValues' => [
                            1 => $this->translator->trans('Enabled', [], 'Modules.Agilemultisellerpro.Product'),
                            0 => $this->translator->trans('Disabled', [], 'Modules.Agilemultisellerpro.Product'),
                        ],
                    ],
                ],
            ],
            [
                'fieldName' => 'name',
                'options' => [
                    'label' => $this->translator->trans('Name', [], 'Modules.Agilemultisellerpro.Product'),
                    'lang' => true,
                    'formOptions' => [
                        'required' => true,
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['text'],
                        'isAgileForm' => true,
                    ],
                ],
            ],
            [
                'fieldName' => 'reference',
                'options' => [
                    'label' => $this->translator->trans('Reference', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'required' => true,
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['text'],
                    ],
                ],
            ],
            [
                'fieldName' => 'id_category_default',
                'options' => [
                    'label' => $this->translator->trans('Category', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'required' => true,
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['select'],
                        'availableValues' => $categories,
                    ],
                ],
            ],
            [
                'fieldName' => 'price',
                'options' => [
                    'label' => $this->translator->trans('Retail Price', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['number'],
                        'required' => true,
                        'availableValues' => [
                            'comment' => $this->translator->trans('Please set price in %currency%', ['%currency%' => $defaultCurrency->name . ' (' . $defaultCurrency->iso_code . ')'], 'Modules.Agilemultisellerpro.Product'),
                            'otherAttr' => 'step="0.01"',
                            'group' => [
                                'after' => $defaultCurrency->iso_code,
                            ],
                        ],
                        'isAgileForm' => true,
                    ],
                ],
            ],
        ];

        $quantityField = [
            'fieldName' => 'quantity',
            'options' => [
                'label' => $this->translator->trans('Quantity', [], 'Modules.Agilemultisellerpro.Product'),
                'formOptions' => [
                    'required' => true,
                    'type' => SellerInfoAdapter::FORM_FIELD_TYPES['number'],
                ],
            ],
        ];

        if ($this->product->product_type != ProductType::TYPE_COMBINATIONS) {
            array_push($formFields, $quantityField);
        }

        return $formFields;
    }

    private function getDescriptionFields()
    {
        return [
            [
                'fieldName' => 'description_short',
                'options' => [
                    'label' => $this->translator->trans('Short description', [], 'Modules.Agilemultisellerpro.Product'),
                    'lang' => true,
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['html'],
                        'isAgileForm' => true,
                    ],
                ],
            ],
            [
                'fieldName' => 'description',
                'options' => [
                    'label' => $this->translator->trans('Description', [], 'Modules.Agilemultisellerpro.Product'),
                    'lang' => true,
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['html'],
                        'isAgileForm' => true,
                    ],
                ],
            ],
            [
                'fieldName' => 'meta_description',
                'options' => [
                    'label' => $this->translator->trans('Meta Description', [], 'Modules.Agilemultisellerpro.Product'),
                    'lang' => true,
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['text'],
                        'isAgileForm' => true,
                    ],
                ],
            ],
            [
                'fieldName' => 'meta_title',
                'options' => [
                    'label' => $this->translator->trans('Meta Title', [], 'Modules.Agilemultisellerpro.Product'),
                    'lang' => true,
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['text'],
                        'isAgileForm' => true,
                    ],
                ],
            ],
            [
                'fieldName' => 'link_rewrite',
                'options' => [
                    'label' => $this->translator->trans('Friendly URL', [], 'Modules.Agilemultisellerpro.Product'),
                    'lang' => true,
                    'formOptions' => [
                        'required' => true,
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['text'],
                        'isAgileForm' => true,
                    ],
                ],
            ],
            [
                'fieldName' => 'tags',
                'options' => [
                    'label' => $this->translator->trans('Tags', [], 'Modules.Agilemultisellerpro.Product'),
                    'lang' => true,
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['text'],
                        'isAgileForm' => true,
                    ],
                ],
            ],
        ];
    }

    private function getImagesFields()
    {
        $images = [];

        foreach ($this->product->getImages($this->context->language->id) as $image) {
            $images[] = new \Image($image['id_image']);
        }

        return [
            [
                'fieldName' => 'images',
                'options' => [
                    'label' => $this->translator->trans('Images', [], 'Modules.Agilemultisellerpro.Product'),
                    'value' => '',
                    'formOptions' => [
                        'templateFile' => 'module:agilemultisellerpro/views/templates/front/products/images.tpl',
                        'availableValues' => [
                            'images' => $images,
                            'countImages' => count($images),
                            'shops' => \Shop::getShops(),
                            'max_image_size' => (int) \Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE') / 1000,
                            'image_number_limit' => (int) \Configuration::get('AGILE_MS_PRODUCT_IMAGE_NUMBER'),
                            'imagesTypes' => \ImageType::getImagesTypes('products'),
                        ],
                    ],
                ],
            ],
        ];
    }

    private function getFeaturesFields()
    {
        $features = \Feature::getFeatures($this->context->language->id);

        foreach ($features as $k => $tab_features) {
            $features[$k]['current_item'] = false;
            $features[$k]['val'] = [];

            $custom = true;
            foreach ($this->product->getFeatures() as $tab_products) {
                if ($tab_products['id_feature'] == $tab_features['id_feature']) {
                    $features[$k]['current_item'] = $tab_products['id_feature_value'];
                }
            }
            $features[$k]['featureValues'] = \FeatureValue::getFeatureValuesWithLang(
                $this->context->language->id,
                (int) $tab_features['id_feature']
            );
            if (count($features[$k]['featureValues'])) {
                foreach ($features[$k]['featureValues'] as $value) {
                    if ($features[$k]['current_item'] == $value['id_feature_value']) {
                        $custom = false;
                    }
                }
            }
            if ($custom) {
                foreach (\FeatureValue::getFeatureValueLang($features[$k]['current_item']) as $featuresValueCustom) {
                    $features[$k]['val'][$featuresValueCustom['id_lang']] = $featuresValueCustom;
                }
            }
        }

        return [
            [
                'fieldName' => 'features',
                'options' => [
                    'label' => $this->translator->trans('Assign features to this product', [], 'Modules.Agilemultisellerpro.Product'),
                    'value' => '',
                    'formOptions' => [
                        'templateFile' => 'module:agilemultisellerpro/views/templates/front/products/features.tpl',
                        'availableValues' => [
                            'features' => $features,
                        ],
                    ],
                ],
            ],
        ];
    }

    private function getAssociationsFields()
    {
        $default_category = $this->product->id_category_default;
        $idLang = $this->context->language->id;

        if (!$this->product->id) {
            $selected_cat = \Category::getCategoryInformations(
                \Tools::getValue('categoryBox', [$default_category]),
                $idLang
            );
        } else {
            $selected_cat = \Product::getProductCategoriesFull($this->product->id, $idLang);
        }

        if (!array_key_exists($default_category, $selected_cat)) {
            $sql = 'SELECT id_category, name, link_rewrite, id_lang FROM ' . _DB_PREFIX_ .
                'category_lang WHERE id_category=' . $default_category .
                ' AND id_lang=' . (int) $idLang;
            $selected_cat[$default_category] = \Db::getInstance()->getRow($sql);
        }

        return [
            [
                'fieldName' => 'associations',
                'options' => [
                    'label' => $this->translator->trans('Associations', [], 'Modules.Agilemultisellerpro.Product'),
                    'value' => '',
                    'formOptions' => [
                        'templateFile' => 'module:agilemultisellerpro/views/templates/front/products/associations.tpl',
                        'availableValues' => [
                            'manufacturers' => \Manufacturer::getManufacturers(),
                            'selected_cat' => $selected_cat,
                            'allow_register_athome' => (int) \Configuration::get(DataConfiguration::AGILE_MS_ALLOW_REGISTER_ATHOME),
                            'agile_ms_edit_category' => (int) \Configuration::get(DataConfiguration::AGILE_MS_EDIT_CATEGORY),
                        ],
                    ],
                ],
            ],
        ];
    }

    private function getPricesFields()
    {
        $address = new \Address();
        $address->id_country = (int) $this->context->country->id;

        // Tax
        $tax_rules_groups = \TaxRulesGroup::getTaxRulesGroups(true);
        $tax_rates = [
            0 => [
                'id_tax_rules_group' => 0,
                'rates' => [0],
                'computation_method' => 0,
            ],
        ];

        foreach ($tax_rules_groups as $tax_rules_group) {
            $id_tax_rules_group = (int) $tax_rules_group['id_tax_rules_group'];

            $tax_calculator = \TaxManagerFactory::getManager($address, $id_tax_rules_group)->getTaxCalculator();

            $tax_rates[$id_tax_rules_group] = [
                'id_tax_rules_group' => $id_tax_rules_group,
                'rates' => [],
                'computation_method' => (int) $tax_calculator->computation_method,
            ];

            if (isset($tax_calculator->taxes) && count($tax_calculator->taxes)) {
                foreach ($tax_calculator->taxes as $tax) {
                    $tax_rates[$id_tax_rules_group]['rates'][] = (float) $tax->rate;
                }
            } else {
                $tax_rates[$id_tax_rules_group]['rates'][] = 0;
            }
        }

        // Combinations
        $attributes = $this->product->getAttributesGroups((int) $this->context->language->id);
        $combinations = [];
        $currencyDefault = new \Currency((int) \Configuration::get('PS_CURRENCY_DEFAULT'));

        foreach ($attributes as $attribute) {
            $combinations[
                $attribute['id_product_attribute']
            ]['id_product_attribute'] = $attribute['id_product_attribute'];

            if (!isset($combinations[$attribute['id_product_attribute']]['attributes'])) {
                $combinations[$attribute['id_product_attribute']]['attributes'] = '';
            }

            $combinations[$attribute['id_product_attribute']]['attributes'] .= $attribute['attribute_name'] .
                ' - ';

            $combinations[$attribute['id_product_attribute']]['price'] = \Tools::displayPrice(
                \Tools::convertPrice(
                    \Product::getPriceStatic((int) $this->product->id, false, $attribute['id_product_attribute']),
                    $currencyDefault
                ),
                $currencyDefault
            );
        }

        foreach ($combinations as &$combination) {
            $combination['attributes'] = rtrim($combination['attributes'], ' - ');
        }

        \Media::addJsDef([
            'taxesRatesByGroup' => $tax_rates,
        ]);

        return [
            [
                'fieldName' => 'prices',
                'options' => [
                    'label' => $this->translator->trans('Product price', [], 'Modules.Agilemultisellerpro.Product'),
                    'value' => '',
                    'formOptions' => [
                        'templateFile' => 'module:agilemultisellerpro/views/templates/front/products/prices.tpl',
                        'availableValues' => [
                            'tax_rules_groups' => $tax_rules_groups,
                            'combinations' => $combinations,
                            'ps_use_ecotax' => \Configuration::get('PS_USE_ECOTAX'),
                            'tax_exclude_taxe_option' => \Tax::excludeTaxeOption(),
                            'ecotaxTaxRate' => \Tax::getProductEcotaxRate(),
                            'ps_tax' => \Configuration::get('PS_TAX'),
                            'country_display_tax_label' => $this->context->country->display_tax_label,
                            'currencyDefault' => $currencyDefault,
                        ],
                    ],
                ],
            ],
        ];
    }

    private function getQuantitesFields()
    {
        $show_quantities = true;
        $shop_context = \Shop::getContext();
        $group_shop = $this->context->shop->getGroup();

        if ($shop_context == \Shop::CONTEXT_ALL) {
            $show_quantities = false;
        } elseif ($shop_context == \Shop::CONTEXT_GROUP) {
            if (!$group_shop->share_stock) {
                $show_quantities = false;
            }
        } else {
            if ($group_shop->share_stock) {
                $show_quantities = false;
            }
        }

        // Attributes
        $attributes = $this->product->getAttributesResume($this->context->language->id);

        if (empty($attributes)) {
            $attributes[] = [
                'id_product_attribute' => 0,
                'attribute_designation' => '',
            ];
        }

        $available_quantity = [];
        $product_designation = [];

        foreach ($attributes as $attribute) {
            $available_quantity[
                $attribute['id_product_attribute']
            ] = \StockAvailable::getQuantityAvailableByProduct(
                (int) $this->product->id,
                $attribute['id_product_attribute']
            );
            $product_designation[$attribute['id_product_attribute']] = rtrim(
                $this->product->name[$this->context->language->id] . ' - ' .
                $attribute['attribute_designation'],
                ' - '
            );
        }

        // Pack
        $pack_quantity = null;

        if (\Pack::isPack($this->product->id)) {
            $items = \Pack::getItems((int) $this->product->id, \Configuration::get('PS_LANG_DEFAULT'));

            $pack_quantities = [];

            foreach ($items as $item) {
                if (!$item->isAvailableWhenOutOfStock((int) $item->out_of_stock)) {
                    $pack_id_product_attribute = \Product::getDefaultAttribute($item->id, 1);
                    $pack_quantities[] = \Product::getQuantity(
                        $item->id,
                        $pack_id_product_attribute
                    ) / ($item->pack_quantity !== 0 ? $item->pack_quantity : 1);
                }
            }

            $pack_quantity = $pack_quantities[0];

            foreach ($pack_quantities as $value) {
                if ($pack_quantity > $value) {
                    $pack_quantity = $value;
                }
            }

            if (!\Warehouse::getPackWarehouses((int) $this->product->id)) {
                $this->displayWarning(
                    $this->getMessage('You must have a common warehouse between this pack and its product.')
                );
            }
        }

        return [
            [
                'fieldName' => 'quantites',
                'options' => [
                    'label' => $this->translator->trans('Available quantities for sale', [], 'Modules.Agilemultisellerpro.Product'),
                    'value' => '',
                    'formOptions' => [
                        'templateFile' => 'module:agilemultisellerpro/views/templates/front/products/quantites.tpl',
                        'availableValues' => [
                            'show_quantities' => $show_quantities,
                            'attributes' => $attributes,
                            'available_quantity' => $available_quantity,
                            'product_designation' => $product_designation,
                            'pack_quantity' => $pack_quantity,
                            'ps_stock_management' => \Configuration::get('PS_STOCK_MANAGEMENT'),
                            'stock_management_active' => \Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'),
                        ],
                    ],
                ],
            ],
        ];
    }

    private function getCombinationsFields()
    {
        $address = new \Address();
        $address->id_country = (int) $this->context->country->id;

        $tax_rules_groups = \TaxRulesGroup::getTaxRulesGroups(true);
        $tax_rates = [
            0 => [
                'id_tax_rules_group' => 0,
                'rates' => [0],
                'computation_method' => 0,
            ],
        ];

        foreach ($tax_rules_groups as $tax_rules_group) {
            $id_tax_rules_group = (int) $tax_rules_group['id_tax_rules_group'];
            $tax_calculator = \TaxManagerFactory::getManager($address, $id_tax_rules_group)->getTaxCalculator();
            $tax_rates[$id_tax_rules_group] = [
                'id_tax_rules_group' => $id_tax_rules_group,
                'rates' => [],
                'computation_method' => (int) $tax_calculator->computation_method,
            ];

            if (isset($tax_calculator->taxes) && count($tax_calculator->taxes)) {
                foreach ($tax_calculator->taxes as $tax) {
                    $tax_rates[$id_tax_rules_group]['rates'][] = (float) $tax->rate;
                }
            } else {
                $tax_rates[$id_tax_rules_group]['rates'][] = 0;
            }
        }

        $currency = new \Currency((int) \Configuration::get('PS_CURRENCY_DEFAULT'));

        $attribute_js = [];
        $attributes = $this->getAttributes(true);

        foreach ($attributes as $k => $attribute) {
            $attribute_js[$attribute['id_attribute_group']][$attribute['id_attribute']] = $attribute['name'];
        }

        $images = \Image::getImages($this->context->language->id, $this->product->id);

        foreach ($images as &$image) {
            $image['link'] = $this->context->link->getImageLink(
                $this->product->link_rewrite[$this->context->language->id], $image['id_image'], \ImageType::getFormattedName('small'));
        }

        \Media::addJsDef([
            'taxesRatesByGroup' => $tax_rates,
            'combinationImagesJs' => $this->getCombinationImagesJs(),
        ]);

        return [
            [
                'fieldName' => 'quantites',
                'options' => [
                    'label' => $this->translator->trans('Add or modify combinations for this product.', [], 'Modules.Agilemultisellerpro.Product'),
                    'value' => '',
                    'formOptions' => [
                        'templateFile' => 'module:agilemultisellerpro/views/templates/front/products/combinations.tpl',
                        'availableValues' => [
                            'finalPrice' => \Product::getPriceStatic($this->product->id, true, null, 6, null, false, true, 1, true),
                            'combinationArray' => $this->getCombinations($currency),
                            // 'combinationImagesJs' => $this->getCombinationImagesJs(),
                            'tax_exclude_taxe_option' => \Tax::excludeTaxeOption(),
                            'ecotaxTaxRate' => \Tax::getProductEcotaxRate(),
                            'attributeJs' => $attribute_js,
                            'attributes_groups' => \AttributeGroup::getAttributesGroups($this->context->language->id),
                            'country_display_tax_label' => $this->context->country->display_tax_label,
                            'ps_weight_unit' => \Configuration::get('PS_WEIGHT_UNIT'),
                            'images' => $images,
                            'currencyDefault' => $currency,
                        ],
                    ],
                ],
            ],
        ];
    }

    public function getCombinations($currency)
    {
        $color_by_default = '#BDE5F8';

        if ($this->product->id) {
            $combinations = $this->product->getAttributeCombinations($this->context->language->id);
            $groups = [];
            $comb_array = [];

            if (is_array($combinations)) {
                $combination_images = $this->product->getCombinationImages($this->context->language->id);
                foreach ($combinations as $combination) {
                    $price = \Tools::displayPrice($combination['price'], $currency);

                    $comb_array[
                        $combination['id_product_attribute']
                    ]['id_product_attribute'] = $combination['id_product_attribute'];
                    $comb_array[$combination['id_product_attribute']]['attributes'][] = [
                        $combination['group_name'],
                        $combination['attribute_name'],
                        $combination['id_attribute'],
                    ];
                    $comb_array[
                        $combination['id_product_attribute']
                    ]['wholesale_price'] = $combination['wholesale_price'];
                    $comb_array[
                        $combination['id_product_attribute']
                    ]['price'] = $price;
                    $comb_array[
                        $combination['id_product_attribute']
                    ]['weight'] = $combination['weight'] .
                        \Configuration::get('PS_WEIGHT_UNIT');
                    $comb_array[
                        $combination['id_product_attribute']
                    ]['unit_impact'] = $combination['unit_price_impact'];
                    $comb_array[
                        $combination['id_product_attribute']
                    ]['reference'] = $combination['reference'];
                    $comb_array[
                        $combination['id_product_attribute']
                    ]['ean13'] = $combination['ean13'];
                    $comb_array[
                        $combination['id_product_attribute']
                    ]['upc'] = $combination['upc'];
                    $comb_array[
                        $combination['id_product_attribute']
                        ]['id_image'] = isset($combination_images[
                            $combination['id_product_attribute']
                        ][0]['id_image']) ?
                        $combination_images[$combination['id_product_attribute']][0]['id_image'] : 0;
                    $comb_array[
                        $combination['id_product_attribute']
                    ]['available_date'] = $combination['available_date'];
                    $comb_array[
                        $combination['id_product_attribute']
                    ]['default_on'] = $combination['default_on'];
                    if ($combination['is_color_group']) {
                        $groups[$combination['id_attribute_group']] = $combination['group_name'];
                    }
                }
            }

            if (isset($comb_array)) {
                foreach ($comb_array as $id_product_attribute => $product_attribute) {
                    $list = '';

                    asort($product_attribute['attributes']);

                    foreach ($product_attribute['attributes'] as $attribute) {
                        $list .= htmlspecialchars($attribute[0]) . ' - ' . htmlspecialchars($attribute[1]) . ', ';
                    }
                    $list = rtrim($list, ', ');
                    $comb_array[$id_product_attribute]['image'] = $product_attribute['id_image'] ?
                        new \Image($product_attribute['id_image']) : false;
                    $comb_array[$id_product_attribute]['available_date'] = $product_attribute['available_date'] != 0 ?
                        date('Y-m-d', strtotime($product_attribute['available_date'])) : '0000-00-00';
                    $comb_array[$id_product_attribute]['attributes'] = $list;

                    if ($product_attribute['default_on']) {
                        $comb_array[$id_product_attribute]['name'] = 'is_default';
                        $comb_array[$id_product_attribute]['color'] = $color_by_default;
                    }
                }
            }
        }

        return $comb_array;
    }

    public function getCombinationImagesJS()
    {
        if (!($obj = $this->product)) {
            return;
        }

        $images = $obj->getCombinationImages($this->context->language->id);

        if (!is_array($images)) {
            return [];
        }

        return $images;
    }

    public function getAttributes($notNull = false)
    {
        if (!\Combination::isFeatureActive()) {
            return [];
        }

        return \Db::getInstance()->executeS('
			SELECT DISTINCT ag.*, agl.*, a.`id_attribute`, al.`name`, agl.`name` AS `attribute_group`
			FROM `' . _DB_PREFIX_ . 'attribute_group` ag
			LEFT JOIN `' . _DB_PREFIX_ . 'attribute_group_lang` agl
				ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = ' . (int) $this->context->language->id . ')
			LEFT JOIN `' . _DB_PREFIX_ . 'attribute` a
				ON a.`id_attribute_group` = ag.`id_attribute_group`
			LEFT JOIN `' . _DB_PREFIX_ . 'attribute_lang` al
				ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = ' . (int) $this->context->language->id . ')
			' . \Shop::addSqlAssociation('attribute_group', 'ag') . '
			' . \Shop::addSqlAssociation('attribute', 'a') . '
			' . ($notNull ? 'WHERE a.`id_attribute` IS NOT NULL AND al.`name` IS NOT NULL AND agl.`id_attribute_group` IS NOT NULL' : '') . '
			ORDER BY agl.`name` ASC, a.`position` ASC
		');
    }

    private function getVirtualproductFields()
    {
        $productDownload = new \ProductDownload();

        if ($id_product_download = $productDownload->getIdFromIdProduct($this->product->id)) {
            $productDownload = new \ProductDownload($id_product_download);
        }

        $cache_default_attribute = (int) \Product::getDefaultAttribute($this->product->id);

        $exists_file = realpath(_PS_DOWNLOAD_DIR_) . '/' . $productDownload->filename;

        if (!file_exists($exists_file)
            && !empty($productDownload->display_filename)
            && empty($cache_default_attribute)) {
            $msg = sprintf(
                $this->translator->trans('This file "%s" is missing', [], 'Modules.Agilemultisellerpro.Product'),
                $productDownload->display_filename
            );
        } else {
            $msg = '';
        }

        $productDownload->nb_downloadable = ($productDownload->id > 0) ?
            $productDownload->nb_downloadable :
            htmlentities(\Tools::getValue('virtual_product_nb_downloable'), ENT_COMPAT, 'UTF-8');

        $productDownload->date_expiration = ($productDownload->id > 0) ?
            ((!empty($productDownload->date_expiration)
                && $productDownload->date_expiration != '0000-00-00 00:00:00') ?
                date('Y-m-d', strtotime($productDownload->date_expiration)) : '') :
            htmlentities(\Tools::getValue('virtual_product_expiration_date'), ENT_COMPAT, 'UTF-8');

        $productDownload->nb_days_accessible = ($productDownload->id > 0) ?
            $productDownload->nb_days_accessible : htmlentities(
                \Tools::getValue('virtual_product_nb_days'),
                ENT_COMPAT,
                'UTF-8'
            );

        $productDownload->is_shareable = $productDownload->id > 0 && $productDownload->is_shareable;

        return [
            [
                'fieldName' => 'virtualproduct',
                'options' => [
                    'label' => $this->translator->trans('Virtual Product (services, booking and downloadable products)',
                        [], 'Modules.Agilemultisellerpro.Product'),
                    'value' => '',
                    'formOptions' => [
                        'templateFile' => 'module:agilemultisellerpro/views/templates/front/products/virtualproduct.tpl',
                        'availableValues' => [
                            'cache_default_attribute' => $cache_default_attribute,
                            'download_product_file_missing' => $msg,
                            'download_dir_writable' => \ProductDownload::checkWritableDir(),
                            'productDownload' => $productDownload,
                            'upload_max_filesize' => (\Tools::getOctets(ini_get('upload_max_filesize')) / 1024) / 1024,
                        ],
                    ],
                ],
            ],
        ];
    }

    protected function getAvailableValuesByField($field): array
    {
        $availableValues = [];
        $options = $this->getOptionsByField($field);

        if (isset($options['formOptions']['availableValues'])) {
            $availableValues = $options['formOptions']['availableValues'];
        }

        return $availableValues;
    }

    private function getShippingFields()
    {
        $carrier_list = \Carrier::getCarriers(
            $this->context->language->id,
            true,
            false,
            false,
            null,
            \Carrier::ALL_CARRIERS
        );
        $carrier_selected_list = $this->product->getCarriers();

        foreach ($carrier_list as &$carrier) {
            foreach ($carrier_selected_list as $carrier_selected) {
                if ($carrier_selected['id_reference'] == $carrier['id_reference']) {
                    $carrier['selected'] = true;
                    break;
                }
            }
        }

        return [
            [
                'fieldName' => 'shipping',
                'options' => [
                    'label' => $this->translator->trans('Shipping', [], 'Modules.Agilemultisellerpro.Product'),
                    'value' => '',
                    'formOptions' => [
                        'templateFile' => 'module:agilemultisellerpro/views/templates/front/products/shipping.tpl',
                        'availableValues' => [
                            'ps_dimension_unit' => \Configuration::get('PS_DIMENSION_UNIT'),
                            'ps_weight_unit' => \Configuration::get('PS_WEIGHT_UNIT'),
                            'country_display_tax_label' => $this->context->country->display_tax_label,
                            'carrier_list' => $carrier_list,
                        ],
                    ],
                ],
            ],
        ];
    }

    private function getAttachmentsFields()
    {
        return [
            [
                'fieldName' => 'attachments',
                'options' => [
                    'label' => $this->translator->trans('Attachment', [], 'Modules.Agilemultisellerpro.Product'),
                    'value' => '',
                    'formOptions' => [
                        'templateFile' => 'module:agilemultisellerpro/views/templates/front/products/attachments.tpl',
                        'availableValues' => [
                            // 'attach1' => \Attachment::getAttachments($this->context->language->id, $this->product->id, false),
                            // 'attach2' => \Attachment::getAttachments($this->context->language->id, $this->product->id, true),

                            'attach1' => $this->entityManager->getRepository(SellerinfoAttachment::class)
                            ->getAttachments($this->sellerinfo, $this->context->language->id, $this->product->id, false),
                            'attach2' => $this->entityManager->getRepository(SellerinfoAttachment::class)
                            ->getAttachments($this->sellerinfo, $this->context->language->id, $this->product->id, true),
                        ],
                    ],
                ],
            ],
        ];
    }

    private function getOptionsFields()
    {
        return [
            [
                'fieldName' => 'ean13',
                'options' => [
                    'label' => $this->translator->trans('EAN-13 or JAN barcode', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['text'],
                    ],
                ],
            ],
            [
                'fieldName' => 'upc',
                'options' => [
                    'label' => $this->translator->trans('UPC barcode', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['text'],
                    ],
                ],
            ],
            [
                'fieldName' => 'visibility',
                'options' => [
                    'label' => $this->translator->trans('Visibility', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'required' => true,
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['select'],
                        'availableValues' => [
                            'both' => $this->translator->trans('Everywhere', [], 'Modules.Agilemultisellerpro.Product'),
                            'catalog' => $this->translator->trans('Catalog only', [], 'Modules.Agilemultisellerpro.Product'),
                            'search' => $this->translator->trans('Search only', [], 'Modules.Agilemultisellerpro.Product'),
                            'none' => $this->translator->trans('Nowhere', [], 'Modules.Agilemultisellerpro.Product'),
                        ],
                    ],
                ],
            ],
            [
                'fieldName' => 'available_for_order',
                'options' => [
                    'label' => $this->translator->trans('Available for order', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['checkbox'],
                    ],
                ],
            ],
            [
                'fieldName' => 'show_price',
                'options' => [
                    'label' => $this->translator->trans('Show price', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['checkbox'],
                        'isAgileForm' => true,
                    ],
                ],
            ],
            [
                'fieldName' => 'online_only',
                'options' => [
                    'label' => $this->translator->trans('Web only (not sold in retail store)', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['checkbox'],
                    ],
                ],
            ],
            [
                'fieldName' => 'condition',
                'options' => [
                    'label' => $this->translator->trans('Condition', [], 'Modules.Agilemultisellerpro.Product'),
                    'formOptions' => [
                        'required' => true,
                        'type' => SellerInfoAdapter::FORM_FIELD_TYPES['select'],
                        'availableValues' => [
                            'new' => $this->translator->trans('New', [], 'Modules.Agilemultisellerpro.Product'),
                            'used' => $this->translator->trans('Used', [], 'Modules.Agilemultisellerpro.Product'),
                            'refurbished' => $this->translator->trans('Refurbished', [], 'Modules.Agilemultisellerpro.Product'),
                        ],
                    ],
                ],
            ],
        ];
    }

    protected function getMaxLengthByField($field): ?int
    {
        $maxLength = parent::getMaxLengthByField($field);

        if (!$maxLength) {
            $fieldType = $this->getNameByField($field);
            if (isset(\Product::$definition['fields'][$fieldType]['size'])) {
                $maxLength = (int) \Product::$definition['fields'][$fieldType]['size'];
            }
        }

        return $maxLength;
    }

    protected function getOptionsByField($field)
    {
        $options = [];

        if (isset($field['options'])) {
            $options = $field['options'];
        }

        return $options;
    }

    protected function getValueFormByField($field)
    {
        $value = null;

        if (isset($this->product->$field)) {
            $value = $this->product->$field;
        }

        if (is_numeric($value)) {
            $value = round($value, 2);
        }

        return $value;
    }

    protected function getValueLangByField($field)
    {
        $value = null;

        if ('tags' === $field) {
            foreach (\Language::getLanguages(true) as $language) {
                $idLang = $language['id_lang'];
                $value[$idLang] = $this->product->getTags($idLang);
            }
        } elseif (isset($this->product->$field)) {
            $value = $this->product->$field;
        }

        return $value;
    }
}
