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

namespace WriteTextAI\WriteTextAI\Model\Config\Source;

use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributeCollectionFactory;
use Magento\Framework\Data\OptionSourceInterface;
use WriteTextAI\WriteTextAI\Model\Config\Source\ProductAttributes\Excluded;
use Magento\Store\Model\ScopeInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;

class ProductAttributes implements OptionSourceInterface
{
    public const MAPPING_SETTINGS_CONFIG_PATH = 'writetextai_settings/mapping';

    public const PRODUCT_RESEARCH_DATA_ATTRIBUTE_CODE = 'wtai_product_research_data';

    public const CUSTOMIZABLE_OPTIONS_ATTRIBUTE_CODE = 'wtai_customizable_options';

    public const CUSTOMIZABLE_OPTIONS_WITH_VALUES_ATTRIBUTE_CODE = 'wtai_customizable_options_with_values';

    /**
     * @var AttributeCollectionFactory
     */
    protected $attributeCollectionFactory;
    
    /**
     * @var ScopeConfigInterface
     */
    protected $scopeConfig;

    /**
     * Constructor
     *
     * @param AttributeCollectionFactory $attributeCollectionFactory
     * @param ScopeConfigInterface $scopeConfig
     */
    public function __construct(
        AttributeCollectionFactory $attributeCollectionFactory,
        ScopeConfigInterface $scopeConfig
    ) {
        $this->attributeCollectionFactory = $attributeCollectionFactory;
        $this->scopeConfig = $scopeConfig;
    }

    /**
     * Get options
     *
     * @return array
     */
    public function toOptionArray()
    {
        $attributes = $this->attributeCollectionFactory->create()
            ->addVisibleFilter();
        
        $options = [];
        
        $mappedAttributes = array_values((array)$this->getMappingSettings());
        $exclude = array_merge(
            $mappedAttributes,
            Excluded::GENERATE_SETTINGS_EXCLUDE_ATTRIBUTES
        );
        
        foreach ($attributes as $attribute) {
            if (in_array(
                $attribute->getAttributeCode(),
                $exclude
            )) {
                continue;
            }
            $options[] = [
                'id' => $attribute->getAttributeId(),
                'value' => $attribute->getAttributeCode(),
                'label' => $attribute->getFrontendLabel(),
            ];
        }

        usort($options, function ($a, $b) {
            if (strtolower($a['value']) === 'thumbnail') {
                return -1;
            }
            if (strtolower($b['value']) === 'thumbnail') {
                return 1;
            }
            return strcmp($a['label'], $b['label']);
        });

        $productResearchData = [
            'id' => self::PRODUCT_RESEARCH_DATA_ATTRIBUTE_CODE,
            'value' => self::PRODUCT_RESEARCH_DATA_ATTRIBUTE_CODE,
            'label' => __('Product Research'),
        ];
        array_splice($options, 1, 0, [$productResearchData]);

        $customizableOptions = [
            'id' => self::CUSTOMIZABLE_OPTIONS_ATTRIBUTE_CODE,
            'value' => self::CUSTOMIZABLE_OPTIONS_ATTRIBUTE_CODE,
            'label' => __('Customizable options'),
        ];
        array_splice($options, 2, 0, [$customizableOptions]);

        return $options;
    }

    /**
     * Return field value or array of field values
     *
     * @param string|null $path
     * @return array|string
     */
    public function getMappingSettings($path = null)
    {
        $path = $path ? '/' . $path : '';
        return $this->conf(self::MAPPING_SETTINGS_CONFIG_PATH . $path);
    }
    
    /**
     * Get config value
     *
     * @param string $path
     * @param int|null $storeId
     * @return mixed
     */
    public function conf($path, $storeId = null)
    {
        return $this->scopeConfig->getValue($path, ScopeInterface::SCOPE_STORE, $storeId);
    }
}
