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

namespace WriteTextAI\WriteTextAI\Model\Keywords;

use WriteTextAI\WriteTextAI\Model\Api\Keywords;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
use WriteTextAI\WriteTextAI\Helper\Store as StoreHelper;
use WriteTextAI\WriteTextAI\Helper\Image;
use WriteTextAI\WriteTextAI\Helper\Product as ProductHelper;
use Magento\Catalog\Helper\Image as MagentoImageHelper;
use WriteTextAI\WriteTextAI\Model\Magento\Category as MagentoCategory;

class ReuploadThumbnails
{
    /**
     * @var Keywords
     */
    protected $keywords;

    /**
     * @var StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var RemoteAddress
     */
    protected $remoteAddress;

    /**
     * @var StoreHelper
     */
    protected $storeHelper;

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

    /**
     * @var ProductHelper
     */
    protected $productHelper;

    /**
     * @var MagentoImageHelper
     */
    protected $magentoImageHelper;

    /**
     * @var MagentoCategory
     */
    protected $magentoCategory;

    /**
     * Constructor.
     *
     * @param Keywords $keywords
     * @param StoreManagerInterface $storeManager
     * @param RemoteAddress $remoteAddress
     * @param StoreHelper $storeHelper
     * @param Image $imageHelper
     * @param ProductHelper $productHelper
     * @param MagentoImageHelper $magentoImageHelper
     * @param MagentoCategory $magentoCategory
     */
    public function __construct(
        Keywords $keywords,
        StoreManagerInterface $storeManager,
        RemoteAddress $remoteAddress,
        StoreHelper $storeHelper,
        Image $imageHelper,
        ProductHelper $productHelper,
        MagentoImageHelper $magentoImageHelper,
        MagentoCategory $magentoCategory
    ) {
        $this->keywords = $keywords;
        $this->storeManager = $storeManager;
        $this->remoteAddress = $remoteAddress;
        $this->storeHelper = $storeHelper;
        $this->imageHelper = $imageHelper;
        $this->productHelper = $productHelper;
        $this->magentoImageHelper = $magentoImageHelper;
        $this->magentoCategory = $magentoCategory;
    }

    /**
     * Cron execute command
     */
    public function execute()
    {
        $types = ['Product', 'Category'];

        foreach ($types as $type) {
            foreach ($this->getStoreIds() as $storeId) {
                $this->reuploadThumbnails($storeId, $type);
            }
        }
    }

    /**
     * Reupload thumbnails
     *
     * @param int $storeId
     * @param string $type
     */
    protected function reuploadThumbnails($storeId, $type)
    {
        $statuses = ['Completed'];
        $result = $this->keywords->getOptimizationList($storeId, $statuses, null, $type);
        $recordIds = array_column($result['result'], 'recordId');
        if (isset($result['continuationToken'])) {
            do {
                $result = $this->keywords->getOptimizationList(
                    $storeId,
                    $statuses,
                    $result['continuationToken'],
                    $type
                );
                $recordIds = array_merge($recordIds, array_column($result['result'], 'recordId'));
            } while (isset($result['continuationToken']));
        }

        foreach ($recordIds as $recordId) {
            $imageData = $this->getImageData($storeId, $recordId, $type);
            if ($imageData['imageId']) {
                $response = $this->uploadImage($storeId, $imageData['imageId'], $imageData['image']);
                if ($response) {
                    $this->keywords->updateOptimizationImage($storeId, $recordId, $imageData['imageId'], $type);
                }
            }
        }
    }

    /**
     * Get image data
     *
     * @param int $storeId
     * @param int $recordId
     * @param string $type
     *
     * @return array
     */
    protected function getImageData($storeId, $recordId, $type)
    {
        switch ($type) {
            case 'Product':
                $product = $this->productHelper->getProduct($recordId, $storeId);
                $origImageHelper = $this->magentoImageHelper->init($product, 'product_listing_thumbnail')
                    ->setImageFile($product->getThumbnail());
                $image = $origImageHelper->getUrl();
                $imageId = $this->imageHelper->getImageValue($product);
                break;
            case 'Category':
                $category = $this->magentoCategory->getCategory($recordId, $storeId);
                $image = '';
                if ($category->getImage()) {
                    $image = rtrim(
                        $this->storeManager->getStore()->getBaseUrl(
                            \Magento\Framework\UrlInterface::URL_TYPE_DIRECT_LINK
                        ),
                        '/'
                    ) . $category->getImage();
                }
                $imageId = $this->imageHelper->getCategoryImageId($recordId, $storeId, $category->getImage());
                break;
        }

        return [
            'image' => $image,
            'imageId' => $imageId
        ];
    }

    /**
     * Get store ids
     *
     * @return array
     */
    public function getStoreIds()
    {
        $storeIds = [];
        $stores = $this->storeManager->getStores();
        foreach ($stores as $store) {
            $storeIds[] = $store->getId();
        }

        return $storeIds;
    }

    /**
     * Upload image
     *
     * @param int $storeId
     * @param string $imageId
     * @param string $image
     *
     * @return bool
     */
    private function uploadImage($storeId, $imageId, $image)
    {
        try {
            $this->imageHelper->getImageApiId(
                $storeId,
                '',
                $this->storeHelper->getFormattedLanguage($storeId),
                $imageId,
                $image
            );
            return true;
        } catch (\WriteTextAI\WriteTextAI\Exception\ImageUnsupported $e) {
            return false;
        } catch (\WriteTextAI\WriteTextAI\Exception\ImageInvalid $e) {
            return false;
        }
    }
}
