#!/bin/bash
# Mark emails as unread by message ID (optimized with position hints)
# Usage: mail-mark-unread.sh <message-id> [message-id...]

if [[ $# -eq 0 ]]; then
    echo "Usage: mail-mark-unread.sh <message-id> [message-id...]" >&2
    exit 1
fi

# Find the Mail database
find_db() {
    local db
    for v in 11 10 9; do
        db="$HOME/Library/Mail/V$v/MailData/Envelope Index"
        if [[ -f "$db" ]]; then
            echo "$db"
            return 0
        fi
    done
    return 1
}

DB_PATH=$(find_db)

if [[ -z "$DB_PATH" ]]; then
    echo "Error: Mail database not found" >&2
    exit 1
fi

MARKED=0
FAILED=0

for MSG_ID in "$@"; do
    # Get account UUID, mailbox path, and approximate position
    MSG_INFO=$(sqlite3 "$DB_PATH" "
    SELECT 
        substr(mb.url, 8, instr(substr(mb.url, 8), '/') - 1) as account_uuid,
        replace(replace(substr(mb.url, 8 + instr(substr(mb.url, 8), '/')), '%5B', '['), '%5D', ']') as mailbox_path,
        (SELECT COUNT(*) FROM messages m2 WHERE m2.mailbox = m.mailbox AND m2.date_received >= m.date_received) as approx_pos
    FROM messages m
    JOIN mailboxes mb ON m.mailbox = mb.ROWID
    WHERE m.ROWID = $MSG_ID;" 2>/dev/null)
    
    if [[ -z "$MSG_INFO" ]]; then
        echo "Message $MSG_ID not found in database" >&2
        FAILED=$((FAILED + 1))
        continue
    fi
    
    IFS='|' read -r ACCOUNT_UUID MAILBOX_PATH APPROX_POS <<< "$MSG_INFO"
    MAILBOX_PATH=$(python3 -c "import urllib.parse; print(urllib.parse.unquote('$MAILBOX_PATH'))")
    
    START_POS=$((APPROX_POS > 5 ? APPROX_POS - 5 : 1))
    END_POS=$((APPROX_POS + 20))
    
    RESULT=$(osascript << EOF
tell application "Mail"
    try
        set targetId to $MSG_ID
        set targetAccount to first account whose id is "$ACCOUNT_UUID"
        set mbx to mailbox "$MAILBOX_PATH" of targetAccount
        set msgCount to count of messages of mbx
        
        if $END_POS > msgCount then
            set endPos to msgCount
        else
            set endPos to $END_POS
        end if
        
        -- Search in expected range first
        repeat with i from $START_POS to endPos
            try
                set msg to message i of mbx
                if id of msg = targetId then
                    set read status of msg to false
                    return "OK"
                end if
            end try
        end repeat
        
        -- Expand search if not found
        repeat with i from 1 to msgCount
            try
                set msg to message i of mbx
                if id of msg = targetId then
                    set read status of msg to false
                    return "OK"
                end if
            end try
        end repeat
        
        return "ERROR: Message not found"
    on error errMsg
        return "ERROR: " & errMsg
    end try
end tell
EOF
)
    
    if [[ "$RESULT" == "OK" ]]; then
        echo "Marked message $MSG_ID as unread"
        MARKED=$((MARKED + 1))
    else
        echo "Failed to mark message $MSG_ID: $RESULT" >&2
        FAILED=$((FAILED + 1))
    fi
done

echo ""
echo "Summary: $MARKED marked, $FAILED failed"
