<?php

namespace Webkul\WooCommerceBundle\Connector\Writer;

use Webkul\WooCommerceBundle\Traits\DataMappingTrait;
use Webkul\WooCommerceBundle\Entity\DataMapping;
use Webkul\WooCommerceBundle\Listener\ClassDefinationForCompatibility;

$obj = new ClassDefinationForCompatibility();
$obj->objectCreate();
/**
 * Add products to WooCommerce
 *
 * @author    Webkul Software Pvt Ltd
 * @copyright 2010-2017 Webkul pvt. ltd.
 * @license   https://store.webkul.com/license.html
 */
class ProductWriter extends BaseWriter implements \ItemWriterInterface
{
    use DataMappingTrait;

    const AKENEO_ENTITY_NAME = 'product';
    const AKENEO_ATTRIBUTE_ENTITY_NAME = 'attribute';
    const AKENEO_CATEGORY_ENTITY_NAME = 'category';
    const ACTION_ADD = 'addProduct';
    const ACTION_UPDATE = 'updateProduct';
    const ACTION_DELETE= 'deleteProduct';
    const ACTION_ADD_VARIATION = 'addVariation';
    const ACTION_UPDATE_VARIATION = 'updateVariation';
    const SETTING_SECTION = 'woocommerce_connector_settings';
    const CODE_ALREADY_EXIST = 'product_invalid_sku';
    const CODE_DUPLICATE_EXIST = 'duplicate_term_slug';
    const CODE_NOT_EXIST = 'woocommerce_rest_term_invalid';
    const CODE_DELETED_VARIATION = 'woocommerce_rest_product_variation_invalid_id';
    const CODE_INAVLID_IMAGE_ID = 'woocommerce_product_invalid_image_id';
    const RELATED_INDEX = null;
    const ACTION_GET = 'getAllProduct';
    const DEFAULTS_SECTION = 'woocommerce_connector_defaults';
    const OTHER_MAPPINGS_SECTION = 'woocommerce_other_mappings';
    const ACTION_GET_SYSTEM_STATUS = 'getSystemStatus';
    const WPML_CODE_ALREADY_EXIST = 'Failed! SKU already exists.';
    const WPML_GET_DATA = 'getWpmlProduct';
    const WPML_INVALID_CODE = 'Failed! Product id not exists.';

    protected $mainAttributes = [
        'sku',
        'name'
    ];

    protected $mappedFields;
    protected $defaultValues;
    protected $otherMappedFields;

    protected $locale;
    protected $baseCurrency;
    protected $systemStatus;
    protected $obj;
    protected $parameters;

    
    /**
     * write products to WooCommerce
     */
    public function write(array $items)
    {
        
        if (!$this->parameters) {
            $this->parameters = $this->stepExecution->getJobParameters();
            
        }
        
        if ($this->getJobName() == 'woocommerce_quick_export') {
            
            $exportProfile1 = $this->connectorService->getDefaultCredential() ? $this->connectorService->getDefaultCredential()->getId() : '';
            
            $exportProfile = strval($exportProfile1);
            
            
        } else {
            
            $params = $this->stepExecution ? $this->stepExecution->getJobparameters()->all() : null;
            
            $exportProfile = (!empty($params['exportProfile'])) ? $params['exportProfile'] : "";
            
        }
        
       
        
        $settings = $this->connectorService->getMultiSetting('settings'); //$this->connectorService->getSettings(self::SETTING_SECTION);
        $classex = 'Webkul\WpmlProductBundle\Connector\Writer\Product';
        if (class_exists($classex) && isset($settings['enable_wpml']) && $settings['enable_wpml'] == "on") {
            if ($this->obj == '') {
                $this->obj = new $classex($this->connectorService);
                $this->obj->setStepExecution($this->stepExecution);
                $this->obj->writeWpml($items,$exportProfile);
            } else {
                $this->obj->writeWpml($items,$exportProfile);
            }
        } else {
            
            
            if (!$this->systemStatus) {
                $getSystemStatus = $this->connectorService->requestApiAction(
                    self::ACTION_GET_SYSTEM_STATUS,
                    [],
                    ["exportProfile" => $exportProfile]
                );
                
                
                if (isset($getSystemStatus['code']) && $getSystemStatus['code'] != "200") {
                    
                    $this->stepExecution->addWarning($getSystemStatus['code'], [], new \DataInvalidItem([json_encode($this->systemStatus)]));
                    $this->stepExecution->setTerminateOnly();
                }
                $this->systemStatus = $getSystemStatus['environment']['version'] ?? null;
            }
            $this->writeSimple($items,$exportProfile);
        }
    }
    
