<?php
declare(strict_types=1);

namespace WriteTextAI\WriteTextAI\Model;

use WriteTextAI\WriteTextAI\Api\ImageApiInterface;
use Magento\Framework\Webapi\Rest\Response as RestResponse;
use WriteTextAI\WriteTextAI\Helper\Product as ProductHelper;
use Magento\Catalog\Helper\Image as ImageHelper;

use Magento\Framework\Exception\NoSuchEntityException;

/**
 * Class ImageApi
 * Implementation for retrieving product images with alt text
 */
class ImageApi implements ImageApiInterface
{
    /**
     * @var RestResponse
     */
    private $response;

    /**
     * @var ProductHelper
     */
    private $productHelper;
    
    /**
     * @var ImageHelper
     */
    private $imageHelper;

    /**
     * @var array
     */
    private $featuredImageData = [];

    /**
     * @var array
     */
    private $galleryImageData = [];

    /**
     * @param RestResponse $response
     * @param ProductHelper $productHelper
     * @param ImageHelper $imageHelper
     */
    public function __construct(
        RestResponse $response,
        ProductHelper $productHelper,
        ImageHelper $imageHelper
    ) {
        $this->response = $response;
        $this->productHelper = $productHelper;
        $this->imageHelper = $imageHelper;
    }

    /**
     * Get product images with alt text
     *
     * @param $recordId
     * @param $type
     * @param $storeId
     * @param $language
     * @param $withAltText
     * @param $withTemplate
     * @return \Magento\Framework\DataObject
     */
    public function getImages(
        $recordId,
        $type,
        $storeId = null,
        $language = null,
        $withAltText = null,
        $withTemplate = null
    ) {
        try {
            $product = $this->productHelper->getProduct($recordId, $storeId);
        } catch (NoSuchEntityException $e) {
            $this->response->setStatusCode(404);
            return $this->response->setBody(json_encode(['error' => $e->getMessage()]))->sendResponse();
        }
        try {
            $images = $this->productHelper->getImages($product, $storeId, $language);
            $altTexts = $this->getAltTextParams($product, $images);
            // Hardcoded JSON response
            $responseData = [];

            if (!empty($this->featuredImageData)) {
                $responseData['images'] = [$this->featuredImageData];

                if ($withTemplate) {
                    $responseData['featuredImage'] = $this->featuredImageData;
                }
            }

            if (!empty($altTexts) && $withAltText) {
                $responseData['imageAltTexts'] = $altTexts;
            }

            if (!empty($this->galleryImageData) && $withTemplate) {
                $responseData['galleryImages'] = $this->galleryImageData;
            }

            return $this->response->setBody(json_encode($responseData))->sendResponse();
        } catch (\Exception $e) {
            $this->response->setStatusCode(500);
            return $this->response->setBody(json_encode(
                [
                    'error' => 500,
                    'message' => $e->getMessage()
                ]
            ))->sendResponse();
        }
    }

    /**
     * Get alt text params
     *
     * @param \Magento\Catalog\Model\Product $product
     * @param array $galleryImages
     * @param array $failedImages
     * @return array
     */
    protected function getAltTextParams($product, $galleryImages, $failedImages = [])
    {
        $altTexts = [];

        $images = $product->getMediaGalleryImages()->setOrder('position', 'ASC');
        $imageLimit = 10;
        $imageCount = 0;

        $featuredImageData = [];
        $featuredImageId = null;
        $isFeaturedImageIncluded = false;
        foreach ($galleryImages as $image) {
            if (isset($image['is_featured']) && $image['is_featured']) {
                $featuredImageId = $image['id'];
                $this->featuredImageData = [
                    'imageId' => $image['id'],
                    'url' => $image['noncached_url']
                ];
            }
        }

        foreach ($images as $image) {
            if ($image->getDisabled()) {
                continue;
            }
            
            if (in_array($image->getId(), $failedImages)) {
                $imageCount++;
                continue;
            }

            if ($imageCount >= $imageLimit) {
                break;
            }

            $imageFile = $image->getFile();
            $imageFilePreview = $this->imageHelper->init(
                $product,
                'product_listing_thumbnail_preview'
            )->setImageFile($imageFile);
            $url = $imageFilePreview->getUrl();
            if ($url == $imageFilePreview->getDefaultPlaceholderUrl()) {
                continue;
            }

            if ($image->getId() === $featuredImageId) {
                $isFeaturedImageIncluded = true;
                continue;
            }

            $this->galleryImageData[] = [
                'imageId' => $image->getId(),
                'url' => $image->getUrl()
            ];
            $altTexts = $this->galleryImageData;
                
            $imageCount++;
        }
        
        /** Add featured image to the beginning of the array */
        if ($isFeaturedImageIncluded) {
            array_unshift($altTexts, $this->featuredImageData);
        }

        return $altTexts;
    }
}
