<?php
/**
 * Bio sanitizer (no DOMDocument required).
 *
 * Accepts arbitrary user/legacy HTML and returns a strictly-whitelisted
 * subset:
 *   - Allowed tags: p, br, strong, em, b, i, u, ul, ol, li, a
 *   - All attributes stripped EXCEPT href on <a>, and href must use a
 *     safe scheme (http, https, mailto). Safe anchors get target="_blank"
 *     and rel="noopener noreferrer" added automatically.
 *   - <script>, <style>, and HTML comments are removed entirely (tag AND
 *     content). All other disallowed tags are stripped but their text
 *     content is kept (strip_tags semantics).
 *   - Anchors with no safe href are unwrapped (text remains, link gone).
 *
 * Implemented with strip_tags + regex so the host doesn't need the DOM/xml
 * PHP extension.
 */
declare(strict_types=1);

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

    // Drop legacy backslash-escaped quotes
    if (strpos($html, "\\'") !== false || strpos($html, '\\"') !== false) {
        $html = stripslashes($html);
    }

    // Remove dangerous-content tags entirely (tag + inner content + comments)
    $html = preg_replace('/<script\b[^>]*>.*?<\/script\s*>/is', '', $html);
    $html = preg_replace('/<style\b[^>]*>.*?<\/style\s*>/is', '', $html);
    $html = preg_replace('/<!--.*?-->/s', '', $html);

    // Strip everything except the whitelist (inner text of stripped tags is kept)
    $html = strip_tags($html, '<p><br><strong><em><b><i><u><ul><ol><li><a>');

    // Strip ALL attributes from kept non-anchor tags
    $html = preg_replace_callback(
        '/<(p|br|strong|em|b|i|u|ul|ol|li)\b[^>]*?(\/?)>/i',
        function ($m) {
            $tag = strtolower($m[1]);
            $self_close = $tag === 'br' ? ' /' : '';
            return '<' . $tag . $self_close . '>';
        },
        $html
    );

    // Anchors: extract a safe href, drop everything else, add target/rel
    $html = preg_replace_callback(
        '/<a\b([^>]*)>/i',
        function ($m) {
            $attrs = $m[1];
            $safe_href = null;
            if (preg_match('/\bhref\s*=\s*("([^"]*)"|\'([^\']*)\'|([^\s>]+))/i', $attrs, $hm)) {
                $href = trim($hm[2] !== '' ? $hm[2] : ($hm[3] !== '' ? $hm[3] : ($hm[4] ?? '')));
                if (preg_match('#^(https?://|mailto:)#i', $href)) {
                    $safe_href = $href;
                }
            }
            if ($safe_href === null) {
                // Mark with a sentinel so we can unwrap below
                return '<a>';
            }
            $safe = htmlspecialchars($safe_href, ENT_QUOTES, 'UTF-8');
            return '<a href="' . $safe . '" target="_blank" rel="noopener noreferrer">';
        },
        $html
    );

    // Unwrap anchors with no valid href (keep their text)
    $html = preg_replace('/<a>(.*?)<\/a>/is', '$1', $html);

    // Collapse stray empty paragraphs
    $html = preg_replace('/<p>\s*<\/p>/i', '', $html);

    return trim($html);
}