    public function writeSimple($items,$exportProfile)
    { 
        
        $this->locale = $this->getDefaultLanguage();
        $this->baseCurrency = $this->getDefaultCurrency();

        if (!$this->mappedFields) {
            $this->mappedFields = $this->connectorService->getMultiSetting('settings');
            $this->defaultValues = $this->connectorService->getMultiSetting('defaults');
            
            $this->otherMappedFields = $this->connectorService->getMultiOtherMappings();
           
            $this->otherMappedFields['custom_fields'] = array_merge(
                $this->otherMappedFields['custom_fields'],
                ($this->otherMappedFields['files'] ?? [])
            );
        }
        

        $i = 0;
        $len = count($items);
        $settings = $this->connectorService->getMultiSetting('settings'); 
        
        foreach ($items as $item) {
            
            if (!empty($item['parent'])) {
                $item['code'] = $item['parent'];
                $item['type'] = 'variable';
            } else {
                $item['code'] = $item['identifier'];
                $item['type'] = 'simple';
            }

            $mapping = $this->checkMappingInDb($item,$entity = self::AKENEO_ENTITY_NAME,$exportProfile);
             
            $formattedData = $this->formatData($item,$exportProfile);
            $varResult = null;
            if (!empty($mapping)) {

                if ($mapping->getJobInstanceId() === $this->stepExecution->getJobExecution()->getId()) {
                    $reResult = [ 'id' => $mapping->getExternalId() ];
                
                } else {
                   
                    if ($this->parameters->has('switchForUpdate') && $this->parameters->get('switchForUpdate')) {
                        $updateTrack = $this->connectorService->getEntityTrackByEntityAndCode(self::AKENEO_ENTITY_NAME, $item['code']);
                        if (!$updateTrack) {
                            $this->stepExecution->incrementSummaryInfo('update');
                            continue;
                        }
                    }
                   
                    $result = $this->connectorService->requestApiAction(
                        self::ACTION_UPDATE,
                        $formattedData,
                        ['id' => $mapping->getExternalId(), "exportProfile" => $exportProfile]
                    );    
                    $reResult = $this->handleAfterApiRequest($item, $result, $mapping);
                    if (isset($updateTrack)) {
                        $this->connectorService->removeTrack($updateTrack);
                    }
                    $this->stepExecution->incrementSummaryInfo('update');
                }
            } else { 
                 
                
                $result = $this->connectorService->requestApiAction(
                    self::ACTION_ADD,
                    $formattedData,
                    ["exportProfile" => $exportProfile]
                );
                
                $reResult = $this->handleAfterApiRequest($item, $result,$mapping=null);
 
                $this->stepExecution->incrementSummaryInfo('create');
                if ($item['type'] == 'variable') {
                    $this->connectorService->updateOrCreateTrackByEntityCodeAndAction(self::AKENEO_ENTITY_NAME, $item['code'], "save",$exportProfile);
                }
            }
            
            if (!empty($reResult) && !empty($item['parent']) && !empty($reResult['id']) && !empty($item['variantAttributes'])) {
                $formattedVariation = $this->formatVariation($item,$exportProfile);
                
                $mapping = $this->checkMappingInDb([
                            'code' => $item['identifier'],
                            'relatedId' => $reResult['id']
                ],$entity = self::AKENEO_ENTITY_NAME,$exportProfile);
                
                if (!$mapping) {
                    $this->reMappingExisingProductVariations($reResult['id'],$exportProfile);
                    
                    $mapping = $this->checkMappingInDb([
                                'code' => $item['identifier'],
                                'relatedId' => $reResult['id']
                    ],$entity = self::AKENEO_ENTITY_NAME,$exportProfile);
                   
                }
                 
                if ($mapping) {
                    
                    $varResult = $this->connectorService->requestApiAction(
                        self::ACTION_UPDATE_VARIATION,
                        $formattedVariation,
                        [   'product' => $reResult['id'],
                            'id' => $mapping->getExternalId(),
                            'exportProfile' => $exportProfile
                                    ]
                    );
                    if (!empty($varResult['code']) && $varResult['code'] == self::CODE_DELETED_VARIATION) {
                        $this->connectorService->deleteMapping($mapping);
                        $mapping = null;
                    }
                }
                if (empty($mapping)) {
                    $varResult = $this->connectorService->requestApiAction(
                        self::ACTION_ADD_VARIATION,
                        $formattedVariation,
                        [ 'product' => $reResult['id'], 'exportProfile' => $exportProfile ]
                    );
                }
                
                if (!empty($varResult['code']) && ($varResult['code'] == 201 || $varResult['code'] == 200)) {
                     
                    $this->connectorService->addOrUpdateMapping(
                        $mapping,
                        $item['identifier'],
                        self::AKENEO_ENTITY_NAME,
                        '',
                        $exportProfile,
                        $varResult['id'],
                        $reResult['id']
                    );
                    
                } elseif (isset($item['identifier'])) {
                    $varResult = $this->connectorService->requestApiAction(
                        self::ACTION_ADD_VARIATION,
                        $formattedVariation,
                        [ 'product' => $reResult['id'], 'exportProfile' => $exportProfile ]
                    );
                }
            } else {
                $error = true;
            }
        }
            
        if (isset($settings['enableDelete']) && $settings['enableDelete'] == "on") {
            $this->deleteDataMappingAndData(self::AKENEO_ENTITY_NAME,$exportProfile);
        }
         
    }
    
