<?php
/**
 * TekDek - Utility Functions
 * 
 * Lightweight markdown renderer and helpers. No external dependencies.
 */

if (!defined('TEKDEK')) die('Direct access not permitted.');

/**
 * Convert markdown to HTML (lightweight, no dependencies).
 * Supports: headings, bold, italic, code blocks, inline code, links, images,
 * unordered/ordered lists, blockquotes, horizontal rules, paragraphs.
 */
function markdown_to_html(string $md): string {
    $md = str_replace("\r\n", "\n", $md);
    $lines = explode("\n", $md);
    $html = '';
    $in_code = false;
    $in_list = false;
    $in_ol = false;
    $in_blockquote = false;
    $paragraph = '';

    $flush_paragraph = function () use (&$html, &$paragraph) {
        if ($paragraph !== '') {
            $html .= '<p>' . inline_markdown(trim($paragraph)) . "</p>\n";
            $paragraph = '';
        }
    };

    $close_list = function () use (&$html, &$in_list, &$in_ol) {
        if ($in_list) { $html .= "</ul>\n"; $in_list = false; }
        if ($in_ol)   { $html .= "</ol>\n"; $in_ol = false; }
    };

    foreach ($lines as $line) {
        // Fenced code blocks
        if (preg_match('/^```(\w*)/', $line, $m)) {
            $flush_paragraph();
            $close_list();
            if (!$in_code) {
                $lang = $m[1] ? ' class="language-' . e($m[1]) . '"' : '';
                $html .= "<pre><code{$lang}>";
                $in_code = true;
            } else {
                $html .= "</code></pre>\n";
                $in_code = false;
            }
            continue;
        }
        if ($in_code) {
            $html .= e($line) . "\n";
            continue;
        }

        // Blank line
        if (trim($line) === '') {
            $flush_paragraph();
            $close_list();
            if ($in_blockquote) { $html .= "</blockquote>\n"; $in_blockquote = false; }
            continue;
        }

        // Headings
        if (preg_match('/^(#{1,6})\s+(.+)/', $line, $m)) {
            $flush_paragraph(); $close_list();
            $level = strlen($m[1]);
            $id = slugify($m[2]);
            $html .= "<h{$level} id=\"{$id}\">" . inline_markdown($m[2]) . "</h{$level}>\n";
            continue;
        }

        // Horizontal rule
        if (preg_match('/^(-{3,}|\*{3,}|_{3,})$/', trim($line))) {
            $flush_paragraph(); $close_list();
            $html .= "<hr>\n";
            continue;
        }

        // Blockquote
        if (preg_match('/^>\s?(.*)/', $line, $m)) {
            $flush_paragraph(); $close_list();
            if (!$in_blockquote) { $html .= "<blockquote>\n"; $in_blockquote = true; }
            $html .= '<p>' . inline_markdown($m[1]) . "</p>\n";
            continue;
        }

        // Unordered list
        if (preg_match('/^[\-\*]\s+(.+)/', $line, $m)) {
            $flush_paragraph();
            if ($in_ol) { $html .= "</ol>\n"; $in_ol = false; }
            if (!$in_list) { $html .= "<ul>\n"; $in_list = true; }
            $html .= '<li>' . inline_markdown($m[1]) . "</li>\n";
            continue;
        }

        // Ordered list
        if (preg_match('/^\d+\.\s+(.+)/', $line, $m)) {
            $flush_paragraph();
            if ($in_list) { $html .= "</ul>\n"; $in_list = false; }
            if (!$in_ol) { $html .= "<ol>\n"; $in_ol = true; }
            $html .= '<li>' . inline_markdown($m[1]) . "</li>\n";
            continue;
        }

        // Paragraph text
        $paragraph .= $line . "\n";
    }

    $flush_paragraph();
    $close_list();
    if ($in_code) $html .= "</code></pre>\n";
    if ($in_blockquote) $html .= "</blockquote>\n";

    return $html;
}

/**
 * Process inline markdown: bold, italic, code, links, images.
 */
function inline_markdown(string $text): string {
    // Images: ![alt](src)
    $text = preg_replace('/!\[([^\]]*)\]\(([^)]+)\)/', '<img src="$2" alt="$1" loading="lazy">', $text);
    // Links: [text](url)
    $text = preg_replace('/\[([^\]]+)\]\(([^)]+)\)/', '<a href="$2">$1</a>', $text);
    // Bold+italic
    $text = preg_replace('/\*\*\*(.+?)\*\*\*/', '<strong><em>$1</em></strong>', $text);
    // Bold
    $text = preg_replace('/\*\*(.+?)\*\*/', '<strong>$1</strong>', $text);
    // Italic
    $text = preg_replace('/\*(.+?)\*/', '<em>$1</em>', $text);
    // Inline code
    $text = preg_replace('/`([^`]+)`/', '<code>$1</code>', $text);
    return $text;
}

/**
 * HTML-escape shorthand.
 */
function e(string $s): string {
    return htmlspecialchars($s, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}

/**
 * Generate a URL-friendly slug from text.
 */
function slugify(string $text): string {
    $text = strtolower(strip_tags($text));
    $text = preg_replace('/[^a-z0-9\s-]/', '', $text);
    return preg_replace('/[\s-]+/', '-', trim($text));
}

/**
 * Load and render a markdown content file. Returns HTML or null.
 */
function load_content(string $slug): ?string {
    global $CONTENT_MAP;
    $file = $CONTENT_MAP[$slug] ?? null;
    if (!$file) return null;
    $path = CONTENT_DIR . $file;
    if (!file_exists($path)) return null;
    return markdown_to_html(file_get_contents($path));
}

/**
 * Check if current page matches slug (for nav highlighting).
 */
function is_active(string $slug, string $current): string {
    return ($slug === $current) ? ' class="active"' : '';
}

/**
 * Get the URL for a page slug.
 */
function page_url(string $slug): string {
    if ($slug === 'home') return SITE_BASE_URL;
    return SITE_BASE_URL . $slug;
}
