<?php
declare(strict_types=1);

namespace Leadlion\Autogedal\Setup\Patch\Data;

use Magento\Cms\Api\BlockRepositoryInterface;
use Magento\Cms\Api\PageRepositoryInterface;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Psr\Log\LoggerInterface;

class UpdateUspRateZeroLinks implements DataPatchInterface
{
    public function __construct(
        private readonly BlockRepositoryInterface $blockRepository,
        private readonly PageRepositoryInterface $pageRepository,
        private readonly SearchCriteriaBuilder $searchCriteriaBuilder,
        private readonly FilterBuilder $filterBuilder,
        private readonly LoggerInterface $logger
    ) {
    }

    public function apply(): self
    {
        try {
            $this->updateCmsBlocks();
            $this->updateCmsPages();
        } catch (\Exception $e) {
            $this->logger->error('Error applying Data Patch UpdateUspRateZeroLinks: ' . $e->getMessage());
            throw $e;
        }

        return $this;
    }

    private function updateCmsBlocks(): void
    {
        $this->searchCriteriaBuilder->addFilters($this->getCommonFilters());
        $searchCriteria = $this->searchCriteriaBuilder->create();

        $blocks = $this->blockRepository->getList($searchCriteria)->getItems();

        foreach ($blocks as $block) {
            $originalContent = $block->getContent() ?? '';
            $newContent = $this->updateContent($originalContent);

            if ($newContent !== $originalContent) {
                $block->setContent($newContent);
                $this->blockRepository->save($block);
            }
        }
    }

    private function updateCmsPages(): void
    {
        $this->searchCriteriaBuilder->addFilters($this->getCommonFilters());
        $searchCriteria = $this->searchCriteriaBuilder->create();

        $pages = $this->pageRepository->getList($searchCriteria)->getItems();

        foreach ($pages as $page) {
            $originalContent = $page->getContent() ?? '';
            $newContent = $this->updateContent($originalContent);

            if ($newContent !== $originalContent) {
                $page->setContent($newContent);
                $this->pageRepository->save($page);
            }
        }
    }

    private function getCommonFilters(): array
    {
        return [
            $this->filterBuilder->setField('content')->setConditionType('like')->setValue('%3 rate%')->create(),
            $this->filterBuilder->setField('content')->setConditionType('like')->setValue('%3 Rate%')->create(),
            $this->filterBuilder->setField('content')->setConditionType('like')->setValue('%Alpha Bank%')->create(),
            $this->filterBuilder->setField('content')->setConditionType('like')->setValue('%alphabank%')->create(),
            $this->filterBuilder->setField('content')->setConditionType('like')->setValue('%brdfinance%')->create()
        ];
    }

    private function updateContent(string $content): string
    {
        $content = preg_replace_callback('/(?<!-)\b3\s+(rate)\b/iu', function($matches) {
            return '3-6 ' . $matches[1];
        }, $content);

        $alphaBankPatterns = [
            '/(?:•|&bull;|\*|-|&ndash;)?\s*Card\s+Cump[aă]r[aă]turi\s*-\s*Alpha Bank\s*(?:–|-|&ndash;)\s*<a[^>]+>.*?<\/a>\s*aveti detalii despre cum puteti obtine Card Cumparaturi Alpha Bank;?(?:\s*<\/?br\s*\/?>)?\r?\n?/iu',
            '/(?:•|&bull;|\*|-|&ndash;)?\s*Card\s+Cump[aă]r[aă]turi\s*-\s*<a[^>]+>Alpha Bank<\/a>(?:\s*<\/?br\s*\/?>)?\r?\n?/iu',
            '/<li[^>]*>\s*Card\s+Cump[aă]r[aă]turi\s*-\s*Alpha Bank.*?<\/li>\r?\n?/iu',
            '/(?:•|&bull;|\*|-|&ndash;)?\s*Card\s+Cump[aă]r[aă]turi\s*-\s*Alpha Bank(?:\s*<\/?br\s*\/?>)?\r?\n?/iu'
        ];
        
        $content = preg_replace($alphaBankPatterns, '', $content);

        $content = preg_replace(
            '/https?:\/\/(?:www\.)?brdfinance\.ro\/[^\s"\'<>]+/iu',
            'https://www.brd.ro/persoane-fizice/carduri-si-conturi/carduri/card-de-credit-brd',
            $content
        );

        return $content;
    }

    public function getAliases(): array
    {
        return [];
    }

    public static function getDependencies(): array
    {
        return [];
    }
}