    protected function reMappingExisingProductVariations($productId,$exportProfile)
    {
 
        $exisitingProductVariations = $this->connectorService->requestApiAction(
            'getVariation',
            null,
            [ 'product' => $productId, 'exportProfile' => $exportProfile]
        );

        if (isset($exisitingProductVariations['code']) && 200 === $exisitingProductVariations['code']) {
            foreach ($exisitingProductVariations as $productVariation) {
                if (!isset($productVariation['id'])) {
                    continue;
                }

                $externalId = $productVariation['id'];
                $identifier = $productVariation['sku'];
    
                $mapping = $this->checkMappingInDb([
                    'code' => $identifier,
                    'relatedId' => $productId,
                    'externalId' => $externalId
                ], self::AKENEO_ATTRIBUTE_ENTITY_NAME,$exportProfile);

                $this->connectorService->addOrUpdateMapping(
                    $mapping,
                    $identifier,
                    self::AKENEO_ENTITY_NAME,
                    $externalId,
                    $exportProfile,
                    $productId,
                    ''
                    
                );
            }
        }
    }

    protected function formatData($item,$exportProfile)
    {
        
        $selectVariation = $this->connectorService->getAttributeCodes('pim_catalog_simpleselect');
        $multiSelectVariation = $this->connectorService->getAttributeCodes('pim_catalog_multiselect');

        $wcVersion = $this->systemStatus;     
        
        $formatted = [
            'name' => $item['code'],
            'slug' => $item['code'],
            'sku' => $item['code'],
            'status' => $item['enabled'] ? 'publish' : 'draft',
            'type' => $item['type'],
            'description' => !empty($item['description']) ? $item['description'] : '' ,
        ];

       
        $values = $item['values'];
        if (!empty($item['allVariantAttributes'])) {
            foreach ($values as $key => $value) {
                if (in_array($key, $item['allVariantAttributes']) && !in_array($key, $item['variantAttributes'])) {
                    unset($values[$key]);
                }
            }
        }
        $attributes = $this->formatAttributes($values);
        
        $duplicateAttributes = $attributes;
        /* main attributes */
        
       
        foreach ($this->mappedFields as $name => $field) {
            if (is_array($duplicateAttributes) && array_key_exists($field, $duplicateAttributes)) {
                if (!empty($this->wrapper[$name])) {
                    $formatted[$this->wrapper[$name]][$name] = (string)round($duplicateAttributes[$field]);
                } else {
                    if ($name == 'slug') {
                        $formatted[$name] = $duplicateAttributes[$field]."_".$item['code'];
                    } else {
                        $formatted[$name] = $duplicateAttributes[$field];
                    }
                    $this->addDependentField($formatted, $name, $duplicateAttributes[$field]);
                }
                unset($attributes[$field]);
            }
        }
      
        /* default values */
        if (isset($this->defaultValues) && !empty($this->defaultValues)) {
            foreach ($this->defaultValues as $name => $value) {
                if($value !== '') {
                    if (!empty($this->wrapper[$name])) {
                        $formatted[$this->wrapper[$name]][$name] = $value;
                    } else {
                        $formatted[$name] = $value;
                        $this->addDependentField($formatted, $name, $value);
                    }
                }
               
            }
        }
       
        if (empty($formatted['weight'])) {
            $formatted['virtual'] = true;
        } else {
            $formatted['virtual'] = false;
        }

        $imageAttrsCodes = $this->connectorService->getImageAttributeCodes();

        $imageAssetsAttrsCodes = $this->connectorService->getAssetsImageAttributeCodes();

        
        $imageAttrsMappedCodes = array();
        // mapped image attributes
        if (isset($this->otherMappedFields['images'])) {
            $imageAttrsinDB = $this->otherMappedFields['images'];
            $imageAttrsMappedCodes = array_intersect($imageAttrsCodes, $imageAttrsinDB);
            $imageAssetAttrsMappedCodes = array_intersect($imageAssetsAttrsCodes, $imageAttrsinDB);

        }

        $customAttrs = [];
        $imageAttrs = [];
        $settings = $this->connectorService->getSettings('settings'); //$this->connectorService->getSettings(self::SETTING_SECTION);
        /* other attributes */
        foreach ($attributes as $code => $value) {
            if (!in_array($code, $this->mainAttributes)) {
                
                /* image attrs */
                $enableSelect = isset($settings['enableSelect']) ? filter_var($settings['enableSelect'], FILTER_VALIDATE_BOOLEAN) : false;
                
                if (in_array($code, $imageAttrsMappedCodes)) {
                    $imageUrl = $this->createImageUrl($value);
                    
                    if ($imageUrl) {
                        if ($value) {
                            $attrAsImage = (!empty($item['attributeAsImage']) && $item['attributeAsImage'] === $code);
                            if ($attrAsImage || (count($imageAttrs) == 0 && (empty($item['attributeAsImage']) || empty($attributes[$item['attributeAsImage']])))) {
                                $id = $this->checkImagesExported($item, $imageUrl,$exportProfile);
                                if ($id) {
                                    $imageAttrs[] = [
                                        'id' => $id,
                                        'position' => 0
                                    ];
                                } else {
                                    $imageAttrs[] = [
                                        'src' => $imageUrl,
                                        'position' => 0,
                                        'name' => $this->getImageName($imageUrl)
                                    ];
                                }
                            } else {
                                $id = $this->checkImagesExported($item, $imageUrl,$exportProfile);
                                if ($id) {
                                    $imageAttrs[] = [
                                        'id' => $id
                                    ];
                                } else {
                                    $imageAttrs[] = [
                                        'src' => $imageUrl,
                                        'name' => $this->getImageName($imageUrl)
                                    ];
                                }
                            }
                        }
                    }
                } else if(in_array($code, $imageAssetAttrsMappedCodes)) {
                    $assetAttrValue = $this->connectorService->convertAssetToPath($value);                    
                    foreach ($assetAttrValue['data'] as $assetkey => $assetValue) {
                        $imageUrl = $this->createImageUrl($assetValue);
                        
                        $id = $this->checkImagesExported($item, $imageUrl,$exportProfile);
                        if ($id) {
                            $imageAttrs[] = [
                                'id' => $id,
                            ];
                        } else {
                            $imageAttrs[] = [
                                'src' => $imageUrl,
                                'name' => $this->getImageName($imageUrl)
                            ];
                        }
                    }

                } else {

                    $settings = $this->connectorService->getMultiSetting('settings'); //$this->connectorService->getSettings(self::SETTING_SECTION);
                    if ($value) {
                        
                        $attributeMapping = $this->checkMappingInDb(['code' => $code], self::AKENEO_ATTRIBUTE_ENTITY_NAME,$exportProfile);
                        
                        if (version_compare($wcVersion, '3.2.6', '>')) {
                            if (isset($this->otherMappedFields['custom_fields'])) {
                                $custAttrsinDB = $this->otherMappedFields['custom_fields'];
                                    
                                if (!in_array($code, $selectVariation) && !in_array($code, $multiSelectVariation)) {
                                    if (in_array($code, $custAttrsinDB)) {
                                        if (in_array($code, $this->connectorService->getNumberAttributeCodes())) {
                                            if (!is_array($value)) {
                                                $value = (float)$value;
                                                $value = [ (string)$value ];
                                            }
                                        } else {
                                            if (!is_array($value)) {
                                                $value = [ (string)$value ];
                                            }
                                        }
                                            
                                            
                                        if (!$enableSelect) {
                                            $customAttr = [
                                                    'name' =>  $this->connectorService->getAttributeLabelByCodeAndLocale($code, $this->locale),
                                                    'visible' => true,
                                                    'variation' => false,
                                                    'options' => $value
                                                ];

                                            $customAttrs[] = $customAttr;
                                        } else {
                                            $this->createOptions($code, $item, $this->locale);
                                        }
                                    }
                                }
                            }
                        }
                    }
                        
                    if (!$enableSelect) {
                        if (isset($attributeMapping) && $attributeMapping && $attributeMapping->getCode()) {
                            $selectAttributeCodes = $this->connectorService->getSelectAttributeCodes();
                            if (!in_array($attributeMapping->getCode(), $selectAttributeCodes) && !in_array($attributeMapping->getCode(), $multiSelectVariation)) {
                                $attributeMapping = '';
                            }
                        }
                    }
                    if (isset($attributeMapping) && $attributeMapping && $attributeMapping->getExternalId()) {
                        $customAttr = [
                                'id' => $attributeMapping->getExternalId(),
                                'visible' => true,
                                'variation' => (!empty($item['variantAttributes']) && in_array($code, $item['variantAttributes']) ? true : false),
                            ];
                            
                        if ((!empty($item['variantAttributes']) && in_array($code, $item['variantAttributes']) ? true : false)) {
                            $options = $this->connectorService->getOptionsByAttribute($code, $this->locale);
                                
                            $customAttr['options'] = $options;
                            $customAttr['visible'] = false;
                        } else {
                            //custome attribute mapped by database
                            if (isset($this->otherMappedFields['custom_fields'])) {
                                $custAttrsinDB = $this->otherMappedFields['custom_fields'];
                                    
                                if (in_array($code, $custAttrsinDB)) {
                                    if (!is_array($value)) {
                                        $value = [ (string)$value ];
                                    }
                                    $customAttr['options'] = $value;
                                }
                            }
                        }

                        $customAttrs[] = $customAttr;
                    }
                }
            }
        }

        $formatted['attributes'] = $customAttrs;
    
        
        if ($this->connectorService->checkAws3module()) {
           
            if ($imageAttrs) {
                
                $formatted['images'] = $imageAttrs;
            }
        } elseif ($this->isHttpsScheme()) {
           
            if ($imageAttrs) {
                $formatted['images'] = $imageAttrs;
            }
        } else {
           
            $this->stepExecution->addWarning('Images not uploaded, to enable images upload setup https on this server and save credentials once again.', [], new \DataInvalidItem([]));
        }

        
        /* add associate product */
        if (isset($item['associations'])) {
            $mappedAssociations = $this->connectorService->getSettings('woocommerce_association_mapping');
            if (!empty($mappedAssociations)) {
                foreach ($mappedAssociations as $key => $value) {
                    if (isset($item['associations'][$value]) && ($item['associations'][$value]['products'] || $item['associations'][$value]['product_models'])) {
                        foreach ($item['associations'][$value]['products'] as $sku) {
                            $mapping = $this->connectorService->getMappingByCode($sku, 'product', $exportProfile);
                            
                            if (!empty($mapping)) {
                                $formatted[$key][] = $mapping->getExternalId();
                            }
                        }
                        foreach ($item['associations'][$value]['product_models'] as $sku) {
                            $mapping = $this->connectorService->getMappingByCode($sku, 'product', $exportProfile);
                            
                            if (!empty($mapping)) {
                                $formatted[$key][] = $mapping->getExternalId();
                            }
                        }
                    }
                }
            }
        }
            

        /* categories */
        $categories = [];
        foreach ($item['categories'] as $code) {
            $categoryMapping = $this->checkMappingInDb(['code' => $code], self::AKENEO_CATEGORY_ENTITY_NAME,$exportProfile);
            if ($categoryMapping && $categoryMapping->getExternalId()) {
                $categories[] = [
                    'id' => $categoryMapping->getExternalId(),
                ];
            }
        }

        $formatted['categories'] = $categories;
        
        return $formatted;
    }
    
