<?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\Framework\Exception\FileSystemException;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Helper\Image as ImageHelper;
use WriteTextAI\WriteTextAI\Model\ApiManager;
use WriteTextAI\WriteTextAI\Helper\Image as WtaImageHelper;

class Product extends AbstractHelper
{
    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

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

    /**
     * @var ApiManager
     */
    protected $apiManager;

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

    /**
     * Constructor
     *
     * @param ProductRepositoryInterface $productRepository
     * @param ImageHelper $imageHelper
     * @param ApiManager $apiManager
     * @param WtaImageHelper $wtaImageHelper
     */
    public function __construct(
        ProductRepositoryInterface $productRepository,
        ImageHelper $imageHelper,
        ApiManager $apiManager,
        WtaImageHelper $wtaImageHelper
    ) {
        $this->productRepository = $productRepository;
        $this->imageHelper = $imageHelper;
        $this->apiManager = $apiManager;
        $this->wtaImageHelper = $wtaImageHelper;
    }

    /**
     * Get product
     *
     * @param int $productId
     * @param int $storeId
     * @return \Magento\Catalog\Api\Data\ProductInterface
     */
    public function getProduct($productId, $storeId)
    {
        return $this->productRepository->getById($productId, false, $storeId);
    }

    /**
     * Get images
     *
     * @param \Magento\Catalog\Api\Data\ProductInterface $product
     * @param int $storeId
     * @param string $language
     * @param int $imageLimit
     * @return array
     */
    public function getImages($product, $storeId, $language, $imageLimit = 10)
    {
        $images = [];
        $mediaGallery = $product->getMediaGalleryImages()->setOrder('position', 'ASC');
        $imageIds = [];
        $imageCount = 0;
        $featuredId = $this->wtaImageHelper->getImageValue($product);
        $featuredImageData = [];
        /** get the images from the media gallery */
        if (!empty($mediaGallery)) {
            foreach ($mediaGallery as $mediaGalleryEntry) {
                if ($mediaGalleryEntry->getDisabled()) {
                    continue;
                }

                if (is_null($mediaGalleryEntry->getId())) {
                    continue;
                }

                $imageFileThumbnail = $this->imageHelper->init($product, 'product_listing_thumbnail')
                    ->setImageFile($mediaGalleryEntry->getFile());
                $url = $imageFileThumbnail->getUrl();

                $origUrl = $this->imageHelper->init($product, 'product_listing_thumbnail_preview')
                    ->setImageFile($mediaGalleryEntry->getFile())
                    ->getUrl();

                /**
                 * Do not include the image file if it cannot be processed.
                 */
                try {
                    $imageFileThumbnail->getOriginalWidth();
                } catch (\InvalidArgumentException | FileSystemException $e) {
                    continue;
                }
                $imageData = [
                    'id' => $mediaGalleryEntry->getId(),
                    'url' => $url,
                    'alt' => $mediaGalleryEntry->getLabel() ?? '',
                    'orig_url' => $origUrl,
                    'noncached_url' => $mediaGalleryEntry->getUrl()
                ];
                if ($featuredId) {
                    $isFeatured = $mediaGalleryEntry->getId() === $featuredId;
                    if ($isFeatured) {
                        $imageData['is_featured'] = $isFeatured;
                        $featuredImageData = $imageData;
                        continue;
                    }
                }
                $imageIds[] = $imageData;
            }
        }

        /** select the first 10, if there is a featured image, add it to the beginning */
        $tempImageIds = [];
        if ($imageLimit === 0) {
            $tempImageIds = $imageIds;
        } else {
            $tempImageIds = array_slice($imageIds, 0, $imageLimit);
        }
        
        if (!empty($featuredImageData)) {
            array_unshift($tempImageIds, $featuredImageData);
            $imageIds = $tempImageIds;
        }

        $chunks = array_chunk($imageIds, 20);

        foreach ($chunks as $chunk) {
            $ids = array_column($chunk, 'id');

            try {
                $apiImages = $this->apiManager->getImageList([
                    "language" => $language,
                    "images" => $ids,
                    "storeId" => $storeId,
                    "includeUpdateHistory" => "true"
                ]);

                foreach ($chunk as $image) {
                    $wtaAltText = '';
                    $wtaPublish = false;
                    $wtaReview = false;
                    $wtaTextId = null;
                    $filteredImages = array_filter(
                        $apiImages['images'],
                        function ($filteredImage) use ($image) {
                            return $filteredImage['imageId']== $image['id'];
                        }
                    );
                    $apiImage = reset($filteredImages);

                    $wtaFeedback = [];
                    $wtaKeywords = [];
                    
                    if ($apiImage) {
                        $wtaAltText = $apiImage['altText']['value'] ?? '';
                        $wtaPublish = $apiImage['altText']['history'][0]['publish'] ?? false;
                        $wtaReview = $apiImage['altText']['history'][0]['reviewed'] ?? false;
                        $wtaTextId = $apiImage['altText']['id'] ?? null;
                        $wtaFeedback = $apiImage['altText']['latestFeedback'] ?? [];
                        $wtaKeywords = $apiImage['altText']['keywords'] ?? [];
                    }

                    $images[] = [
                        'url' => $image['url'],
                        'noncached_url' => $image['noncached_url'],
                        'orig_url' => $image['orig_url'],
                        'alt' => $image['alt'],
                        'id' => $image['id'],
                        'original_writetext_alt' => $wtaAltText,
                        'writetext_alt' => $wtaAltText,
                        'writetext_alt_id' => $wtaTextId,
                        'reviewed' => $wtaReview,
                        'status' => [
                            'generated' => $wtaAltText !== '',
                            'transferred' => $wtaPublish
                        ],
                        'feedback' => $wtaFeedback,
                        'keywords' => $wtaKeywords,
                        'is_featured' => isset($image['is_featured']) ? $image['is_featured'] : false
                    ];
                }
            } catch (\WriteTextAI\WriteTextAI\Exception\ApiException $e) {
                if ($e->getCode() !== 404) {
                    throw $e;
                }
            }
        }

        return $images;
    }

