<?php

namespace Webkul\TableAttributeBundle\ArrayConverter\FlatToStandard;

use Pim\Component\Catalog\Repository\LocaleRepositoryInterface;
use Pim\Component\Connector\ArrayConverter\ArrayConverterInterface;
use Pim\Component\Connector\ArrayConverter\FieldsRequirementChecker;
use Pim\Component\Connector\Exception\StructureArrayConversionException;
use Webkul\DamBundle\Listener\ClassDefinationForCompatibility;

$versionCompatiblility = new ClassDefinationForCompatibility();
$versionCompatiblility->createClassAliases();
/**
 * Convert flat format to standard format for attribute column
 *
 * @author    Jitendra Singh <jitendra@webkul.com>
 * @copyright Webkul Software Pvt Ltd (https://www.webkul.com)
 */
class AttributeColumn implements ArrayConverterInterface
{
    /** @var LocaleRepositoryInterface */
    protected $localeRepository;

    /** @var FieldsRequirementChecker */
    protected $fieldChecker;

    /**
     * @param LocaleRepositoryInterface $localeRepository
     * @param FieldsRequirementChecker  $fieldChecker
     */
    public function __construct(
        LocaleRepositoryInterface $localeRepository,
        FieldsRequirementChecker $fieldChecker
    ) {
        $this->localeRepository = $localeRepository;
        $this->fieldChecker = $fieldChecker;
    }

    /**
     * {@inheritdoc}
     *
     * Converts flat csv array to standard structured array:
     *
     * Before:
     * {
     *     'attribute': 'maximum_print_size',
     *     'code': '210_x_1219_mm',
     *     'sort_order': '2',
     *     'type': text,
     *     'validations': '{0: "email", 1: "required"}',
     *     'options': null,
     *     'label-de_DE': '210 x 1219 mm',
     *     'label-en_US': '210 x 1219 mm',
     *     'label-fr_FR': '210 x 1219 mm'
     * }
     *
     * After:
     * {
     *     'attribute': 'maximum_print_size',
     *     'code': '210_x_1219_mm',
     *     'sort_order': 2,
     *     'type': text,
     *     'validations': {
     *          0: "email",
     *          1: "required"
     *      },
     *     'options': null,
     *     'labels': {
     *         'de_DE': '210 x 1219 mm',
     *         'en_US': '210 x 1219 mm',
     *         'fr_FR': '210 x 1219 mm'
     *     }
     * }
     */
    public function convert(array $item, array $options = [])
    {
        $this->validate($item);
        $convertedItem = ['labels' => []];
        foreach ($item as $field => $data) {
            $isLabel = false !== strpos($field, 'label-', 0);
            if ($isLabel) {
                $labelTokens = explode('-', $field);
                $labelLocale = $labelTokens[1];
                $convertedItem['labels'][$labelLocale] = $data;
            } else {
                if (in_array($field, ['validations', 'options'])) {
                    $convertedItem[$field] = json_decode($data, true);
                } else {
                    $convertedItem[$field] = $data;
                }
            }
        }
        if (isset($convertedItem['sort_order'])) {
            $convertedItem['sort_order'] = (int) $convertedItem['sort_order'];
        }

        return $convertedItem;
    }

    /**
     * @param array $item
     *
     * @throws StructureArrayConversionException
     */
    protected function validate(array $item)
    {
        $requiredFields = ['attribute', 'code'];

        $this->fieldChecker->checkFieldsPresence($item, $requiredFields);

        $authorizedFields = array_merge($requiredFields, ['sort_order', 'type', 'validations', 'options']);

        $localeCodes = $this->localeRepository->getActivatedLocaleCodes();
        foreach ($localeCodes as $code) {
            $authorizedFields[] = 'label-' . $code;
        }

        foreach (array_keys($item) as $field) {
            if (!in_array($field, $authorizedFields)) {
                throw new StructureArrayConversionException(
                    sprintf(
                        'Field "%s" is provided, authorized fields are: "%s"',
                        $field,
                        implode(', ', $authorizedFields)
                    )
                );
            }
        }
    }
}
