<?php
if (!function_exists('sitesmith_sanitize_html')) {

    function sitesmith_sanitize_html(string $html): string {
        if ($html === '') return '';

        static $allowed = [
            'a' => ['href','title','target','rel'],
            'p' => [], 'br' => [], 'hr' => [],
            'div' => ['class'], 'span' => ['class'],
            'section' => ['class'], 'article' => ['class'],
            'header' => ['class'], 'footer' => ['class'],
            'main' => ['class'], 'aside' => ['class'], 'nav' => ['class'],
            'ul' => [], 'ol' => [], 'li' => [],
            'h1' => [], 'h2' => [], 'h3' => [], 'h4' => [], 'h5' => [], 'h6' => [],
            'em' => [], 'strong' => [], 'b' => [], 'i' => [], 'u' => [], 's' => [],
            'blockquote' => [], 'code' => [], 'pre' => [],
            'img' => ['src','alt','title','width','height'],
            'figure' => [], 'figcaption' => [],
            'iframe' => ['src','title','width','height','frameborder','allowfullscreen','allow'],
        ];
        static $iframeHosts = [
            'www.youtube.com','youtube.com','youtube-nocookie.com',
            'player.vimeo.com','vimeo.com',
            'www.google.com','maps.google.com',
        ];

        $dom = new DOMDocument('1.0','UTF-8');
        libxml_use_internal_errors(true);
        $wrapped = '<?xml encoding="UTF-8"?><div>'.$html.'</div>';
        if (!$dom->loadHTML($wrapped, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NOWARNING | LIBXML_NOERROR)) {
            libxml_clear_errors();
            return '';
        }
        libxml_clear_errors();

        $root = $dom->getElementsByTagName('div')->item(0);
        if (!$root) return '';
        _sitesmith_clean_node($root, $allowed, $iframeHosts);

        $out = '';
        foreach ($root->childNodes as $child) $out .= $dom->saveHTML($child);
        return $out;
    }

    function _sitesmith_clean_node(DOMNode $node, array $allowed, array $iframeHosts): void {
        if (!$node->hasChildNodes()) return;
        $kids = [];
        foreach ($node->childNodes as $c) $kids[] = $c;
        foreach ($kids as $child) {
            if ($child->nodeType !== XML_ELEMENT_NODE) continue;
            $el  = $child;
            $tag = strtolower($el->tagName);

            if (!isset($allowed[$tag])) {
                if (in_array($tag, ['script','style','object','embed','link','meta','form','input','button','select','textarea'], true)) {
                    $el->parentNode->removeChild($el);
                } else {
                    while ($el->firstChild) $el->parentNode->insertBefore($el->firstChild, $el);
                    $el->parentNode->removeChild($el);
                }
                continue;
            }
            $allowedAttrs = $allowed[$tag];
            $toRemove = [];
            foreach ($el->attributes as $a) {
                $name = strtolower($a->name);
                if (!in_array($name, $allowedAttrs, true)) { $toRemove[] = $name; continue; }
                if (in_array($name, ['href','src'], true)) {
                    $v = trim($a->value);
                    if (preg_match('#^(javascript|vbscript|file):#i', $v)) { $toRemove[] = $name; continue; }
                    if (preg_match('#^data:#i', $v) && !preg_match('#^data:image/(png|jpeg|gif|webp);base64,#i', $v)) { $toRemove[] = $name; continue; }
                    if ($tag === 'iframe') {
                        $host = parse_url($v, PHP_URL_HOST) ?: '';
                        if (!in_array(strtolower($host), $iframeHosts, true)) { $toRemove[] = $name; continue; }
                    }
                }
            }
            foreach ($toRemove as $n) $el->removeAttribute($n);
            _sitesmith_clean_node($el, $allowed, $iframeHosts);
        }
    }
}
