#!/usr/bin/env nu

let DATABASE_URL = $env.DATABASE_URL

# Fetch all messages, optionally filtered by channel
def messages [channel_id?: int] {
    let query = if ($channel_id | is-empty) {
        "COPY (SELECT m.id, m.channel_id, m.user_id, u.username, m.content, m.created_at, m.updated_at, m.is_edited FROM messages m JOIN users u ON m.user_id = u.id ORDER BY m.created_at DESC) TO STDOUT CSV HEADER;"
    } else {
        $"COPY \(SELECT m.id, m.channel_id, m.user_id, u.username, m.content, m.created_at, m.updated_at, m.is_edited FROM messages m JOIN users u ON m.user_id = u.id WHERE m.channel_id = ($channel_id) ORDER BY m.created_at DESC\) TO STDOUT CSV HEADER;"
    }

    psql $DATABASE_URL -c $query | from csv
}

# Fetch all users
def users [] {
    psql $DATABASE_URL -c "COPY (SELECT id, username, display_name, email, twofa_enabled, created_at, updated_at FROM users ORDER BY created_at DESC) TO STDOUT CSV HEADER;"
    | from csv | print
}

# Fetch specific user by ID or username
def user [identifier: string] {
    let query = if ($identifier | into int | is-not-empty) {
        $"COPY \(SELECT id, username, display_name, email, twofa_enabled, created_at, updated_at FROM users WHERE id = ($identifier)\) TO STDOUT CSV HEADER;"
    } else {
        $"COPY \(SELECT id, username, display_name, email, twofa_enabled, created_at, updated_at FROM users WHERE username = '($identifier)'\) TO STDOUT CSV HEADER;"
    }

    psql $DATABASE_URL -c $query | from csv
}

# Fetch all channels
def channels [] {
    psql $DATABASE_URL -c "COPY (SELECT c.id, c.name, c.created_at, c.updated_at, COUNT(m.id) as message_count FROM channels c LEFT JOIN messages m ON c.id = m.channel_id GROUP BY c.id ORDER BY c.created_at DESC) TO STDOUT CSV HEADER;"
    | from csv | print
}

# Fetch specific channel by ID
def channel [channel_id: int] {
    psql $DATABASE_URL -c $"COPY \(SELECT c.id, c.name, c.created_at, c.updated_at, COUNT\(m.id\) as message_count FROM channels c LEFT JOIN messages m ON c.id = m.channel_id WHERE c.id = ($channel_id) GROUP BY c.id\) TO STDOUT CSV HEADER;"
    | from csv
}

# Fetch all sessions
def sessions [] {
    psql $DATABASE_URL -c "COPY (SELECT s.id, s.user_id, u.username, s.token, s.created_at, s.expires_at FROM sessions s JOIN users u ON s.user_id = u.id ORDER BY s.created_at DESC) TO STDOUT CSV HEADER;"
    | from csv | print
}

# Fetch active sessions only
def active-sessions [] {
    psql $DATABASE_URL -c "COPY (SELECT s.id, s.user_id, u.username, s.token, s.created_at, s.expires_at FROM sessions s JOIN users u ON s.user_id = u.id WHERE s.expires_at > NOW() ORDER BY s.created_at DESC) TO STDOUT CSV HEADER;"
    | from csv | print
}

# Fetch all access codes
def access-codes [] {
    psql $DATABASE_URL -c "COPY (SELECT ac.id, ac.creator_id, u.username as creator, ac.code, ac.name, ac.uses, ac.max_uses, ac.created_at, ac.expires_at FROM access_codes ac JOIN users u ON ac.creator_id = u.id ORDER BY ac.created_at DESC) TO STDOUT CSV HEADER;"
    | from csv | print
}

# Fetch valid (non-expired, not fully used) access codes
def valid-access-codes [] {
    psql $DATABASE_URL -c "COPY (SELECT ac.id, ac.creator_id, u.username as creator, ac.code, ac.name, ac.uses, ac.max_uses, ac.created_at, ac.expires_at FROM access_codes ac JOIN users u ON ac.creator_id = u.id WHERE ac.expires_at > NOW() AND ac.uses < ac.max_uses ORDER BY ac.created_at DESC) TO STDOUT CSV HEADER;"
    | from csv | print
}

