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

namespace WriteTextAI\WriteTextAI\Controller\Adminhtml\Image;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use WriteTextAI\WriteTextAI\Helper\Image;
use Magento\Backend\Model\UrlInterface;
use Magento\Framework\HTTP\PhpEnvironment\RemoteAddress;
use WriteTextAI\WriteTextAI\ViewModel\Settings;
use WriteTextAI\WriteTextAI\Helper\Store as StoreHelper;

class Upload extends Action
{
    /**
     * @var Image
     */
    protected $imageHelper;

    /**
     * @var UrlInterface
     */
    protected $urlBuilder;

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

    /**
     * @var Settings
     */
    protected $settings;

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

    /**
     * Constructor
     *
     * @param Context $context
     * @param Image $imageHelper
     * @param UrlInterface $urlBuilder
     * @param RemoteAddress $remoteAddress
     * @param Settings $settings
     * @param StoreHelper $storeHelper
     */
    public function __construct(
        Context $context,
        Image $imageHelper,
        UrlInterface $urlBuilder,
        RemoteAddress $remoteAddress,
        Settings $settings,
        StoreHelper $storeHelper
    ) {
        $this->imageHelper = $imageHelper;
        $this->urlBuilder = $urlBuilder;
        $this->remoteAddress = $remoteAddress;
        $this->settings = $settings;
        $this->storeHelper = $storeHelper;
        parent::__construct($context);
    }

    /**
     * Execute action
     *
     * @return \Magento\Framework\Controller\Result\Json
     */
    public function execute()
    {
        $response = $this->resultFactory->create(ResultFactory::TYPE_JSON);
        $params = $this->getRequest()->getPost();
        $language = $this->storeHelper->getFormattedLanguage($params['store_id']);
        $ipAddress = $this->remoteAddress->getRemoteAddress();

        try {
            // process gallery images
            $images = $this->uploadImages(
                $params['store_id'],
                $language,
                $ipAddress,
                $params['gallery_images'] ?? [],
                $params['images'] ?? [],
                $this->settings->getSettings('rules')
            );
            $failedImages = $images['failed_images'] ?? [];
            $failedImagesWithoutThumbnail = $failedImages;
            $invalid = $images['invalid'] ?? [];
            $notSupported = $images['not_supported'] ?? [];
            $downloadFailed = $images['download_failed'] ?? [];
            $general = $images['general'] ?? [];
            $errorMessages = $images['error_messages'] ?? [];

            // process thumbnail
            $thumbnailFailed = false;
            
            $result = [
                'success' => empty($failedImages)
            ];

            if (!empty($failedImages)) {
                $selectedImagesCount = count($params['gallery_images'] ?? []);
                $failedImagesCount = count($failedImages);

                if (isset($params['selected_fields']) && !empty($params['selected_fields'])) {
                    $result['proceedable'] = true;
                } else {
                    if ($selectedImagesCount > 0) {
                        $result['proceedable'] = $failedImagesCount !== $selectedImagesCount + (
                            $thumbnailFailed ? 1 : 0
                        );
                    }
                }

                $result['success_images'] = $images['success_images'] ?? [];
                $result['failed_images'] = $failedImages;
                $result['failed_images_without_thumbnail'] = $failedImagesWithoutThumbnail;
                $result['invalid'] = $invalid;
                $result['not_supported'] = $notSupported;
                $result['download_failed'] = $downloadFailed;
                $result['general'] = $general;
                $result['error_messages'] = $errorMessages;
            }
        } catch (\WriteTextAI\WriteTextAI\Exception\UnauthorizedException $e) {
            $result = [
                'success' => false,
                'unauthorized' => true,
                'login_url' => $this->urlBuilder->getUrl('wtai/setup/index'),
                'message' => $e->getMessage()
            ];
        } catch (\Exception $e) {
            $message = $e->getMessage();
            if (!$message) {
                $message = __(
                    'A system error has occurred. Please try again. If the issue persists,'
                    . ' please contact our support team at support@writetext.ai.'
                );
            }

            $result = [
                'success' => false,
                'message' => $message
            ];
        }

        $response->setData($result);

        return $response;
    }

    /**
     * Upload images to api
     *
     * @param int $storeId
     * @param string $language
     * @param string $ipAddress
     * @param array $selectedImages
     * @param array $gallery
     * @param array $rules
     *
     * @return array
     */
    private function uploadImages(
        $storeId,
        $language,
        $ipAddress,
        $selectedImages,
        $gallery,
        $rules
    ) {
        $failedImages = [];
        $successImages = [];
        $invalid = [];
        $notSupported = [];
        $downloadFailed = [];
        $general = [];
        $errorMessages = [];

        if (empty($selectedImages)) {
            return [
                'failed_images' => $failedImages,
                'success_images' => $successImages,
                'invalid' => $invalid,
                'not_supported' => $notSupported,
                'download_failed' => $downloadFailed,
                'general' => $general,
                'error_messages' => $errorMessages
            ];
        }

        $selectedImagesChunks = array_chunk($selectedImages, $rules['maxImageAltTextPerRequest']);

        foreach ($selectedImagesChunks as $selectedImagesChunk) {
            foreach ($gallery as $image) {
                if (!in_array($image['id'], $selectedImagesChunk)) {
                    continue;
                }

                $failedImageUrl = !empty($image['noncached_url']) ? $image['noncached_url'] : (!empty($image['orig_url']) ? $image['orig_url'] : $image['url']);

                try {
                    $successImages[] = $this->imageHelper->getImageApiId(
                        $storeId,
                        $ipAddress,
                        $language,
                        $image['id'],
                        $image['orig_url']
                    );
                } catch (\WriteTextAI\WriteTextAI\Exception\ImageUnsupported $e) {
                    $failedImages[] = $failedImageUrl;
                    $notSupported[] = [
                        "url" => $failedImageUrl,
                        "id" => $image['id']
                    ];
                    $errorMessages['not_supported'] = $e->getMessage();
                } catch (\WriteTextAI\WriteTextAI\Exception\ImageInvalid $e) {
                    $failedImages[] = $failedImageUrl;
                    $invalid[] = [
                        "url" => $failedImageUrl,
                        "id" => $image['id']
                    ];
                    $errorMessages['invalid'] = $e->getMessage();
                } catch (\WriteTextAI\WriteTextAI\Exception\ImageDownloadFailed $e) {
                    $failedImages[] = $failedImageUrl;
                    $downloadFailed[] = [
                        "url" => $failedImageUrl,
                        "id" => $image['id']
                    ];
                    $errorMessages['download_failed'] = $e->getMessage();
                } catch (\WriteTextAI\WriteTextAI\Exception\ImageGeneral $e) {
                    $failedImages[] = $failedImageUrl;
                    $general[] = [
                        "url" => $failedImageUrl,
                        "id" => $image['id']
                    ];
                    $errorMessages['general'] = __('A system error has occurred. Please try again.'
                        . ' If the issue persists, please contact our support team at support@writetext.ai.');
                }
            }
        }

        return [
            'failed_images' => $failedImages,
            'success_images' => $successImages,
            'invalid' => $invalid,
            'not_supported' => $notSupported,
            'download_failed' => $downloadFailed,
            'general' => $general,
            'error_messages' => $errorMessages
        ];
    }
}
