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

namespace WriteTextAI\WriteTextAI\Model;

use WriteTextAI\WriteTextAI\Helper\Fields as FieldsHelper;
use WriteTextAI\WriteTextAI\Model\Api\CurlBuilder;
use WriteTextAI\WriteTextAI\Helper\Store as StoreHelper;

/**
 * @api
 */
class ApiManager
{
    /**
     * @var FieldsHelper
     */
    protected $fieldsHelper;

    /**
     * @var CurlBuilder
     */
    protected $curlBuilder;

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

    /**
     * Constructor
     *
     * @param FieldsHelper $fieldsHelper
     * @param CurlBuilder $curlBuilder
     * @param StoreHelper $storeHelper
     */
    public function __construct(
        FieldsHelper $fieldsHelper,
        CurlBuilder $curlBuilder,
        StoreHelper $storeHelper
    ) {
        $this->fieldsHelper = $fieldsHelper;
        $this->curlBuilder = $curlBuilder;
        $this->storeHelper = $storeHelper;
    }

    /**
     * Get tones
     *
     * @param string $locale
     * @return array
     */
    public function getTones($locale = 'en-US')
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Tones', [], 'get', $locale) ?? [];
    }

    /**
     * Get styles
     *
     * @param string $locale
     * @return array
     */
    public function getStyles($locale = 'en-US')
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Styles', [], 'get', $locale) ?? [];
    }

    /**
     * Get audiences
     *
     * @param string $locale
     * @return array
     */
    public function getAudiences($locale = 'en-US')
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Audiences', [], 'get', $locale) ?? [];
    }

    /**
     * Get credit
     *
     * @return array
     */
    public function getCredit()
    {
        return $this->curlBuilder->getApiResponse('text/Credit') ?? [];
    }

    /**
     * Set free premium credits to false
     *
     * @param array $body
     *
     * @return array
     */
    public function setFreePremiumCreditsToFalse($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Credit/setFreePremiumCreditsToFalse', $body, 'post');
    }

    /**
     * Set welcome premium 20 to false
     *
     * @param array $body
     *
     * @return array
     */
    public function setWelcomePremium20ToFalse($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Credit/setWelcomePremium20ToFalse', $body, 'post');
    }

    /**
     * Set unlocked free trial to false
     *
     * @param array $body
     *
     * @return array
     */
    public function setUnlockedFreeTrialToFalse($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Credit/setUnlockedFreeTrialToFalse', $body, 'post');
    }

    /**
     * Set no credits free trial to false
     *
     * @param array $body
     *
     * @return array
     */
    public function setNoCreditsFreeTrialToFalse($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Credit/setNoCreditsFreeTrialToFalse', $body, 'post');
    }

    /**
     * Set unlocked professional to false
     *
     * @param array $body
     *
     * @return array
     */
    public function setUnlockedProfessionalToFalse($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Credit/setUnlockedProfessionalToFalse', $body, 'post');
    }

    /**
     * Set unlocked enterprise to false
     *
     * @param array $body
     *
     * @return array
     */
    public function setUnlockedEnterpriseToFalse($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Credit/setUnlockedEnterpriseToFalse', $body, 'post');
    }

    /**
     * Get ads
     *
     * @return array
     */
    public function getAccount()
    {
        return $this->curlBuilder->getApiResponse('web/Account/All', [
            'GetAccount' => 'true'
        ]) ?? [];
    }

    /**
     * Get ads
     *
     * @return array
     */
    public function getAds()
    {
        return $this->curlBuilder->getApiResponse('web/ad/SquareMagento') ?? [];
    }

    /**
     * Get ads
     *
     * @param string $type
     * @return array
     */
    public function getSpecificAds($type)
    {
        return $this->curlBuilder->getApiResponse('web/ad/'.$type) ?? [];
    }

    /**
     * Get credits
     *
     * @return array
     */
    public function getCredits()
    {
        $response = $this->curlBuilder->getApiResponse('text/Generate/Credits');

        $propertyMapping = [
            "page title" => "page_title",
            "page description" => "page_description",
            "product description" => "product_description",
            "excerpt" => "short_product_description",
            "open graph text" => "open_graph"
        ];

        $this->fieldsHelper->changePropertyNames($response, $propertyMapping);

        return $response ?? [];
    }

    /**
     * Get formal languages
     *
     * @return array
     */
    public function getFormalLanguageSupport()
    {
        return $this->curlBuilder->getApiResponse('text/Generate/FormalLanguageSupport');
    }

    /**
     * Upload image
     *
     * @param array $body
     * @return array
     */
    public function uploadImage($body)
    {
        return $this->curlBuilder->getApiResponse('text/Image', $body, 'post');
    }

    /**
     * Get image
     *
     * @param array $body
     * @return array
     */
    public function getImage($body)
    {
        return $this->curlBuilder->getApiResponse('text/Image', $body);
    }

    /**
     * Get image list
     *
     * @param array $body
     * @return array
     */
    public function getImageList($body)
    {
        return $this->curlBuilder->getApiResponse('text/Image/List', $body);
    }

    /**
     * Generate alt text
     *
     * @param array $body
     * @return array
     */
    public function generateAltText($body)
    {
        return $this->curlBuilder->getApiResponse('text/Image/GenerateAltText', $body, 'post');
    }

    /**
     * Update alt text
     *
     * @param array $body
     * @return array
     */
    public function updateAltText($body)
    {
        return $this->curlBuilder->getApiResponse('text/Image/altText', $body, 'post');
    }

    /**
     * Batch update alt text
     *
     * @param array $body
     * @return array
     */
    public function batchUpdateAltText($body)
    {
        return $this->curlBuilder->getApiResponse('text/Image/altText/batch', $body, 'post');
    }

    /**
     * Get formal languages
     *
     * @param string $acceptLanguage
     *
     * @return array
     */
    public function getFormalLanguages($acceptLanguage = 'en-US')
    {
        return $this->curlBuilder->getApiResponse(
            'text/Generate/FormalLanguages',
            [
                'language' => $acceptLanguage
            ],
            'get',
            $acceptLanguage
        );
    }

    /**
     * Get disallowed combinations
     *
     * @return array
     */
    public function getDisallowedCombinations()
    {
        return $this->curlBuilder->getApiResponse('text/Generate/DisallowedCombinations');
    }

    /**
     * Get rules
     *
     * @return array
     */
    public function getRules()
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Rules');
    }

    /**
     * Get reviews
     *
     * @param array $params
     * @return string
     */
    public function getReviews($params = [])
    {
        return $this->curlBuilder->getApiResponse('text/Review', $params);
    }

    /**
     * Update review status
     *
     * @param array $body
     * @return string
     */
    public function updateReview($body)
    {
        return $this->curlBuilder->getApiResponse('text/Review', $body, 'post');
    }

    /**
     * Batch update reviews
     *
     * @param array $body
     * @return string
     */
    public function batchUpdateReviews($body)
    {
        return $this->curlBuilder->getApiResponse('text/Review/batch', $body, 'post');
    }

    /**
     * Send feedback
     *
     * @param array $body
     * @return string
     */
    public function sendFeedback($body)
    {
        return $this->curlBuilder->getApiResponse('text/Feedback/Submit', $body, 'post');
    }

    /**
     * Delete feedback
     *
     * @param array $body
     * @return string
     */
    public function deleteFeedback($body)
    {
        return $this->curlBuilder->getApiResponseCustom('text/Feedback', $body, 'delete');
    }

    /**
     * Generate
     *
     * @param array $body
     * @return string
     */
    public function generate($body)
    {
        return $this->curlBuilder->getApiResponse('text/Generate/v2', $body, 'post');
    }

    /**
     * Cancel generate
     *
     * @param string $id
     * @return string
     */
    public function cancelBulk($id)
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Bulk/' . $id . '/cancel', [], 'post');
    }

    /**
     * Retry generate
     *
     * @param string $id
     * @return string
     */
    public function retryGenerate($id)
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Bulk/' . $id . '/retry', [], 'post');
    }

    /**
     * Get bulk status
     *
     * @return string
     */
    public function getBulkStatus()
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Bulk');
    }

    /**
     * Get generate status
     *
     * @param string $id
     *
     * @return string
     */
    public function getBulkRequestById($id)
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Bulk/' . $id);
    }

    /**
     * Get generate status by id
     *
     * @param string $id
     * @return string
     */
    public function getGenerateStatusById($id)
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Bulk/' . $id);
    }

    /**
     * Get generated text
     *
     * @param array $body
     * @return string
     */
    public function getGenerated($body)
    {
        return $this->curlBuilder->getApiResponse('text/Generate', $body);
    }

    /**
     * Get generated status
     *
     * @param array $body
     * @return string
     */
    public function getGeneratedStatus($body)
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Status', $body);
    }

    /**
     * Get generate by request id
     *
     * @param string $requestId
     * @return string
     */
    public function getGenerateByRequestId($requestId)
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Request/' . $requestId);
    }

    /**
     * Get image alt text status
     *
     * @param array $body
     * @return string
     */
    public function getImageAltTextStatus($body)
    {
        return $this->curlBuilder->getApiResponse('text/Image/Status', $body);
    }

    /**
     * Get review status
     *
     * @param array $body
     * @return string
     */
    public function filterReviewStatus($body)
    {
        return $this->curlBuilder->getApiResponse('text/Review/Status', $body);
    }

    /**
     * Get locations
     *
     * @return array
     */
    public function getLocations()
    {
        $response = $this->curlBuilder->getApiResponse('text/KeywordAnalysis/Locations', [], 'get');

        return $response['result'] ?? [];
    }

    /**
     * Get suggested audience
     *
     * @param string $storeId
     * @param string $recordId
     * @param string $keywords
     * @param string $clear
     * @param string $type
     *
     * @return string
     */
    public function getSuggestedAudience(
        $storeId,
        $recordId,
        $keywords,
        $clear = 'false',
        $type = 'Product'
    ) {
        $acceptLanguage =  $this->storeHelper->getFormattedLanguage($storeId);

        $body = [
            "storeId" => $storeId,
            "recordId" => $recordId,
            "text" => $keywords,
            "clearAllText" => $clear,
            "type" => $type,
            "language" => $acceptLanguage
        ];

        return $this->curlBuilder->getApiResponse('text/Suggestion/Audience', $body, 'get', $acceptLanguage);
    }

    /**
     * Select audience
     *
     * @param string $storeId
     * @param string $recordId
     * @param string $keywords
     * @param array $selected
     * @param string $type
     *
     * @return string
     */
    public function selectAudience(
        $storeId,
        $recordId,
        $keywords,
        $selected,
        $type = 'Product'
    ) {
        $acceptLanguage =  $this->storeHelper->getFormattedLanguage($storeId);

        $body = [
            "storeId" => $storeId,
            "recordId" => $recordId,
            "text" => $keywords,
            "selected" => $selected,
            "type" => $type,
            "language" => $acceptLanguage
        ];

        return $this->curlBuilder->getApiResponse(
            'text/Suggestion/Audience',
            json_encode($body),
            'post',
            $acceptLanguage
        );
    }

    /**
     * Get history
     *
     * @param array $params
     * @param string $language
     */
    public function getHistory($params = [], $language = 'en-US')
    {
        return $this->curlBuilder->getApiResponse('text/Generate/History', $params, 'get', $language);
    }

    /**
     * Save
     *
     * @param array $body
     * @return string
     */
    public function save($body)
    {
        return $this->curlBuilder->getApiResponse('text/Generate/text', json_encode($body), 'post');
    }

    /**
     * Get ETags
     *
     * @return array
     */
    public function getETags()
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Etags');
    }

    /**
     * Get region
     *
     * @return string
     */
    public function getRegion()
    {
        $regions = $this->curlBuilder->getRegions();
        $fastest = [];

        foreach ($regions as $region) {
            $time = $this->curlBuilder->pingRegion($region);
            if (isset($fastest['time']) ? $time < $fastest['time'] : true) {
                $fastest = [
                    'region' => $region,
                    'time' => $time
                ];
            }
        }

        return $fastest['region'];
    }

    /**
     * Send statistics
     *
     * @param array $body
     * @return array
     */
    public function sendStatistics($body)
    {
        return $this->curlBuilder->sendPostWithoutAuth('web/Statistics', $body);
    }

    /**
     * Get current template settings
     *
     * @return array
     */
    public function getCurrentTemplateSettings()
    {
        try {
            return $this->curlBuilder->getApiResponse('web/TemplateSettings/current');
        } catch (\WriteTextAI\WriteTextAI\Exception\ApiException $e) {
            return [];
        }
    }

    /**
     * Report new records
     *
     * @param array $body
     * @return array
     */
    public function reportNewRecords($body)
    {
        return $this->curlBuilder->getApiResponse('text/Generate/New', json_encode($body), 'post');
    }

    /**
     * Email new products
     *
     * @param array $body
     * @return array
     */
    public function emailNewProducts($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Email/NewProducts', json_encode($body), 'post');
    }

    /**
     * Email automatic transfer status
     *
     * @param array $body
     * @return array
     */
    public function emailAutomaticTransferStatus($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Email/AutomaticTransfer', json_encode($body), 'post');
    }

    /**
     * Email bulk transfer status
     *
     * @param array $body
     * @return array
     */
    public function emailBulkTransferStatus($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Email/BulkTransfer', json_encode($body), 'post');
    }

    /**
     * Archive record
     *
     * @param array $body
     * @return array
     */
    public function archiveRecord($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Generate/archive', json_encode($body), 'post');
    }

    /**
     * Archive product image
     *
     * @param array $body
     * @return array
     */
    public function archiveProductImage($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Image/archive', json_encode($body), 'post');
    }

    /**
     * Get token time
     *
     * @return array
     */
    public function getTokenTime()
    {
        return $this->curlBuilder->getTokenTime();
    }

    /**
     * Send token time
     *
     * @param array $tokenTime
     * @return array
     */
    public function sendTokenTime($tokenTime)
    {
        return $this->curlBuilder->sendTokenTime($tokenTime);
    }

    /**
     * Clean up cURL handle pool
     */
    public function cleanupPool()
    {
        $this->curlBuilder->cleanupPool();
    }
    /**
     * Get transfered at
     *
     * @param array $body
     * @return array
     */
    public function sendCustomNotification($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Notification/custom', json_encode($body), 'post');
    }

    /**
     * Transfer via API
     *
     * @param array $body
     * @return array
     */
    public function transferViaApi($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/Generate/Transfer', json_encode($body), 'post');
    }

    /**
     * Send API integration
     *
     * @param array $body
     * @return array
     */
    public function sendApiIntegration($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/PlatformSettings', json_encode($body), 'post');
    }

    /**
     * Ping API
     *
     * @param array $body
     * @return array
     */
    public function pingApi($body = [])
    {
        return $this->curlBuilder->getApiResponse('text/PlatformSettings/ping', json_encode($body), 'post');
    }
}
