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

namespace WriteTextAI\WriteTextAI\Helper;

use Magento\Framework\App\Helper\AbstractHelper;

use Magento\Customer\Api\GroupRepositoryInterface;
use WriteTextAI\WriteTextAI\Model\GenerateOptionsManager;
use Magento\Catalog\Helper\Output as OutputHelper;
use WriteTextAI\WriteTextAI\Model\Config\Source\ProductAttributes\Excluded;
use Magento\Customer\Api\Data\GroupInterface;
use Magento\Catalog\Helper\Image as ImageHelper;
use WriteTextAI\WriteTextAI\Helper\Image as WTAImageHelper;
use Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory;
use Magento\Framework\Exception\FileSystemException;
use WriteTextAI\WriteTextAI\Model\UserFieldsSelectedManager;
use WriteTextAI\WriteTextAI\Model\Config\Source\ProductAttributes as ProductAttributesSource;

class ProductAttributes extends AbstractHelper
{
    /**
     * @var GroupRepositoryInterface
     */
    protected $groupRepository;

    /**
     * @var GenerateOptionsManager
     */
    protected $generateOptionsManager;

    /**
     * @var OutputHelper
     */
    protected $outputHelper;

    /**
     * @var ImageHelper
     */
    protected $imageHelper;

    /**
     * @var WTAImageHelper
     */
    protected $wtaImageHelper;

    /**
     * @var CollectionFactory
     */
    protected $attributeCollectionFactory;

    /**
     * @var UserFieldsSelectedManager
     */
    protected $userFieldsSelected;

    /**
     * Constructor
     *
     * @param GroupRepositoryInterface $groupRepository
     * @param GenerateOptionsManager $generateOptionsManager
     * @param OutputHelper $outputHelper
     * @param ImageHelper $imageHelper
     * @param WTAImageHelper $wtaImageHelper
     * @param CollectionFactory $attributeCollectionFactory
     * @param UserFieldsSelectedManager $userFieldsSelected
     */
    public function __construct(
        GroupRepositoryInterface $groupRepository,
        GenerateOptionsManager $generateOptionsManager,
        OutputHelper $outputHelper,
        ImageHelper $imageHelper,
        WTAImageHelper $wtaImageHelper,
        CollectionFactory $attributeCollectionFactory,
        UserFieldsSelectedManager $userFieldsSelected
    ) {
        $this->groupRepository = $groupRepository;
        $this->generateOptionsManager = $generateOptionsManager;
        $this->outputHelper = $outputHelper;
        $this->imageHelper = $imageHelper;
        $this->wtaImageHelper = $wtaImageHelper;
        $this->attributeCollectionFactory = $attributeCollectionFactory;
        $this->userFieldsSelected = $userFieldsSelected;
    }

    /**
     * Get product attributes selected
     *
     * @param \WriteTextAI\WriteTextAI\Model\AiProduct $aiProduct
     * @return array
     */
    public function getProductAttributesSelected($aiProduct)
    {
        $result = [];

        // Change to user preference
        // if ($aiProduct->getProductAttributesSelected()) {
        //     $result = json_decode($aiProduct->getProductAttributesSelected());
        // }

        $userPreference = $this->userFieldsSelected->checkUserFieldsSelected(
            UserFieldsSelectedManager::ACTION_TYPE_ATTRIBUTES_SELECTED,
            'product',
            'grid'
        );

        if ($userPreference) {
            $result = $this->userFieldsSelected->getUserFieldsSelected(
                UserFieldsSelectedManager::ACTION_TYPE_ATTRIBUTES_SELECTED,
                'product',
                'grid'
            );
        } else {
            $result = $this->getAttributesSelectedFromGlobalSettings();
        }

        // if ($aiProduct->getProductAttributesSelected()) {
        //     if ($aiProduct->getProductAttributesSelected() !== 'empty') {
        //         $result = json_decode($aiProduct->getProductAttributesSelected());
        //     }
        // } else {
        //     $result = $this->userFieldsSelected->getUserFieldsSelected(
        //         UserFieldsSelectedManager::ACTION_TYPE_ATTRIBUTES_SELECTED,
        //         'product',
        //         'edit'
        //     );
        // }

        // $thumbnailSelected = filter_var($this->userFieldsSelected->getUserFieldsSelected(
        //     UserFieldsSelectedManager::ACTION_TYPE_THUMBNAIL,
        //     'product',
        //     ''
        // ), FILTER_VALIDATE_BOOLEAN);

        $productResearchDataSelected = filter_var($this->userFieldsSelected->getUserFieldsSelected(
            UserFieldsSelectedManager::ACTION_TYPE_PRODUCT_RESEARCH_DATA,
            '',
            ''
        ), FILTER_VALIDATE_BOOLEAN);
        
        // if ($thumbnailSelected) {
        //     if (!in_array('thumbnail', $result)) {
        //         $result[] = 'thumbnail';
        //     }
        // } else {
        //     $result = array_filter($result, fn($attribute) => $attribute !== 'thumbnail');
        // }

        if ($productResearchDataSelected) {
            if (!in_array(ProductAttributesSource::PRODUCT_RESEARCH_DATA_ATTRIBUTE_CODE, $result)) {
                $result[] = ProductAttributesSource::PRODUCT_RESEARCH_DATA_ATTRIBUTE_CODE;
            }
        } else {
            $result = array_filter(
                $result,
                fn($attribute) => $attribute !== ProductAttributesSource::PRODUCT_RESEARCH_DATA_ATTRIBUTE_CODE
            );
        }

        return array_values($result);
    }