# Fetch message attachments
def attachments [message_id?: int] {
    let query = if ($message_id | is-empty) {
        "COPY (SELECT a.id, a.message_id, a.path, m.content as message_content, u.username FROM attachments a JOIN messages m ON a.message_id = m.id JOIN users u ON m.user_id = u.id ORDER BY a.id DESC) TO STDOUT CSV HEADER;"
    } else {
        $"COPY \(SELECT a.id, a.message_id, a.path, m.content as message_content FROM attachments a JOIN messages m ON a.message_id = m.id WHERE a.message_id = ($message_id)\) TO STDOUT CSV HEADER;"
    }

    psql $DATABASE_URL -c $query | from csv
}

# Get database statistics
def stats [] {
    let user_count = (psql $DATABASE_URL -t -c "SELECT COUNT(*) FROM users;" | str trim | into int)
    let channel_count = (psql $DATABASE_URL -t -c "SELECT COUNT(*) FROM channels;" | str trim | into int)
    let message_count = (psql $DATABASE_URL -t -c "SELECT COUNT(*) FROM messages;" | str trim | into int)
    let session_count = (psql $DATABASE_URL -t -c "SELECT COUNT(*) FROM sessions WHERE expires_at > NOW();" | str trim | into int)
    let access_code_count = (psql $DATABASE_URL -t -c "SELECT COUNT(*) FROM access_codes WHERE expires_at > NOW() AND uses < max_uses;" | str trim | into int)

    {
        users: $user_count,
        channels: $channel_count,
        messages: $message_count,
        active_sessions: $session_count,
        valid_access_codes: $access_code_count
    } | print
}

def redis-cache [...args: string] {
    # print $"redis-cli --csv (...($args | str trim))"

    redis-cli ...($args | str trim) | lines | each { |line| $line | from json } | print
}

# Display help menu
def help-menu [] {
    print "Available commands:"
    print "  messages [channel_id]     - Fetch all messages or messages from a specific channel"
    print "  users                     - Fetch all users"
    print "  user <id|username>        - Fetch specific user by ID or username"
    print "  channels                  - Fetch all channels"
    print "  channel <id>              - Fetch specific channel by ID"
    print "  sessions                  - Fetch all sessions"
    print "  active-sessions           - Fetch only active (non-expired) sessions"
    print "  access-codes              - Fetch all access codes"
    print "  valid-access-codes        - Fetch valid (non-expired, available) access codes"
    print "  attachments [message_id]  - Fetch all attachments or attachments for a message"
    print "  stats                     - Show database statistics"
    print "  help                      - Show this help menu"
    print "  exit                      - Exit the interface"
}

# Main interactive loop
def main [] {
    print "\n=== Database Query Interface ==="
    help-menu

    loop {
        print ""
        let input = (input "Enter command > ")
        let parts = ($input | split row ' ')
        let cmd = ($parts | first)

        match $cmd {
            "messages" => {
                if ($parts | length) > 1 {
                    let channel_id = ($parts | get 1 | into int)
                    messages $channel_id | print
                } else {
                    messages | print
                }
            },
            "users" => users,
            "user" => {
                if ($parts | length) > 1 {
                    user ($parts | get 1) | print
                } else {
                    print "Usage: user <id|username>"
                }
            },
            "channels" => channels,
            "channel" => {
                if ($parts | length) > 1 {
                    let channel_id = ($parts | get 1 | into int)
                    channel $channel_id | print
                } else {
                    print "Usage: channel <id>"
                }
            },
            "sessions" => sessions,
            "redis" => {
                redis-cache ...($parts | skip 1)
            }
            "active-sessions" => active-sessions,
            "access-codes" => access-codes,
            "valid-access-codes" => valid-access-codes,
            "attachments" => {
                if ($parts | length) > 1 {
                    let message_id = ($parts | get 1 | into int)
                    attachments $message_id | print
                } else {
                    attachments | print
                }
            },
            "stats" => stats,
            "help" => help-menu,
            "exit" => break,
            "clear" => clear,
            _ => $"Unknown command: \($cmd). Type 'help' for available commands."
        }
    }

    print "\nGoodbye!"
}
