#!/bin/bash
# Convert email to HTML and open in browser with images

emlfile="/tmp/neomutt-email-$$.eml"
tmpdir="/tmp/neomutt-email-$$"
tmpfile="$tmpdir/email.html"

# Save email from stdin
mkdir -p "$tmpdir"
cat >"$emlfile"

# Extract MIME parts using ripmime if available
if command -v ripmime &>/dev/null; then
    ripmime -i "$emlfile" -d "$tmpdir" --no-nameless 2>/dev/null
elif command -v munpack &>/dev/null; then
    cd "$tmpdir" && munpack -q "$emlfile" 2>/dev/null
fi

# Check if there's an HTML part extracted
html_part=$(find "$tmpdir" -maxdepth 1 -name "*.html" -o -name "*.htm" 2>/dev/null | head -1)

if [[ -n $html_part && -s $html_part ]]; then
    # Use extracted HTML directly
    cp "$html_part" "$tmpfile"
else
    # Generate HTML from text
    {
        echo "<html><head>"
        echo '<meta charset="utf-8">'
        echo "<script>if(window.matchMedia('(prefers-color-scheme:dark)').matches)document.documentElement.classList.add('dark');</script>"
        echo "<style>"
        echo ":root { --bg: #ffffff; --text: #000000; --header-bg: #f5f5f5; --link: #0066cc; }"
        echo ".dark { --bg: #1a1a1a; --text: #e0e0e0; --header-bg: #2d2d2d; --link: #6db3f2; }"
        echo "body { font-family: -apple-system, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; background: var(--bg); color: var(--text); transition: background 0.2s, color 0.2s; }"
        echo "pre { white-space: pre-wrap; word-wrap: break-word; }"
        echo ".headers { background: var(--header-bg); padding: 15px; margin-bottom: 20px; border-radius: 5px; transition: background 0.2s; }"
        echo ".headers p { margin: 5px 0; }"
        echo ".headers ul { margin: 5px 0 10px 20px; padding: 0; }"
        echo ".headers li { margin: 2px 0; }"
        echo ".body { line-height: 1.6; white-space: pre-wrap; word-wrap: break-word; }"
        echo "code { background: var(--header-bg); padding: 2px 5px; border-radius: 3px; font-family: monospace; }"
        echo ".codeblock { background: var(--header-bg); padding: 15px; border-radius: 5px; overflow-x: auto; }"
        echo ".codeblock code { background: none; padding: 0; }"
        echo "img { max-width: 100%; height: auto; }"
        echo "a { color: var(--link); }"
        echo ".toggle { position: fixed; top: 10px; right: 10px; width: 40px; height: 40px; border: none; border-radius: 50%; cursor: pointer; background: var(--header-bg); color: var(--text); font-size: 20px; transition: background 0.2s; }"
        echo ".toggle:hover { opacity: 0.8; }"
        echo ".sun { display: none; } .dark .sun { display: inline; } .dark .moon { display: none; }"
        echo "</style></head><body>"
        echo '<button class="toggle" onclick="toggleTheme()" title="Toggle theme"><span class="moon">&#9790;</span><span class="sun">&#9728;</span></button>'
        echo "<script>"
        echo "function toggleTheme() { document.documentElement.classList.toggle('dark'); }"
        echo "</script>"

        # Extract and display headers (handles multi-line headers)
        echo '<div class="headers">'
        awk 'BEGIN{IGNORECASE=1; show=0; header=""; value=""}
            function decode_qp(str,    result, i, hex, char) {
                result = str
                # Decode =XX hex sequences
                while (match(result, /=[0-9A-Fa-f][0-9A-Fa-f]/)) {
                    hex = substr(result, RSTART+1, 2)
                    cmd = "printf \"\\x" hex "\""
                    cmd | getline char
                    close(cmd)
                    result = substr(result, 1, RSTART-1) char substr(result, RSTART+3)
                }
                gsub(/_/, " ", result)
                return result
            }
            function decode_mime(str,    result, before, after, encoded, charset, encoding, text) {
                result = str
                # Decode =?charset?Q?text?= or =?charset?B?text?=
                while (match(result, /=\?[^?]+\?[QqBb]\?[^?]+\?=/)) {
                    before = substr(result, 1, RSTART-1)
                    encoded = substr(result, RSTART, RLENGTH)
                    after = substr(result, RSTART+RLENGTH)
                    # Remove =?...?Q? and ?=
                    gsub(/=\?[^?]+\?[Qq]\?/, "", encoded)
                    gsub(/\?=$/, "", encoded)
                    text = decode_qp(encoded)
                    result = before text after
                }
                return result
            }
            function split_addresses(str, arr,    n, i, c, inquote, current) {
                n = 0; inquote = 0; current = ""
                for (i = 1; i <= length(str); i++) {
                    c = substr(str, i, 1)
                    if (c == "\"") inquote = !inquote
                    if (c == "," && !inquote) {
                        gsub(/^[ \t]+|[ \t]+$/, "", current)
                        if (current != "") arr[++n] = current
                        current = ""
                    } else {
                        current = current c
                    }
                }
                gsub(/^[ \t]+|[ \t]+$/, "", current)
                if (current != "") arr[++n] = current
                return n
            }
            function output() {
                if (header != "" && value != "") {
                    value = decode_mime(value)
                    gsub(/</, "\\&lt;", value)
                    gsub(/>/, "\\&gt;", value)
                    # Only split To, CC, Bcc addresses (not Date, Subject, From)
                    if (tolower(header) ~ /^(to|cc|bcc)$/) {
                        n = split_addresses(value, addrs)
                        if (n > 1) {
                            print "<p><strong>" header ":</strong></p><ul>"
                            for (i=1; i<=n; i++) print "<li>" addrs[i] "</li>"
                            print "</ul>"
                        } else {
                            print "<p><strong>" header ":</strong> " value "</p>"
                        }
                    } else {
                        print "<p><strong>" header ":</strong> " value "</p>"
                    }
                }
                header = ""; value = ""
            }
            /^$/{output(); exit}
            /^(From|To|CC|Bcc|Reply-To|Subject|Date):/{
                output()
                show=1
                match($0, /^[^:]+/)
                header = substr($0, 1, RLENGTH)
                value = substr($0, RLENGTH+2)
                gsub(/^[ \t]+|[ \t]+$/, "", value)
                next
            }
            /^[A-Za-z0-9-]+:/ && !/^(From|To|CC|Bcc|Reply-To|Subject|Date):/{output(); show=0}
            show && /^[ \t]/{
                gsub(/^[ \t]+/, "", $0)
                value = value " " $0
            }
            END{output()}' "$emlfile"
        echo "</div>"

        # Display body - extract text part and format code blocks
        echo '<div class="body">'
        # Try to find extracted text file first
        text_part=$(find "$tmpdir" -maxdepth 1 -name "textfile*" -o -name "*.txt" 2>/dev/null | head -1)
        if [[ -n $text_part && -s $text_part ]]; then
            body_content=$(cat "$text_part")
        elif command -v mshow &>/dev/null; then
            body_content=$(mshow -N "$emlfile" 2>&1 | grep -v "no filter or default handler" | grep -viE "^(From|To|Cc|Bcc|Reply-To|Subject|Date):")
        else
            body_content=$(sed '1,/^$/d' "$emlfile")
        fi
        # Process body: escape HTML, handle code blocks and inline code
        echo "$body_content" | awk '
            BEGIN { incode=0 }
            /^```/ {
                if (incode) { print "</code></pre>"; incode=0 }
                else { print "<pre class=\"codeblock\"><code>"; incode=1 }
                next
            }
            {
                gsub(/</, "\\&lt;")
                gsub(/>/, "\\&gt;")
                if (!incode) {
                    # Handle inline code `code`
                    while (match($0, /`[^`]+`/)) {
                        before = substr($0, 1, RSTART-1)
                        code = substr($0, RSTART+1, RLENGTH-2)
                        after = substr($0, RSTART+RLENGTH)
                        $0 = before "<code>" code "</code>" after
                    }
                }
                print
            }
            END { if (incode) print "</code></pre>" }
        '
        echo "</div>"

        # Show extracted images
        find "$tmpdir" -maxdepth 1 -type f \( -iname "*.png" -o -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.gif" \) 2>/dev/null | while read -r img; do
            echo "<p><img src=\"$(basename "$img")\"></p>"
        done

        echo "</body></html>"
    } >"$tmpfile"
fi

open "$tmpfile"
rm -f "$emlfile"
# Clean up after 60 seconds in background
(sleep 60 && rm -rf "$tmpdir") &
