<?php

declare(strict_types=1);

/**
 * @author Amasty Team
 * @copyright Copyright (c) Amasty (https://www.amasty.com)
 * @package Lazy Load for Magento 2 (System)
 */

namespace Amasty\LazyLoad\Model\Crawler\Combination;

use Amasty\LazyLoad\Model\ConfigProvider;
use Amasty\LazyLoad\Model\OptionSource\Crawler\AvifSupport;
use Amasty\LazyLoad\Model\OptionSource\Crawler\UserAgents;
use Amasty\PageSpeedTools\Model\DeviceDetect;
use GuzzleHttp\RequestOptions;
use Magento\Framework\App\Http\Context;

class WebpAndDeviceCombination
{
    public const WEBP_AVIF = 'webp_avif';
    public const NO_WEBP_AVIF = 'no_webp_avif';
    public const WEBP_NO_AVIF = 'webp_no_avif';
    public const NO_WEBP_NO_AVIF = 'no_webp_no_avif';

    public const DEVICE_AGENT_MAP = [
        DeviceDetect::DESKTOP => [
            self::WEBP_AVIF => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
                . ' Chrome/103.0.5060.134 Safari/537.36',
            self::NO_WEBP_AVIF => '', // there is no suitable and real user agent
            self::WEBP_NO_AVIF => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
                . ' Chrome/85.0.4183.121 Safari/537.36',
            self::NO_WEBP_NO_AVIF => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0'
        ],
        DeviceDetect::TABLET => [
            self::WEBP_AVIF => 'Mozilla/5.0 (Linux; Android 12; SM-T720) AppleWebKit/537.36 (KHTML, like Gecko)'
                . ' Chrome/103.0.5060.134 Safari/537.36',
            self::NO_WEBP_AVIF => '', // there is no suitable and real user agent
            self::WEBP_NO_AVIF => 'Mozilla/5.0 (iPad; CPU OS 14_8_1 like Mac OS X) AppleWebKit/605.1.15'
                . ' (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1',
            self::NO_WEBP_NO_AVIF => 'Mozilla/5.0 (iPad; CPU OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46'
                . ' (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1'
        ],
        DeviceDetect::MOBILE => [
            self::WEBP_AVIF => 'Mozilla/5.0 (Linux; Android 12; SM-T720) AppleWebKit/537.36 (KHTML, like Gecko)'
                . ' Chrome/103.0.5060.134 Safari/537.36',
            self::NO_WEBP_AVIF => '', // there is no suitable and real user agent
            self::WEBP_NO_AVIF => 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_8_1 like Mac OS X) AppleWebKit/605.1.15'
                . ' (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1',
            self::NO_WEBP_NO_AVIF => 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46'
                . ' (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1'
        ]
    ];

    /**
     * @var ConfigProvider
     */
    private $configProvider;

    public function __construct(ConfigProvider $configProvider)
    {
        $this->configProvider = $configProvider;
    }

    public function getVariations(): array
    {
        if (!$this->configProvider->isEnabled() || !$this->configProvider->isReplaceImagesUsingUserAgent()) {
            return [];
        }

        $combination = [];
        $webpSupportConfig = $this->configProvider->convertStringToArray(
            $this->configProvider->getCustomValue('amasty_fpc/optimizer/webp_support') ?? UserAgents::WEBP,
            ','
        );
        $deviceConfig = $this->configProvider->convertStringToArray(
            $this->configProvider->getCustomValue('amasty_fpc/optimizer/devices') ?? DeviceDetect::DESKTOP,
            ','
        );
        $avifConfig = $this->configProvider->convertStringToArray(
            $this->configProvider->getCustomValue('amasty_fpc/optimizer/avif_support') ?? AvifSupport::AVIF,
            ','
        );

        foreach ($avifConfig as $avifSupport) {
            foreach ($webpSupportConfig as $webpSupport) {
                foreach ($deviceConfig as $device) {
                    $combination[] = [
                        'webp' => $webpSupport,
                        'device' => $device,
                        'avif' => $avifSupport
                    ];
                }
            }
        }

        return $combination;
    }

    public function getCombinationKey(): string
    {
        return 'crawler_webp_and_device';
    }

    public function modifyRequest(array $combination, array &$requestParams, Context $context)
    {
        if (!$this->configProvider->isEnabled() || !$this->configProvider->isReplaceImagesUsingUserAgent()) {
            return;
        }

        $deviceConfig = $combination[$this->getCombinationKey()] ?? null;

        if ($deviceConfig) {
            $webpSupport = $deviceConfig['webp'];
            $device = $deviceConfig['device'];
            $avifSupport = $deviceConfig['avif'];
            $requestParams[RequestOptions::HEADERS]['User-Agent']
                = self::DEVICE_AGENT_MAP[$device][$webpSupport . '_' . $avifSupport]
                ?? '';
            $context->setValue(
                'amasty_device_type',
                $device,
                DeviceDetect::DESKTOP
            );
            $context->setValue(
                'amasty_is_use_webp',
                $webpSupport === UserAgents::WEBP ? 1 : 0,
                0
            );
            $context->setValue(
                'amasty_is_use_avif',
                $avifSupport === AvifSupport::AVIF ? 1 : 0,
                0
            );
        }
    }

    public function prepareLog(array $crawlerLogData, array $combination): array
    {
        $deviceConfig = $combination[$this->getCombinationKey()] ?? null;

        if ($deviceConfig) {
            $crawlerLogData['avif_support'] = $deviceConfig['avif'] ?? null;
            $crawlerLogData['webp_support'] = $deviceConfig['webp'] ?? null;
            $crawlerLogData['device'] = $deviceConfig['device'] ?? null;
        }

        return $crawlerLogData;
    }
}
