<?php
namespace Autogedal\BlogInternalLinking\Plugin\Frontend;

use Magento\Framework\Registry;
use Magento\Framework\View\LayoutInterface;
use Autogedal\BlogInternalLinking\Block\Frontend\LinkingGroup;

class InjectLinkingGroup
{
    private $registry;
    private $layout;

    public function __construct(Registry $registry, LayoutInterface $layout)
    {
        $this->registry = $registry;
        $this->layout   = $layout;
    }

    public function afterToHtml(\Zemez\Blog\Block\Post\View $subject, string $result): string
    {
        // Skip subclasses that extend View (their interceptors are instanceof the subclass)
        if ($subject instanceof \Zemez\Blog\Block\Post\View\Comments
            || $subject instanceof \Zemez\Blog\Block\Post\View\Posts
        ) {
            return $result;
        }

        $post = $this->registry->registry('tm_blog_post');
        if (!$post || !$post->getId()) {
            return $result;
        }

        $groupId = (int)$post->getData('linking_group_id');
        if (!$groupId) {
            return $result;
        }

        $blockName = 'autogedal.blog.linking.' . $post->getId();

        if ($this->layout->getBlock($blockName)) {
            return $result;
        }

        $blockHtml = $this->layout->createBlock(LinkingGroup::class, $blockName)->toHtml();

        if (!$blockHtml) {
            return $result;
        }

        // Inject at ~50% of article paragraphs, strictly within post-text.
        // Regex allows extra classes/attributes and whitespace variations in the marker divs.
        $postTextPos = false;
        $postDataPos = false;
        $postTextEnd = 0;

        if (preg_match('/<div[^>]+class=["\'][^"\']*\bpost-text\b[^"\']*["\'][^>]*>/i', $result, $m, PREG_OFFSET_CAPTURE)) {
            $postTextPos = $m[0][1];
            $postTextEnd = $postTextPos + strlen($m[0][0]);
        }

        if (preg_match('/<div[^>]+class=["\'][^"\']*\bpost-data\b[^"\']*["\'][^>]*>/i', $result, $m, PREG_OFFSET_CAPTURE)) {
            $postDataPos = $m[0][1];
        }

        if ($postTextPos !== false && $postDataPos !== false) {
            $contentStart = $postTextEnd;

            // Mask table contents so </p> tags inside <table> are not counted or targeted.
            // Replacement is same-length whitespace so all offsets stay valid against $result.
            $masked = preg_replace_callback(
                '/<table[\s\S]*?<\/table>/i',
                static fn($m) => str_repeat(' ', strlen($m[0])),
                $result
            );

            $section = substr($masked, $contentStart, $postDataPos - $contentStart);
            $pCount  = substr_count($section, '</p>');
            $targetP = max(1, (int)ceil($pCount / 2));

            $offset = $contentStart;
            for ($i = 0; $i < $targetP; $i++) {
                $found = strpos($masked, '</p>', $offset);
                if ($found === false || $found >= $postDataPos) {
                    break;
                }
                $offset = $found + 4;
            }

            if ($offset > $contentStart) {
                return substr($result, 0, $offset) . $blockHtml . substr($result, $offset);
            }

            return substr($result, 0, $postDataPos) . $blockHtml . substr($result, $postDataPos);
        }

        return $result . $blockHtml;
    }
}