    protected function addDependentField(&$formatted, $key, $value)
    {
        switch ($key) {
            case 'stock_quantity':
                $formatted['stock_quantity'] = (int)$formatted['stock_quantity'];
                $formatted['manage_stock'] = true;
                $formatted['in_stock'] = (boolean)$value;
                break;
            case 'reviews_allowed':
            case 'featured':
                $formatted[$key] = (boolean)$value;
                break;
            case 'backorders_allowed':
                $formatted['backorders'] = ((boolean)$formatted['backorders_allowed']) ? 'yes' : 'no';
                unset($formatted['backorders_allowed']);
                break;
        }
    }

    protected function formatVariation($item,$exportProfile)
    {
        
        $variantAttributes = !empty($item['variantAttributes']) ? $item['variantAttributes'] : [];

        $attributes = $this->formatAttributes($item['values']);
        
        $formatted = [
            'attributes' => [
            ],
        ];
        if (isset($attributes['sku'])) {
            $formatted['sku'] = $attributes['sku'];
        }

        /* add possible variant fields */
        foreach (['regular_price', 'stock_quantity', 'weight', 'length', 'width', 'height', 'backorders_allowed'] as $varField) {
            $fieldAlias = !empty($this->mappedFields[$varField]) ? $this->mappedFields[$varField] : null;
            
            if ($fieldAlias && isset($attributes[$fieldAlias])) {
               
                if (!empty($this->wrapper[$varField])) {
                    $formatted[$this->wrapper[$varField]][$varField] = (string)$attributes[$fieldAlias];
                } else {
                    $formatted[$varField] = $attributes[$fieldAlias];
                }
                if ($varField == 'stock_quantity' && !empty($attributes[$fieldAlias]) && in_array($fieldAlias, $item['allVariantAttributes'])) {
                    $formatted['manage_stock'] = true;
                }
                if ($varField == 'backorders_allowed') {
                    $formatted['backorders'] = ((boolean)$formatted['backorders_allowed']) ? 'yes' : 'no';
                    unset($formatted['backorders_allowed']);
                }
            }
        }

        foreach ($this->defaultValues as $name => $value) {
            if (!in_array($name, $item['variantAttributes'])) {
                if (!empty($this->wrapper[$name])) {
                    $formatted[$this->wrapper[$name]][$name] = $value;
                } else {
                    $formatted[$name] = $value;
                    $this->addDependentField($formatted, $name, $value);
                }
            }
        }

        /* add options in variation (variation axes) */
        foreach ($variantAttributes as $varAttribute) {
            if (is_array($attributes) && array_key_exists($varAttribute, $attributes)) {
                $attributeMapping = $this->checkMappingInDb(['code' => $varAttribute], self::AKENEO_ATTRIBUTE_ENTITY_NAME,$exportProfile);
                if ($attributeMapping && $attributeMapping->getExternalId()) {
                    if (!empty($attributes[$varAttribute]) && !is_array($attributes[$varAttribute])) {
                        $optionValue = $attributes[$varAttribute];

                        $formatted['attributes'][] = [
                            'id' => $attributeMapping->getExternalId(),
                            'option' => (string) $optionValue,
                        ];
                    }
                } else {
                    $this->stepExecution->addWarning(sprintf('Make sure %s attribute is select type and added in custom field mapping. otherwise add it in cutsom field mapping and export attribute and product again.', $varAttribute), [], new \DataInvalidItem([]));
                    return;
                }
            }
        }
        /* to get items out of trash */
        $formatted['visible'] = $item['enabled'] ? true : false;

        /* get enable or disable variant */
        $formatted['status'] = $item['enabled'] ? 'publish' : 'private';
        // $formatted['purchasable'] = true;

        /* add variant wise images */
        if ($this->isHttpsScheme() && !empty($item['allVariantAttributes'])) {
            $imageAttrsCodes = $this->connectorService->getImageAttributeCodes();
            $imageAssetsAttrsCodes = $this->connectorService->getAssetsImageAttributeCodes();


            $imageAttrsMappedCodes = array();
            if (isset($this->otherMappedFields['images'])) {
                if (gettype($this->otherMappedFields['images']) == 'string') {
                    $imageAttrsinDB = array_map('trim', explode(',', $this->otherMappedFields['images']));
                } else {
                    $imageAttrsinDB = $this->otherMappedFields['images'];
                }
                $imageAttrsMappedCodes = array_intersect($imageAttrsCodes, $imageAttrsinDB);
                $imageAssetAttrsMappedCodes = array_intersect($imageAssetsAttrsCodes, $imageAttrsinDB);

            }
            foreach ($imageAssetAttrsMappedCodes as $attrCode) {
                if (in_array($attrCode, $item['allVariantAttributes']) && !empty($attributes[$attrCode])) {
                    $value = $this->formatValue($attributes[$attrCode]);
                    $assetAttrValue = $this->connectorService->convertAssetToPath($value);                    
                    foreach ($assetAttrValue['data'] as $assetkey => $assetValue) {
                        $imageUrl = $this->connectorService->generateImageUrl($assetValue);
                        if ($imageUrl) {
                            $id = $this->checkImagesExported($item, $imageUrl,$exportProfile);
                            if (!$id) {
                                $formatted['image'] = [
                                    "src" => $imageUrl,
                                    'name' => $this->getImageName($imageUrl)
                                ];
                            } else {
                                $formatted['image'] = [
                                    "id" => $id,
                                ];
                            }
                            break;
                        }
                    }
                }
            }


            foreach ($imageAssetAttrsMappedCodes as $attrCode) {
                if (in_array($attrCode, $item['allVariantAttributes']) && !empty($attributes[$attrCode])) {
                    $value = $this->formatValue($attributes[$attrCode]);
                    $assetAttrValue = $this->connectorService->convertAssetToPath($value);                    
                    foreach ($assetAttrValue['data'] as $assetkey => $assetValue) {
                        $imageUrl = $this->connectorService->createImageUrl($assetValue);
                        if ($imageUrl) {
                            $id = $this->checkImagesExported($item, $imageUrl,$exportProfile);
                            if (!$id) {
                                $formatted['image'] = [
                                    "src" => $imageUrl,
                                    'name' => $this->getImageName($imageUrl)
                                ];
                            } else {
                                $formatted['image'] = [
                                    "id" => $id,
                                ];
                            }
                            break;
                        }
                    }
                }
            }

    
        }
        return $formatted;
    }

