<?php
declare(strict_types=1);

namespace FiloBlu\Refilo\Plugins;

use Magento\Framework\Api\AttributeValue;
use Magento\Framework\Api\CustomAttributesDataInterface;

/**
 * MNTFOS-1255.
 *
 * Magento\Customer\Model\Address\AbstractAddress::setData() converte gli oggetti
 * AttributeValue passati a setCustomAttributes() in array grezzi {attribute_code, value}
 * (via __toArray()) invece di estrarne il solo valore. isAddressMultilineAttribute()
 * tratta poi QUALSIASI custom attribute EAV di customer_address come "multiriga",
 * quindi il pacchetto {attribute_code, value} viene confuso per un elenco di righe e
 * unito con implode("\n", ...), producendo "<attribute_code>\n<valore>" (es. "note\nConsegnare al bar").
 *
 * Questo plugin ripristina il valore corretto subito dopo setCustomAttributes(),
 * scrivendolo tramite setCustomAttribute() (singolare), che assegna direttamente
 * $this->_data['custom_attributes'][$code] bypassando il setData() difettoso di
 * AbstractAddress.
 *
 * @see https://filoblu.atlassian.net/browse/MNTFOS-1255
 */
class FixAddressCustomAttributeArrayToStringBug
{
    /**
     * @param CustomAttributesDataInterface $subject
     * @param CustomAttributesDataInterface $result
     * @param array $attributes
     * @return CustomAttributesDataInterface
     */
    public function afterSetCustomAttributes(CustomAttributesDataInterface $subject, $result, array $attributes)
    {
        foreach ($attributes as $code => $attribute) {
            if (!$attribute instanceof AttributeValue) {
                continue;
            }

            $value = $attribute->getValue();
            if (is_array($value)) {
                // Attributo genuinamente multiline (es. frontend_input "multiline"): le righe vengono
                // riunite esattamente come farebbe il core, ma senza lasciare il wrapper {attribute_code, value}.
                $value = trim(implode("\n", array_filter($value, 'is_scalar')));
            }

            if (is_scalar($value)) {
                $subject->setCustomAttribute($code, $value);
            }
        }

        return $result;
    }
}
