<?php
/**
 * @author 1902 Software
 * @copyright Copyright © 2023 1902 Software (https://1902software.com/magento/)
 * @package WriteTextAI_WriteTextAI
 */

namespace WriteTextAI\WriteTextAI\Helper;

use WriteTextAI\WriteTextAI\Helper\Data;
use WriteTextAI\WriteTextAI\Model\Config\Source\ProductAttributes;
use Magento\Catalog\Helper\Output as CatalogOutput;
use Magento\Catalog\Model\Attribute\ScopeOverriddenValueFactory;
use WriteTextAI\WriteTextAI\Model\OptionSource\Filter\Fields as FieldsFilter;

class Fields extends \Magento\Framework\App\Helper\AbstractHelper
{
    public const MEDIA_PATTERN = '<(img).*?>|<(audio|canvas|embed|iframe|video).*?<\/\2>';

    /**
     * @var ProductAttributes
     */
    protected $attributes;

    /**
     * @var Data
     */
    protected $helper;

    /**
     * @var CatalogOutput
     */
    protected $catalogOutput;

    /**
     * @var ScopeOverriddenValueFactory
     */
    protected $scopeOverriddenValueFactory;

    /**
     * @var array
     */
    protected $mappingSettings = [];

    /**
     * @var ScopeOverriddenValueFactory
     */
    protected $scopeOverriddenValueFactoryInstance = null;

    /**
     * Constructor
     *
     * @param ProductAttributes $attributes
     * @param Data $helper
     * @param CatalogOutput $catalogOutput
     * @param ScopeOverriddenValueFactory $scopeOverriddenValueFactory
     */
    public function __construct(
        ProductAttributes $attributes,
        Data $helper,
        CatalogOutput $catalogOutput,
        ScopeOverriddenValueFactory $scopeOverriddenValueFactory
    ) {
        $this->helper = $helper;
        $this->attributes = $attributes;
        $this->catalogOutput = $catalogOutput;
        $this->scopeOverriddenValueFactory = $scopeOverriddenValueFactory;
    }
    
    /**
     * Get mapping settings value
     *
     * @return array
     */
    public function getMappingSettingsValue()
    {
        if (empty($this->mappingSettings)) {
            $this->mappingSettings = $this->helper->getMappingSettings();
        }
        return $this->mappingSettings;
    }

    /**
     * Check if using default values
     *
     * @param \Magento\Catalog\Model\Product $product
     * @param int $storeId
     * @param string $field
     * @return bool
     */
    public function isUsingDefaultValues($product, $storeId, $field)
    {
        $isOverriden = $this->scopeOverriddenValueFactory->create()->containsValue(
            \Magento\Catalog\Api\Data\ProductInterface::class,
            $product,
            $field,
            $storeId
        );

        return !$isOverriden;
    }

    /**
     * Get field mappings
     *
     * @return array
     */
    public function getFieldLabels()
    {
        $mapping = $this->getMappingSettingsValue();
        $fields = [];

        $attributes = $this->attributes->toOptionArray();

        foreach ($attributes as $attribute) {
            foreach ($mapping as $key => $value) {
                if ($value == $attribute['value']) {
                    $fields[$key] = [
                        'attribute' => $value,
                        'label' => 'Magento ' . $attribute['label']
                    ];
                }
            }
        }

        return $fields;
    }

    /**
     * Get attributes values
     *
     * @param \Magento\Catalog\Api\Data\ProductInterface $product
     * @param string $field
     * @return string
     */
    public function getAttributesValues($product, $field)
    {
        return $this->helper->getAttributesValues($product, $field);
    }

    /**
     * Check if directive exists
     *
     * @param \Magento\Catalog\Api\Data\ProductInterface $product
     * @param string $field
     * @return bool
     */
    public function isDirectiveExists($product, $field)
    {
        $mapping = $this->getMappingSettingsValue();
        $value = '';
        if (isset($mapping[$field])) {
            $attribute = $mapping[$field];
            $value = $product->getData($attribute);
        }

        $hasDirective = false;
        $hasMedia = false;
        if ($value) {
            $hasDirective = $this->catalogOutput->isDirectivesExists($value);

            $filteredValue = $this->getAttributesValues($product, $field);
            $hasMedia = $this->hasMedia($filteredValue);
        }

        return $hasDirective || $hasMedia;
    }

     /**
      * Check if value has media

      * @param string $value
      * @return bool
      */
    public function hasMedia($value)
    {
        $regEx = '/'.self::MEDIA_PATTERN . '/si';
        if (preg_match_all($regEx, $value, $matches, PREG_SET_ORDER)) {
            return true;
        }
        
        return false;
    }

    /**
     * Change property names
     *
     * @param array $data
     * @param array $mapping
     * @return array
     */
    public function changePropertyNames(&$data, $mapping)
    {
        foreach ($data as $key => &$value) {
            if (is_array($value)) {
                $this->changePropertyNames($value, $mapping);
            }
    
            if (isset($mapping[$key])) {
                $data[$mapping[$key]] = $value;
                unset($data[$key]);
            }
        }
    }

    /**
     * Get field text type
     *
     * @param string $field
     * @return string
     */
    public function getFieldTextType($field)
    {
        switch ($field) {
            case FieldsFilter::PAGE_TITLE:
                return 'page_title';
            case FieldsFilter::PAGE_DESCRIPTION:
                return 'page_description';
            case FieldsFilter::PRODUCT_DESCRIPTION:
                return 'product_description';
            case FieldsFilter::EXCERPT:
                return 'short_product_description';
            case FieldsFilter::OPEN_GRAPH:
                return 'open_graph';
            default:
                return $field;
        }
    }
}