    protected function formatAttributes($attributes)
    {
        
        $selectAttributeCodes = $this->connectorService->getSelectAttributeCodes();
        $fileAttributeCodes = $this->otherMappedFields['files'] ?? [];
        $multiSelectAttributeCodes = $this->connectorService->getMultiSelectAttributeCodes();
        
        foreach ($attributes as $name => $value) {
            $attributes[$name] = $this->formatValue($value);
            if ($attributes[$name] && in_array($name, $selectAttributeCodes)) {
                if ('string' == gettype($attributes[$name])) {
                    $optionLabel = $this->getOptionNameByCode($name . '.' . $attributes[$name]);
                    if ($optionLabel) {
                        $attributes[$name] = $optionLabel;
                    }
                } elseif ('array' == gettype($attributes[$name])) {
                }
            } elseif ($attributes[$name] && in_array($name, $multiSelectAttributeCodes)) {
                if ('array' == gettype($attributes[$name])) {
                    foreach ($attributes[$name] as $key => $optionsCode) {
                        $optionLabel = $this->getOptionNameByCode($name . '.' . $optionsCode);
                        if ($optionLabel) {
                            unset($attributes[$name][$key]);
                            $attributes[$name][$key] = $optionLabel;
                        }
                    }
                }
            } elseif (in_array($name, $fileAttributeCodes)) {
                $attributes[$name] = $this->connectorService->generateFileUrl($attributes[$name]);
            }
        }
       
        return $attributes;
    }


    

