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

namespace WriteTextAI\WriteTextAI\Helper;

use WriteTextAI\WriteTextAI\Model\ApiManager;
use Magento\Framework\Filesystem\Driver\File as DriverInterface;
use Magento\Framework\Filesystem\Io\File;
use Magento\Framework\Url\EncoderInterface;
use Magento\Catalog\Model\Category\Image as CategoryImage;
use Laminas\Uri\UriFactory;

class Image extends \Magento\Framework\App\Helper\AbstractHelper
{
    protected const ATTRIBUTE_NAME = 'image';

    public const IMAGE_TYPES = [
        IMAGETYPE_GIF => "gif",
        IMAGETYPE_JPEG => "jpeg",
        IMAGETYPE_PNG => "png",
        IMAGETYPE_SWF => "swf",
        IMAGETYPE_PSD => "psd",
        IMAGETYPE_BMP => "bmp",
        IMAGETYPE_TIFF_II => "tiff_ii",
        IMAGETYPE_TIFF_MM => "tiff_mm",
        IMAGETYPE_JPC => "jpc",
        IMAGETYPE_JP2 => "jp2",
        IMAGETYPE_JPX => "jpx",
        IMAGETYPE_JB2 => "jb2",
        IMAGETYPE_SWC => "swc",
        IMAGETYPE_IFF => "iff",
        IMAGETYPE_WBMP => "wbmp",
        IMAGETYPE_XBM => "xbm",
        IMAGETYPE_ICO => "ico",
    ];

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

    /**
     * @var DriverInterface
     */
    protected $driver;

    /**
     * @var EncoderInterface
     */
    protected $urlEncoder;

    /**
     * @var File
     */
    protected $file;

    /**
     * @var CategoryImage
     */
    protected $categoryImage;

    /**
     * Constructor
     *
     * @param ApiManager $apiManager
     * @param DriverInterface $driver
     * @param EncoderInterface $urlEncoder
     * @param File $file
     * @param CategoryImage $categoryImage
     */
    public function __construct(
        ApiManager $apiManager,
        DriverInterface $driver,
        EncoderInterface $urlEncoder,
        File $file,
        CategoryImage $categoryImage
    ) {
        $this->apiManager = $apiManager;
        $this->driver = $driver;
        $this->urlEncoder = $urlEncoder;
        $this->file = $file;
        $this->categoryImage = $categoryImage;
    }

    /**
     * Get image API ID
     *
     * @param int $storeId
     * @param string $ipAddress
     * @param string $language
     * @param int $id
     * @param string $url
     * @return int
     */
    public function getImageApiId(
        $storeId,
        $ipAddress,
        $language,
        $id,
        $url
    ) {
        $params = [
            "storeId" => $storeId,
            "language" => $language,
            "imageId" => $id
        ];

        try {
            $image = $this->apiManager->getImage($params);

            $expiryDate = new \DateTime($image['imageDataExpires']);
            $expiryDate = $expiryDate->format('Y-m-d H:i:s');

            $now = new \DateTime();
            $now = $now->format('Y-m-d H:i:s');
            
            if ($now > $expiryDate || (isset($image['archivedAt']) && !empty($image['archivedAt']))) {
                $this->uploadImage($ipAddress, $url, $params, true);
            }
        } catch (\WriteTextAI\WriteTextAI\Exception\ApiException $e) {
            if ($e->getCode() === 404) {
                $this->uploadImage($ipAddress, $url, $params, true);
            } else {
                throw $e;
            }
        }
        
        return $id;
    }

    /**
     * Upload image
     *
     * @param string $ipAddress
     * @param string $url
     * @param array $params
     * @param bool $overwrite
     * @return void
     */
    public function uploadImage($ipAddress, $url, $params, $overwrite = false)
    {
        $params["ipAddress"] = $ipAddress;
        $params["url"] = $url;

        if ($overwrite) {
            $params["overwrite"] = true;
        }

        try {
            $this->apiManager->uploadImage(json_encode($params));
        } catch (\WriteTextAI\WriteTextAI\Exception\ImageDownloadFailed $e) {
            unset($params["url"]);
            $pathInfo = $this->file->getPathInfo($url);
            $type = $pathInfo['extension'] ?? '';
            $data = $this->driver->fileGetContents($url);
            $base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
            $params["imageData"] = $base64;
            $this->apiManager->uploadImage(json_encode($params));
        }
    }

    /**
     * Get image value
     *
     * @param \Magento\Catalog\Api\Data\ProductInterface $product
     * @return string
     */
    public function getImageValue($product)
    {
        $mediaGallery = $product->getMediaGalleryEntries();
        $thumbnail = $product->getThumbnail();
        
        if (!empty($mediaGallery)) {
            foreach ($mediaGallery as $mediaGalleryEntry) {
                if ($mediaGalleryEntry->getFile() === $thumbnail) {
                    return $mediaGalleryEntry->getId();
                }
            }
        }

        return '';
    }

    /**
     * Get category image id
     *
     * @param int $categoryId
     * @param int $storeId
     * @param string $image
     *
     * @return string
     */
    public function getCategoryImageId($categoryId, $storeId, $image)
    {
        if ($image) {
            if (strpos($image, '://') === false && strpos($image, '//') !== 0) {
                $image = 'http://' . ltrim($image, '/');
            }
            try {
                $uri = UriFactory::factory($image);
                $path = $uri->getPath() ?: '/';
            } catch (\Exception $e) {
                $path = '/';
            }
            return 'category_image_' . $storeId . '_' . $categoryId . '_' . $path;
        }

        return '';
    }

    /**
     * Get category image url
     *
     * @param \Magento\Catalog\Api\Data\CategoryInterface $category
     * @return string
     */
    public function getCategoryImageUrl($category)
    {
        $categoryImage = $this->categoryImage->getUrl($category, self::ATTRIBUTE_NAME);
        return $categoryImage;
    }

    /**
     * Get category image uri
     *
     * @param \Magento\Catalog\Api\Data\CategoryInterface $category
     * @return string
     */
    public function getCategoryImageUri($category)
    {
        $categoryImageUrl = $this->getCategoryImageUrl($category);
        if (!$categoryImageUrl) {
            return  $categoryImageUrl;
        }
        
        if (strpos($categoryImageUrl, '://') === false && strpos($categoryImageUrl, '//') !== 0) {
            $categoryImageUrl = 'http://' . ltrim($categoryImageUrl, '/');
        }
        try {
            $uri = UriFactory::factory($categoryImageUrl);
            $path = $uri->getPath() ?: '/';
        } catch (\Exception $e) {
            return $categoryImageUrl;
        }
        return $path;
    }
}
