<?php
/**
 * Mirasvit
 *
 * This source file is subject to the Mirasvit Software License, which is available at https://mirasvit.com/license/.
 * Do not edit or add to this file if you wish to upgrade the to newer versions in the future.
 * If you wish to customize this module for your needs.
 * Please refer to http://www.magentocommerce.com for more information.
 *
 * @category  Mirasvit
 * @package   mirasvit/module-cache-warmer
 * @version   1.11.13
 * @copyright Copyright (C) 2026 Mirasvit (https://mirasvit.com/)
 */



declare(strict_types=1);

namespace Mirasvit\CacheWarmer\Service;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Config\Storage\WriterInterface;
use Magento\Framework\App\ResourceConnection;
use Mirasvit\CacheWarmer\Api\Data\UserAgentInterface;
use Mirasvit\CacheWarmer\Api\Data\PageInterface;
use Mirasvit\CacheWarmer\Api\Data\SourceInterface;

class UserAgentService
{
    public const USER_AGENT_MIGRATION_FLAG_PATH = 'cache_warmer/system/user_agent_migration_flag';

    /**
     * @var WriterInterface
     */
    private $configWriter;

    /**
     * @var ScopeConfigInterface
     */
    private $scopeConfig;

    /**
     * @var ResourceConnection
     */
    private $resourceConnection;

    public function __construct(
        WriterInterface $configWriter,
        ScopeConfigInterface $scopeConfig,
        ResourceConnection $resourceConnection
    ) {
        $this->resourceConnection = $resourceConnection;
        $this->configWriter = $configWriter;
        $this->scopeConfig = $scopeConfig;
    }

    public function refreshPagesByUserAgents(): void
    {
        if ($this->scopeConfig->isSetFlag(self::USER_AGENT_MIGRATION_FLAG_PATH)) {
            return;
        }

        $connection = $this->resourceConnection->getConnection();
        $pagesTable = $this->resourceConnection->getTableName('mst_cache_warmer_page');
        $sourcesTable = $this->resourceConnection->getTableName('mst_cache_warmer_source');

        $bind = [
            ':pageSourceIdField' => PageInterface::SOURCE_ID,
            ':sourceIdField' => SourceInterface::ID,
            ':pagesUserAgentField' => PageInterface::USER_AGENT,
            ':sourceSourceTypeField' => SourceInterface::SOURCE_TYPE,

            ':sourceTypeCrawler' => $connection->quote(SourceInterface::TYPE_CRAWLER),
            ':sourceTypeSitemap' => $connection->quote(SourceInterface::TYPE_SITEMAP),
            ':sourceTypeFile' => $connection->quote(SourceInterface::TYPE_FILE),

            ':newUserAgentCrawler' => $connection->quote(UserAgentInterface::DESKTOP_USER_AGENT),
            ':newUserAgentSitemap' => $connection->quote(UserAgentInterface::SITEMAP_USER_AGENT),
            ':newUserAgentFile' => $connection->quote(UserAgentInterface::FILE_USER_AGENT)
        ];

        $bindSearch = array_keys($bind);
        $bindReplace = array_values($bind);

        $sql = "
            SELECT :pagesUserAgentField FROM $pagesTable
            WHERE $pagesTable.:pageSourceIdField IN (
                SELECT $sourcesTable.:sourceIdField FROM $sourcesTable
                WHERE $sourcesTable.:sourceSourceTypeField
                IN (:sourceTypeCrawler, :sourceTypeSitemap, :sourceTypeFile)
            )
            AND $pagesTable.:pagesUserAgentField NOT IN (:newUserAgentCrawler, :newUserAgentSitemap, :newUserAgentFile)
            LIMIT 1
        ";

        $sql = str_replace(
            $bindSearch,
            $bindReplace,
            $sql
        );


        $oldUserAgent = $connection->query($sql)->fetch();

        if (false === $oldUserAgent) {
            $this->configWriter->save(self::USER_AGENT_MIGRATION_FLAG_PATH, 1);
            return;
        }

        $sql = "
            UPDATE $pagesTable
            SET :pagesUserAgentField = (
                CASE (
                        SELECT :sourceSourceTypeField
                        FROM $sourcesTable
                        WHERE $pagesTable.:pageSourceIdField = $sourcesTable.:sourceIdField
                        LIMIT 1
                    )

                    WHEN :sourceTypeCrawler THEN :newUserAgentCrawler
                    WHEN :sourceTypeSitemap THEN :newUserAgentSitemap
                    WHEN :sourceTypeFile THEN :newUserAgentFile

                    ELSE $pagesTable.:pagesUserAgentField
                END
            )
            WHERE $pagesTable.:pageSourceIdField IN (
                SELECT $sourcesTable.:sourceIdField FROM $sourcesTable
                WHERE $sourcesTable.:sourceSourceTypeField
                IN (:sourceTypeCrawler, :sourceTypeSitemap, :sourceTypeFile)
            )
            AND $pagesTable.:pagesUserAgentField NOT IN (:newUserAgentCrawler, :newUserAgentSitemap, :newUserAgentFile)
            LIMIT 10000;
        ";

        $sql = str_replace(
            $bindSearch,
            $bindReplace,
            $sql
        );

        $connection->query($sql);
    }
}