    /**
    * format clustered akeneo value data into single formatValue (can filter locale wise, currency wise)
    * @param Array value
    * @return  string $value
    */
    private function formatValue($value)
    {
        if (is_array($value)) {
            foreach ($value as $key => $aValue) {
                if (is_array($aValue)) {
                    if (array_key_exists('locale', $aValue)) {
                        if (!$aValue['locale'] || $aValue['locale'] == $this->locale) {
                            $value = $aValue['data'];
                            break;
                        }
                        if ($key == count($value)-1) {
                            $value = null;
                        }
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            }
        }
        if ($value && is_array($value)) {
            /* price */
            foreach ($value as $key => $aValue) {
                if (is_array($aValue)) {
                    if (array_key_exists('currency', $aValue)) {
                        if (!$aValue['currency'] || $aValue['currency'] == $this->baseCurrency) {
                            $value = $aValue['amount'];
                            break;
                        }
                        if($key == count($value)-1) {
                            $value = !empty($value[0]['amount']) ? $value[0]['amount'] : null ;
                        }
                    }
                } else {
                    break;
                }
            }
            /* metric */
            if (is_array($value) && array_key_exists('unit', $value)) {
                $settings = $this->connectorService->getMultiSetting('settings'); //$this->connectorService->getSettings(self::SETTING_SECTION);
                
                if (!empty($settings['enableUnit']) && $settings['enableUnit'] == "on") {
                    $value = (float)$value['amount']." ".$value['unit'];
                
                } else {
                    $value = !empty($value['amount']) ? $value['amount'] : null;
                }
            }
        }
        
        return $value;
    }

    protected function createImageUrl($filename, $id=null, $host = null)
    {
        return $this->connectorService->generateImageUrl($filename,$id, $host);
    }

    private function getOptionNameByCode($code)
    {
        $option = $this->connectorService->getOptionByCode($code);
        if ($option) {
            $option->setLocale($this->locale);
            $optionValue = $option->__toString() !== '[' . $code . ']' ? $option->__toString() : $code;

            return $optionValue;
        }
    }

    /**
    * check https available on server (makes use of scheme saved while saving credentials)
    * @return boolean true/false
    */
    protected function isHttpsScheme()
    {
        $credentials = $this->connectorService->getCredentials();
        return !empty($credentials['scheme']) && 'https' === $credentials['scheme'];
    }

    public function filterFormattedValue($formattedValue)
    {
        $arrayCountValues = array_count_values(array_column($formattedValue['attributes'], 'name'));
       

        foreach ($arrayCountValues as $countKey => $countValue) {
            $i = 0;
            foreach ($metaFields as $key => $value) {
                if ($value['key'] == $countKey) {
                    if ($i > 0) {
                        unset($metaFields[$key]);
                        $this->stepExecution->addWarning('meta field key is not unique', [], new \DataInvalidItem([$value['key']]));
                    }
                }
                $i++;
            }
        }
    }

    public function getImageName($imageurl)
    {
        $getCode = explode('/', $imageurl);
        $code = end($getCode);
        $name = explode('_', $code);
        unset($name[0]);
        $getName = implode("_", $name); 
        if ($getName) {
            return $getName;
        }
        

        return null;
    }

    public function checkImagesExported($item, $imageUrl,$exportProfile)
    {
        $imageName = $this->getImageName($imageUrl);
        $code = $item['code'].'-'.$imageName;
        $checkItem = $this->checkMappingInDb($item,$entity = self::AKENEO_ENTITY_NAME,$exportProfile);
        if (!$checkItem) {
            return false;
        }
        $imageMapping = $this->connectorService->getMappingByCode($code, "image",$exportProfile);
        if (!$imageMapping) {
            return false;
        }
       
        return $imageMapping->getExternalId();
    }
    /*
    * wrapper needed to add some indexes in product api
    */
    protected $wrapper = [
        'length' => 'dimensions',
        'width' => 'dimensions',
        'height' => 'dimensions',
    ];
}