    /**
     * Get all image IDs for a product.
     *
     * @param \Magento\Catalog\Model\Product $product
     * @return array
     */
    public function getImageIds($product)
    {
        $imageIds = [];
        $mediaGallery = $product->getMediaGalleryImages()->setOrder('position', 'ASC');
        $featuredId = $this->wtaImageHelper->getImageValue($product);
        $featuredFound = false;

        /** get the image IDs from the media gallery */
        if (!empty($mediaGallery)) {
            foreach ($mediaGallery as $mediaGalleryEntry) {
                if ($mediaGalleryEntry->getDisabled()) {
                    continue;
                }

                $imageFileThumbnail = $this->imageHelper->init($product, 'product_listing_thumbnail')
                    ->setImageFile($mediaGalleryEntry->getFile());
                $url = $imageFileThumbnail->getUrl();

                $origUrl = $this->imageHelper->init($product, 'product_listing_thumbnail_preview')
                    ->setImageFile($mediaGalleryEntry->getFile())
                    ->getUrl();

                /**
                 * Do not include the image file if it cannot be processed.
                 */
                try {
                    if ($imageFileThumbnail->getOriginalWidth() === null) {
                        continue;
                    }
                } catch (\InvalidArgumentException | FileSystemException $e) {
                    continue;
                }

                $imageId = $mediaGalleryEntry->getId();

                /** check if this is the featured image */
                if ($featuredId && $imageId === $featuredId) {
                    $featuredFound = true;
                    continue;
                }

                $imageIds[] = $imageId;
            }
        }

        /** add featured image to the beginning if found */
        if ($featuredFound) {
            array_unshift($imageIds, $featuredId);
        }

        return $imageIds;
    }

