<?php

namespace app;

use app\foreignone\PostLanguage;

class MarkupUtil
{
    public static function markdownToHtml(string        $md,
                                          bool          $use_image_previews = true,
                                          ?PostLanguage $lang = null,
                                          bool          $no_paragraph = false): string {
        $pd = new MyParsedown(useImagePreviews: $use_image_previews, lang: $lang);
        $html = $pd->text($md);

        if ($no_paragraph)
            $html = preg_replace('/<p>(.*?)<\/p>/', '$1', $html);

        else {
            // collect references
            $re = '/^<p>(\[([io]?\d{1,2})]) (.*?)<\/p>/ms';
            $result = preg_match_all($re, $html, $matches);
            if (pcreNoError($result)) {
                $reftitles_map = [];
                foreach ($matches[2] as $i => $refname) {
                    $reftitles_map[$refname] = trim(htmlspecialchars_decode(strip_tags($matches[3][$i])));
                }
                $span_opening_tag = '<span class="blog-footnote-ref">';
                $html = preg_replace($re, '<p class="blog-footnote-line" id="footnote_$2">'.$span_opening_tag.'$1</span> $3</p>', $html);
                $re = '/'.implode('|', array_map(fn($m) => '(?:'.$span_opening_tag.')?'.preg_quote($m, '/'), $matches[1])).'/';
                $html = preg_replace_callback($re,
                    function ($match) use ($span_opening_tag, $reftitles_map) {
                        if (str_starts_with($match[0], $span_opening_tag))
                            return $match[0];
                        if (!preg_match('/\[([io]?\d{1,2})]/', $match[0], $refmatch))
                            return $match[0];
                        $refname = $refmatch[1];
                        $reftitle = $reftitles_map[$refname];
                        return '<a href="#footnote_'.$refname.'" class="blog-ref" title="'.htmlescape($reftitle).'">'.$match[0].'</a>';
                    }, $html);
            }
        }

        return $html;
    }

    public static function toc(string $md): string {
        $pd = new MyParsedown([
            'toc' => [
                'lowercase' => true,
                'transliterate' => true,
                'urlencode' => false,
                'headings' => ['h1', 'h2', 'h3']
            ]
        ]);
        $pd->text($md);
        return $pd->contentsList();
    }

    public static function htmlToText(string $html): string {
        $text = html_entity_decode(strip_tags($html));
        $lines = explode("\n", $text);
        $lines = array_map('trim', $lines);
        $text = implode("\n", $lines);
        $text = preg_replace("/(\r?\n){2,}/", "\n\n", $text);
        return $text;
    }

    public static function htmlImagesFix(string $html, bool $is_retina, string $user_theme): string {
        global $config;
        $is_dark_theme = $user_theme === 'dark';
        return preg_replace_callback(
            '/('.preg_quote($config['uploads_path'], '/').'\/\w{8}\/)([ap])(\d+)x(\d+)(\.jpg)/',
            function ($match) use ($is_retina, $is_dark_theme) {
                $mult = $is_retina ? 2 : 1;
                $is_alpha = $match[2] == 'a';
                return $match[1].$match[2].(intval($match[3]) * $mult).'x'.(intval($match[4]) * $mult).($is_alpha && $is_dark_theme ? '_dark' : '').$match[5];
            },
            $html
        );
    }
}