    // phpcs:disable Generic.Metrics.NestingLevel.TooHigh
    /**
     * Get product attributes
     *
     * @param \Magento\Catalog\Api\Data\ProductInterface $product
     * @return array
     */
    public function getProductAttributes($product)
    {
        $attributeSetId = $product->getAttributeSetId();
        $attributeSet = $this->attributeCollectionFactory->create()
            ->addFieldToSelect('attribute_id')
            ->setAttributeSetFilter($attributeSetId)
            ->load()
            ->getItems();
        $attributeIds = array_map(fn($attribute) => $attribute->getAttributeId(), $attributeSet);

        try {
            $options = $this->generateOptionsManager->getOptions('attributes');
        } catch (\Exception $e) {
            return [];
        }

        $attributes = [];
        $hasThumbnail = false;
        foreach ($options as &$option) {
            if (!in_array($option['id'], $attributeIds)) {
                continue;
            }

            $attribute = [
                'attribute_code' => $option['value'],
                'attribute' => $option['label'],
                'value' => $product->getData($option['value']) ?? ''
            ];

            if (in_array($option['value'], Excluded::ARRAY_ATTRIBUTES)) {
                try {
                    switch ($option['value']) {
                        case 'tier_price':
                            $attribute['details'] = '';
                            foreach ($product->getTierPrices() as $tierPrice) {
                                $groupName = $tierPrice['customer_group_id'] !== GroupInterface::CUST_GROUP_ALL ?
                                    $this->groupRepository->getById($tierPrice['customer_group_id']) :
                                    __('ALL GROUPS');

                                // Check if it's an object and get the group name
                                if (is_object($groupName) && method_exists($groupName, 'getCode')) {
                                    $groupName = $groupName->getCode();
                                }
                                
                                $attribute['details'] .= sprintf("%s: ", __('Customer Group')) . $groupName . "<br />"
                                    . sprintf("%s: ", __('Quantity')) . $tierPrice['qty'] . "<br />"
                                    . sprintf("%s: ", __('Price')) . $tierPrice['value'] . "<br /><br />";
                            }
                            
                            break;

                        case 'quantity_and_stock_status':
                            $quantityAndStockStatus = $product->getQuantityAndStockStatus();
                            $qty = $quantityAndStockStatus ? $quantityAndStockStatus['qty'] : '';
                            $stockStatus = $quantityAndStockStatus ? $quantityAndStockStatus['is_in_stock'] : '';
                            $stockStatusLabel = $stockStatus ? __('In Stock') : __('Out of Stock');
                            $attribute['details'] = '';

                            if ($qty || $stockStatus) {
                                $attribute['details'] = sprintf("%s: ", __('Quantity')) . $qty . "<br />"
                                    . sprintf("%s: ", __('Stock status')) . $stockStatusLabel;
                            }

                            break;
                    }
                } catch (\Exception $e) {
                    continue;
                }

                $attributes[] = $attribute;
            } else {
                $attribute['details'] = '';

                if (strtolower($option['value']) === 'thumbnail') {
                    if (empty($attribute['value'])) {
                        continue;
                    }

                    /**
                     * Do not include the image file if it cannot be processed.
                     */
                    try {
                        $imageHelper = $this->imageHelper->init($product, 'product_listing_thumbnail');
                        $thumbnail = $imageHelper->setImageFile($attribute['value']);
                        $attribute['details'] = $imageHelper->getUrl();
                        
                        /**
                         * Always process product_listing_thumbnail_preview after the product_listing_thumbnail
                         * to retain the size of the the thumbnail image.
                         */
                        $origImageHelper = $this->imageHelper->init($product, 'product_listing_thumbnail_preview');
                        $attribute['original_image'] = $origImageHelper->getUrl();

                        $thumbnail->getOriginalWidth();
                    } catch (\InvalidArgumentException | FileSystemException $e) {
                        continue;
                    }
                    $value = $this->wtaImageHelper->getImageValue($product);

                    if (empty($value)) {
                        continue;
                    }

                    $attribute['value'] = $value;

                    if ($value) {
                        $hasThumbnail = true;
                        $attributes[] = $attribute;
                    }
                } else {
                    try {
                        $details = $product->getResource()
                            ->getAttribute($option['value'])
                            ->getFrontend()
                            ->getValue($product);

                        if ($details) {
                            $attribute['details'] = $this->outputHelper->productAttribute(
                                $product,
                                $details,
                                $option['value']
                            );
                        }

                        $attributes[] = $attribute;
                    } catch (\Exception $e) {
                        /** Skip attributes with error */
                        continue;
                    }
                }
            }
        }

        // product research data
        $productResearchData = [
            'attribute_code' => ProductAttributesSource::PRODUCT_RESEARCH_DATA_ATTRIBUTE_CODE,
            'attribute' => __('Product Research'),
            'value' => '',
            'details' => ''
        ];
        if ($hasThumbnail) {
            /** insert product search data to index 2 in order to be it under the thumbnail */
            array_splice($attributes, 2, 0, [$productResearchData]);
        } else {
            /** insert product search data in the first position */
            array_unshift($attributes, $productResearchData);
        }

        return $attributes;
    }
    // phpcs:enable Generic.Metrics.NestingLevel.TooHigh

    /**
     * Get attributes selected from global settings
     *
     * @return array
     */
    public function getAttributesSelectedFromGlobalSettings()
    {
        $attributes = $this->getAttributes();

        $defaultAttributes = array_filter($attributes, function ($attribute) {
            return $attribute['default'];
        });
        $attributesSelected = array_map(function ($attribute) {
            return $attribute['value'];
        }, $defaultAttributes);

        return array_values($attributesSelected);
    }

    /**
     * Get attributes
     *
     * @return array
     */
    public function getAttributes()
    {
        return $this->generateOptionsManager->getOptions('attributes');
    }
}