    /**
     * Get all image IDs for a product.
     *
     * @param \Magento\Catalog\Model\Product $product
     * @return array
     */
    public function getImageIdsWithUrl($product)
    {
        $imageIds = [];
        $mediaGallery = $product->getMediaGalleryImages()->setOrder('position', 'ASC');
        $featuredId = $this->wtaImageHelper->getImageValue($product);
        $featuredFound = false;
        $imageIdsFeatured = [];

        /** get the image IDs from the media gallery */
        if (!empty($mediaGallery)) {
            foreach ($mediaGallery as $mediaGalleryEntry) {
                if ($mediaGalleryEntry->getDisabled()) {
                    continue;
                }

                $imageFileThumbnail = $this->imageHelper->init($product, 'product_listing_thumbnail')
                    ->setImageFile($mediaGalleryEntry->getFile());
                $url = $imageFileThumbnail->getUrl();

                $origUrl = $this->imageHelper->init($product, 'product_listing_thumbnail_preview')
                    ->setImageFile($mediaGalleryEntry->getFile())
                    ->getUrl();

                /**
                 * Do not include the image file if it cannot be processed.
                 */
                try {
                    if ($imageFileThumbnail->getOriginalWidth() === null) {
                        continue;
                    }
                } catch (\InvalidArgumentException | FileSystemException $e) {
                    continue;
                }

                $imageId = $mediaGalleryEntry->getId();

                /** check if this is the featured image */
                if ($featuredId && $imageId === $featuredId) {
                    $imageIdsFeatured[] = [
                        'id' => $imageId,
                        'url' => $url
                    ];
                    $featuredFound = true;
                    continue;
                }

                $imageIds[] = [
                    'id' => $imageId,
                    'url' => $url
                ];
            }
        }

        /** add featured image to the beginning if found */
        if ($featuredFound) {
            array_unshift($imageIds, $imageIdsFeatured);
        }

        return $imageIds;
    }

    /**
     * Convert new lines to <br> tags.
     *
     * @param string $text
     * @return string
     */
    public function convertNewLinesToBr($text)
    {
        if (strpos($text, "<br />") === false) {
            $text = preg_replace("/(\r\n|\n\r|\n|\r)/", "<br />", $text);
        }
        
        return $text;
    }

    /**
     * Get product published images
     *
     * @param \Magento\Catalog\Api\Data\ProductInterface $product
     * @param int $storeId
     * @param string $language
     * @return array
     */
    public function getPublishedImages($product, $storeId, $language)
    {
        $images = [];
        $mediaGallery = $product->getMediaGalleryImages()->setOrder('position', 'ASC');
        $imageIds = [];
        $imageLimit = 10;
        $imageCount = 0;
        $featuredId = $this->wtaImageHelper->getImageValue($product);
        $featuredImageData = [];
        if (!empty($mediaGallery)) {
            foreach ($mediaGallery as $mediaGalleryEntry) {
                if ($mediaGalleryEntry->getDisabled()) {
                    continue;
                }

                $imageFileThumbnail = $this->imageHelper->init($product, 'product_listing_thumbnail')
                    ->setImageFile($mediaGalleryEntry->getFile());
                $url = $imageFileThumbnail->getUrl();

                $origUrl = $this->imageHelper->init($product, 'product_listing_thumbnail_preview')
                    ->setImageFile($mediaGalleryEntry->getFile())
                    ->getUrl();

                /**
                 * Do not include the image file if it cannot be processed.
                 */
                try {
                    $imageFileThumbnail->getOriginalWidth();
                } catch (\InvalidArgumentException | FileSystemException $e) {
                    continue;
                }

                $imageData = [
                    'id' => $mediaGalleryEntry->getId(),
                    'url' => $url,
                    'alt' => $mediaGalleryEntry->getLabel() ?? '',
                    'orig_url' => $origUrl,
                    'noncached_url' => $mediaGalleryEntry->getUrl()
                ];

                if ($featuredId) {
                    $isFeatured = $mediaGalleryEntry->getId() === $featuredId;
                    if ($isFeatured) {
                        $featuredImageData = $imageData;
                        continue;
                    }
                }
                $images[] = $imageData;

                $imageCount++;
            }
        }

        /** select the first 10, if there is a featured image, add it to the beginning */
        $tempImages = [];
        if ($imageLimit === 0) {
            $tempImages = $images;
        } else {
            $tempImages = array_slice($images, 0, $imageLimit);
        }
        
        if (!empty($featuredImageData)) {
            array_unshift($tempImages, $featuredImageData);
            $images = $tempImages;
        }
        
        return $images;
    }
}
