<?php
/**
 * @author Aitoc Team
 * @copyright Copyright (c) 2020 Aitoc (https://www.aitoc.com)
 * @package Aitoc_PreOrders
 */

/**
 * Copyright © 2018 Aitoc. All rights reserved.
 * Developed by Alex Yakimovich
 */
namespace Aitoc\PreOrders\Ui\Component\Form\DataProvider\Modifier;

use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Catalog\Model\Locator\LocatorInterface;
use Aitoc\PreOrders\Helper\Settings as SettingsHelper;
use Magento\Framework\Stdlib\ArrayManager;
use Aitoc\PreOrders\Model\AttributesManagement;
use Magento\Framework\Exception\LocalizedException;

/**
 * Class CatalogPreOrder
 */
class CatalogPreOrder extends AbstractModifier
{
    /**
     * @var AttributesManagement
     */
    private $attributesManagement;

    /**
     * @var LocatorInterface
     */
    private $locator;

    /**
     * @var SettingsHelper
     */
    private $settingsHelper;

    /**
     * @var ArrayManager
     */
    private $arrayManager;

    /**
     * @param LocatorInterface $locator
     * @param SettingsHelper $settingsHelper
     * @param ArrayManager $arrayManager
     * @param AttributesManagement $attributesManagement
     */
    public function __construct(
        LocatorInterface $locator,
        SettingsHelper $settingsHelper,
        ArrayManager $arrayManager,
        AttributesManagement $attributesManagement
    ) {
        $this->locator = $locator;
        $this->settingsHelper = $settingsHelper;
        $this->arrayManager = $arrayManager;
        $this->attributesManagement = $attributesManagement;
    }

    /**
     * @param array $meta
     * @return array
     */
    public function modifyMeta(array $meta)
    {
        // Adding PreOrder Settings container to the Product Edit Form

        $meta['pre_order_settings'] = [
            'arguments' => [
                'data' => [
                    'config' => [
                        'label' => __('Pre-Order Settings'),
                        'sortOrder' => 5,
                        'collapsible' => true,
                        'componentType' => 'fieldset',
                        'dataScope' => static::DATA_SCOPE_PRODUCT,
                        'provider' => static::DATA_SCOPE_PRODUCT . '_data_source',
                        'ns' => static::FORM_NAME,
                        'opened' => false,
                    ]
                ]
            ],
            'children' => []
        ];

        $checkboxToggleArray = ['true' => 1, 'false' => 0];

        $fieldsData = [
            'pre_order_status' => [
                'formElement' => 'checkbox',
                'componentType' => 'field',
                'dataType' => 'number',
                'visible' => 1,
                'prefer' => 'toggle',
                'valueMap' => $checkboxToggleArray,
                'code' => 'pre_order_status',
                'dataScope' => 'pre_order_status',
                'default' => 0,
                'label' => __('Enable Pre-Order')
            ],
            'pre_order_qty' => [
                'formElement' => 'input',
                'componentType' => 'field',
                'dataType' => 'number',
                'visible' => 1,
                'code' => 'pre_order_qty',
                'dataScope' => 'pre_order_qty',
                'scopeLabel' => '[store view]',
                'label' => __('Qty when the product becomes Pre-Order'),
                'imports' => [
                    'visible' => '${$.provider}:data.product.pre_order_status'
                ],
                'validation' => [
                    'required-entry' => true,
                    'validate-number' => true
                ],
            ],
            'out_of_stock_qty' => [
                'formElement' => 'input',
                'componentType' => 'field',
                'dataType' => 'number',
                'visible' => 1,
                'code' => 'out_of_stock_qty',
                'dataScope' => 'out_of_stock_qty',
                'scopeLabel' => '[store view]',
                'label' => __('Qty when the product becomes Out Of Stock'),
                'imports' => [
                    'visible' => '${$.provider}:data.product.pre_order_status'
                ],
                'validation' => [
//                    'required-entry' => true,
                    'validate-number' => true
                ],
            ],
            'pre_order_note' => [
                'formElement' => 'input',
                'componentType' => 'field',
                'dataType' => 'text',
                'visible' => 1,
                'code' => 'pre_order_note',
                'dataScope' => 'pre_order_note',
                'scopeLabel' => '[store view]',
                'label' => __('Pre-Order Note'),
                'imports' => [
                    'visible' => '${$.provider}:data.product.pre_order_status'
                ]
            ]

        ];

        if ($this->settingsHelper->getChangeToInStockByDateSetting()) {
            $fieldsData['in_stock_date'] = [
                'formElement' => 'date',
                'component' => 'Aitoc_PreOrders/js/form/element/date',
                'componentType' => 'field',
                'dataType' => 'date',
                'visible' => 1,
                'code' => 'in_stock_date',
                'dataScope' => 'in_stock_date',
                'scopeLabel' => '[store view]',
                'label' => __('Date when the product appears in stock'),
                'imports' => [
                    'visible' => '${$.provider}:data.product.pre_order_status'
                ],
                'validation' => [
                    'validate-date' => true,
                ],

            ];
        }


        $this->appendCustomFields($meta, $fieldsData);

        //disable validation for product quantity < 0
        $meta['product-details']['children']['quantity_and_stock_status_qty']['children']['qty']['arguments']['data']['config']['validation']['validate-digits'] = false;
        unset($meta['product-details']['children']['quantity_and_stock_status_qty']['children']['qty']['arguments']['data']['config']['imports']['handleChanges']);
        
        return $meta;
    }

    private function appendCustomFields(&$meta, $fieldsData)
    {
        $product = $this->locator->getProduct();
        $productId = $product->getId();
        $storeId = $product->getStoreId();
        foreach ($fieldsData as $fieldName => $fieldConfig) {
            if ($storeId != 0) {
                $isUsedDefault = $this->attributesManagement->isUsedDefault($productId, $fieldName, $storeId);
                $fieldConfig += ['usedDefault' => $isUsedDefault,
                    'disabled' => $isUsedDefault,
                    'service' => [
                        'template' => 'ui/form/element/helper/service',
                    ]
                ];
            }
            $meta['pre_order_settings']['children'][$fieldName] = [
                'arguments' => [
                    'data' => [
                        'config' => $fieldConfig
                    ]
                ]
            ];
        }
    }

    /**
     * @param array $data
     * @return array
     * @throws LocalizedException
     */
    public function modifyData(array $data)
    {
        $product = $this->locator->getProduct();
        $storeId = $product->getStoreId();
        $productId = $product->getId();

        if ($productId) {
            $productAttributes = $this->attributesManagement->getAttributesByProduct($productId, $storeId);
            $productPath = $productId . '/product';
            $data = $this->arrayManager->merge($productPath, $data, $productAttributes);
        }
        return $data;
    }
}
