<?php

declare(strict_types=1);

namespace MauticPlugin\DealFlowBundle\Compat;

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

/**
 * Twig extension that exposes Mautic version helpers and compat filters.
 *
 * All version-branching in Twig templates MUST go through these functions
 * rather than inline PHP/Twig conditionals. This keeps version logic
 * centralized in MauticVersionAdapter and testable.
 *
 * On Mautic 5/6, also registers the `purify_allow_target_blank` Twig filter
 * that only exists in Mautic 7+ core. This prevents 500 errors on deal view.
 *
 * Registered as a tagged twig.extension service in Config/config.php.
 */
final class DealFlowCompatExtension extends AbstractExtension
{
    public function __construct(private readonly MauticVersionAdapter $adapter)
    {
    }

    /**
     * On Mautic 5/6, register purify_allow_target_blank as a compat filter.
     * On Mautic 7+, core provides this filter natively — we return empty to avoid collision.
     *
     * @return TwigFilter[]
     */
    public function getFilters(): array
    {
        if ($this->adapter->isVersion7OrAbove()) {
            return [];
        }

        return [
            new TwigFilter('purify_allow_target_blank', [$this, 'purifyAllowTargetBlank'], ['is_safe' => ['html']]),
        ];
    }

    /**
     * Sanitizes HTML while preserving basic formatting tags and target=_blank on links.
     *
     * Uses HTMLPurifier when available (same as Mautic 7 core), falls back to
     * strip_tags with an allow-list for basic formatting.
     */
    public function purifyAllowTargetBlank(?string $html): string
    {
        if (null === $html || '' === $html) {
            return '';
        }

        if (class_exists(\HTMLPurifier::class)) {
            $config = \HTMLPurifier_Config::createDefault();
            $config->set('HTML.TargetBlank', true);
            $purifier = new \HTMLPurifier($config);

            return $purifier->purify($html);
        }

        // Fallback: strip to safe tags if HTMLPurifier is not available
        return strip_tags($html, '<a><b><i><em><strong><p><br><ul><ol><li><h1><h2><h3><h4><h5><h6><span><div><table><tr><td><th><thead><tbody>');
    }

    /**
     * @return TwigFunction[]
     */
    public function getFunctions(): array
    {
        return [
            new TwigFunction('dealflow_mautic_version', [$this, 'getMauticVersion']),
            new TwigFunction('dealflow_mautic_major_version', [$this, 'getMauticMajorVersion']),
            new TwigFunction('dealflow_is_mautic_7', [$this, 'isMautic7']),
        ];
    }

    /**
     * Returns the full Mautic version string (e.g. "7.1.0").
     *
     * Usage in Twig: {{ dealflow_mautic_version() }}
     */
    public function getMauticVersion(): string
    {
        return $this->adapter->getVersion();
    }

    /**
     * Returns the Mautic major version integer (5, 6, or 7).
     *
     * Usage in Twig: {% if dealflow_mautic_major_version() >= 6 %}
     */
    public function getMauticMajorVersion(): int
    {
        return $this->adapter->getMajorVersion();
    }

    /**
     * Returns true when running on Mautic 7.x or higher.
     *
     * Usage in Twig: {% if dealflow_is_mautic_7() %}
     */
    public function isMautic7(): bool
    {
        return $this->adapter->isVersion7OrAbove();
    }
}
