#!/usr/bin/env bash
set -euo pipefail

DB_DIR="$HOME/.local/share/quoter"
DB="$DB_DIR/quoter.db"

BOLD=$(tput bold 2>/dev/null || echo "")
CYAN=$(tput setaf 6 2>/dev/null || echo "")
YELLOW=$(tput setaf 3 2>/dev/null || echo "")
GREEN=$(tput setaf 2 2>/dev/null || echo "")
DIM=$(tput dim 2>/dev/null || echo "")
RESET=$(tput sgr0 2>/dev/null || echo "")

HAS_FZF=false
HAS_GUM=false
command -v fzf &>/dev/null && HAS_FZF=true
command -v gum &>/dev/null && HAS_GUM=true

find_quotes_sql() {
    if [[ -f "$DB_DIR/quotes.sql" ]]; then
        echo "$DB_DIR/quotes.sql"
    elif [[ -f "$(dirname "$(realpath "$0" 2>/dev/null || echo "$0")")/quotes.sql" ]]; then
        echo "$(dirname "$(realpath "$0" 2>/dev/null || echo "$0")")/quotes.sql"
    elif [[ -z "${QUOTER_SEED:-}" ]] && [[ -f "$QUOTER_SEED" ]]; then
        echo "$QUOTER_SEED"
    else
        echo ""
    fi
}

db_init() {
    mkdir -p "$DB_DIR"
    sqlite3 "$DB" "CREATE TABLE IF NOT EXISTS quotes (
        id        INTEGER PRIMARY KEY AUTOINCREMENT,
        quote     TEXT NOT NULL,
        source    TEXT NOT NULL,
        character TEXT NOT NULL,
        season    TEXT,
        type      TEXT DEFAULT 'tv',
        added_at  DATETIME DEFAULT CURRENT_TIMESTAMP
    );"

    local has_type
    has_type=$(sqlite3 "$DB" "PRAGMA table_info(quotes);" 2>/dev/null | grep -c '^.*|type|.*$' || echo "0")
    if [[ "$has_type" -eq 0 ]]; then
        sqlite3 "$DB" "ALTER TABLE quotes ADD COLUMN type TEXT DEFAULT 'tv';"
        sqlite3 "$DB" "UPDATE quotes SET type = 'movie' WHERE source IN ('The Dark Knight');"
        sqlite3 "$DB" "UPDATE quotes SET type = 'tv' WHERE source IN ('Breaking Bad', 'The Boys');"
    fi
}

db_seed() {
    local count
    count=$(sqlite3 "$DB" "SELECT COUNT(*) FROM quotes;")
    if [[ "$count" -eq 0 ]]; then
        local seed_file
        seed_file=$(find_quotes_sql)
        if [[ -n "$seed_file" ]]; then
            sqlite3 "$DB" < "$seed_file"
        fi
    fi
}

import_quotes() {
    local file="$ARG_IMPORT"
    if [[ ! -f "$file" ]]; then
        echo "Error: file not found: $file" >&2
        exit 1
    fi
    sqlite3 "$DB" < "$file"
    echo "Quotes imported from $file"
}

format_type() {
    local t="$1"
    case "$t" in
        movie) echo "Movie" ;;
        tv) echo "TV Show" ;;
        game) echo "Game" ;;
        *) echo "${t^}" ;;
    esac
}

show_random() {
    local result
    result=$(sqlite3 "$DB" "SELECT id, quote, source, character, COALESCE(season, ''), COALESCE(type, 'tv') FROM quotes ORDER BY RANDOM() LIMIT 1;" 2>/dev/null)
    if [[ -z "$result" ]]; then
        echo "No quotes yet. Add one with ${BOLD}quoter --add${RESET}"
        return
    fi
    IFS='|' read -r id quote source character season qtype <<< "$result"

    if [[ "$ARG_SIMPLE" == "true" ]]; then
        echo "\"${quote}\" — ${character}, ${source}"
        return
    fi

    local season_part=""
    if [[ -n "$season" ]]; then
        season_part=" ${DIM}(${season})${RESET}"
    fi
    local type_label
    type_label=$(format_type "$qtype")

    if $HAS_GUM; then
        local season_display=""
        [[ -n "$season" ]] && season_display=" ($season)"
        echo ""
        printf '"%s"\n  — %s, %s [%s]%s\n' "$quote" "$character" "$source" "$type_label" "$season_display" | gum style --border rounded --margin "1 2" --padding "1 3"
        echo ""
    else
        echo ""
        echo "  ${BOLD}\"${quote}\"${RESET}"
        echo "    — ${CYAN}${character}${RESET}, ${YELLOW}${source}${RESET} ${DIM}[${type_label}]${RESET}${season_part}"
        echo ""
    fi
}

add_interactive() {
    stty echo 2>/dev/null || true
    local quote source character season qtype

    if $HAS_GUM; then
        quote=$(gum input --placeholder "Enter the quote")
        [[ -z "$quote" ]] && { gum style --foreground 1 "Error: quote is required."; exit 1; }

        source=$(gum input --placeholder "Source (movie, TV show, or game title)")
        [[ -z "$source" ]] && { gum style --foreground 1 "Error: source is required."; exit 1; }

        character=$(gum input --placeholder "Character who said it")
        [[ -z "$character" ]] && { gum style --foreground 1 "Error: character is required."; exit 1; }

        qtype=$(gum choose "tv" "movie" "game" --header="Select type")

        if [[ "$qtype" == "tv" ]]; then
            season=$(gum input --placeholder "Season/Episode (e.g. S01E01) or leave empty")
        else
            season=""
        fi

        local type_label
        type_label=$(format_type "$qtype")
        local season_display=""
        [[ -n "$season" ]] && season_display=" ($season)"
        echo ""
        printf '"%s"\n  — %s, %s [%s]%s\n' "$quote" "$character" "$source" "$type_label" "$season_display" | gum style --border rounded --margin "1 2" --padding "0 2"
        echo ""

        if gum confirm "Save this quote?"; then
            if [[ -n "$season" ]]; then
                sqlite3 "$DB" "INSERT INTO quotes (quote, source, character, season, type) VALUES ('$(sqlite3_escape "$quote")', '$(sqlite3_escape "$source")', '$(sqlite3_escape "$character")', '$(sqlite3_escape "$season")', '$(sqlite3_escape "$qtype")');"
            else
                sqlite3 "$DB" "INSERT INTO quotes (quote, source, character, type) VALUES ('$(sqlite3_escape "$quote")', '$(sqlite3_escape "$source")', '$(sqlite3_escape "$character")', '$(sqlite3_escape "$qtype")');"
            fi
            gum style --foreground 2 "Quote added!"
        else
            gum style --foreground 3 "Cancelled."
        fi
    else
        echo "Add a new quote:"
        echo ""
        read -rp "  Quote: " quote
        read -rp "  Source (movie/TV show/game): " source
        read -rp "  Character: " character
        read -rp "  Season/Episode (optional, e.g. S01E01): " season

        echo "  Type:"
        echo "    1) tv"
        echo "    2) movie"
        echo "    3) game"
        read -rp "  Choose [1-3]: " type_choice
        case "$type_choice" in
            2) qtype="movie" ;;
            3) qtype="game" ;;
            *) qtype="tv" ;;
        esac

        if [[ -z "$quote" || -z "$source" || -z "$character" ]]; then
            echo "Error: quote, source, and character are required." >&2
            exit 1
        fi

        if [[ -n "$season" ]]; then
            sqlite3 "$DB" "INSERT INTO quotes (quote, source, character, season, type) VALUES ('$(sqlite3_escape "$quote")', '$(sqlite3_escape "$source")', '$(sqlite3_escape "$character")', '$(sqlite3_escape "$season")', '$(sqlite3_escape "$qtype")');"
        else
            sqlite3 "$DB" "INSERT INTO quotes (quote, source, character, type) VALUES ('$(sqlite3_escape "$quote")', '$(sqlite3_escape "$source")', '$(sqlite3_escape "$character")', '$(sqlite3_escape "$qtype")');"
        fi
        echo "Quote added!"
    fi
}

add_noninteractive() {
    if [[ -z "$ARG_QUOTE" || -z "$ARG_SOURCE" || -z "$ARG_CHARACTER" ]]; then
        echo "Error: --quote, --source, and --character are required when using --add non-interactively." >&2
        echo "Run ${BOLD}quoter --help${RESET} for usage." >&2
        exit 1
    fi

    local qtype="${ARG_TYPE:-tv}"

    if [[ -n "$ARG_SEASON" ]]; then
        sqlite3 "$DB" "INSERT INTO quotes (quote, source, character, season, type) VALUES ('$(sqlite3_escape "$ARG_QUOTE")', '$(sqlite3_escape "$ARG_SOURCE")', '$(sqlite3_escape "$ARG_CHARACTER")', '$(sqlite3_escape "$ARG_SEASON")', '$(sqlite3_escape "$qtype")');"
    else
        sqlite3 "$DB" "INSERT INTO quotes (quote, source, character, type) VALUES ('$(sqlite3_escape "$ARG_QUOTE")', '$(sqlite3_escape "$ARG_SOURCE")', '$(sqlite3_escape "$ARG_CHARACTER")', '$(sqlite3_escape "$qtype")');"
    fi
    echo "Quote added!"
}

sqlite3_escape() {
    local str="$1"
    str="${str//\'/\'\'}"
    printf '%s' "$str"
}

list_quotes() {
    local count
    count=$(sqlite3 "$DB" "SELECT COUNT(*) FROM quotes;")
    if [[ "$count" -eq 0 ]]; then
        echo "No quotes yet. Add one with ${BOLD}quoter --add${RESET}"
        return
    fi

    local where=""
    local conditions=()

    if [[ -n "$ARG_SOURCE" ]]; then
        conditions+=("source LIKE '%$(sqlite3_escape "$ARG_SOURCE")%' COLLATE NOCASE")
    fi
    if [[ -n "$ARG_TYPE" ]]; then
        conditions+=("type = '$(sqlite3_escape "$ARG_TYPE")'")
    fi
    if [[ -n "$ARG_CHARACTER" ]]; then
        conditions+=("character LIKE '%$(sqlite3_escape "$ARG_CHARACTER")%' COLLATE NOCASE")
    fi

    if [[ ${#conditions[@]} -gt 0 ]]; then
        where="WHERE $(IFS=' AND '; echo "${conditions[*]}")"
    fi

    if [[ "$ARG_SIMPLE" == "true" ]]; then
        sqlite3 "$DB" "SELECT quote, character, source FROM quotes $where ORDER BY id;" | while IFS='|' read -r quote character source; do
            echo "\"${quote}\" — ${character}, ${source}"
        done
        return
    fi

    printf "${BOLD}%-4s %-42s %-12s %-20s %-6s %-8s${RESET}\n" "ID" "Quote" "Type" "Source" "Season" "Char"
    printf '%-4s %-42s %-12s %-20s %-6s %-8s\n' "----" "------------------------------------------" "------------" "--------------------" "------" "--------"

    sqlite3 "$DB" "SELECT id, quote, type, source, COALESCE(season, '-'), character FROM quotes $where ORDER BY id;" | while IFS='|' read -r id quote qtype source season character; do
        if [[ ${#quote} -gt 40 ]]; then
            quote="${quote:0:37}..."
        fi
        if [[ ${#source} -gt 20 ]]; then
            source="${source:0:17}..."
        fi
        if [[ ${#character} -gt 8 ]]; then
            character="${character:0:5}..."
        fi
        local type_label
        type_label=$(format_type "$qtype")
        printf "%-4s %-42s %-12s %-20s %-6s %-8s\n" "$id" "$quote" "$type_label" "$source" "$season" "$character"
    done
}

browse_quotes() {
    if ! $HAS_FZF; then
        echo "Error: --browse requires fzf. Install it from https://github.com/junegunn/fzf" >&2
        exit 1
    fi

    local count
    count=$(sqlite3 "$DB" "SELECT COUNT(*) FROM quotes;")
    if [[ "$count" -eq 0 ]]; then
        echo "No quotes yet. Add one with ${BOLD}quoter --add${RESET}"
        return
    fi

    local selected
    selected=$(sqlite3 "$DB" "SELECT id, quote, character, source, COALESCE(season, ''), COALESCE(type, 'tv') FROM quotes ORDER BY id;" | \
        while IFS='|' read -r id quote character source season qtype; do
            local type_label
            type_label=$(format_type "$qtype")
            local season_info=""
            [[ -n "$season" ]] && season_info=" ($season)"
            printf "%-4s  %-50s  — %s, %s [%s]%s\n" "$id" "$quote" "$character" "$source" "$type_label" "$season_info"
        done | fzf \
            --height=~80% \
            --layout=reverse \
            --border=rounded \
            --header="Browse quotes (Enter to view, Esc to cancel)" \
            --no-multi \
            --ansi \
            --cycle \
            --query="${ARG_SEARCH:-}" 2>/dev/null)

    if [[ -n "$selected" ]]; then
        local sel_id
        sel_id=$(echo "$selected" | awk '{print $1}')
        show_quote_by_id "$sel_id"
    fi
}

show_quote_by_id() {
    local id="$1"
    local result
    result=$(sqlite3 "$DB" "SELECT quote, source, character, COALESCE(season, ''), COALESCE(type, 'tv') FROM quotes WHERE id = $id;" 2>/dev/null)
    if [[ -z "$result" ]]; then
        echo "Quote not found." >&2
        return
    fi
    IFS='|' read -r quote source character season qtype <<< "$result"
    local season_part=""
    if [[ -n "$season" ]]; then
        season_part=" ($season)"
    fi
    local type_label
    type_label=$(format_type "$qtype")

    if $HAS_GUM; then
        echo ""
        printf '"%s"\n  — %s, %s [%s]%s\n' "$quote" "$character" "$source" "$type_label" "$season_part" | gum style --border rounded --margin "1 2" --padding "1 3"
        echo ""
    else
        echo ""
        echo "  ${BOLD}\"${quote}\"${RESET}"
        echo "    — ${CYAN}${character}${RESET}, ${YELLOW}${source}${RESET} ${DIM}[${type_label}]${RESET}${DIM}${season_part}${RESET}"
        echo ""
    fi
}

search_quotes() {
    if [[ -z "$ARG_SEARCH" ]]; then
        echo "Error: --search requires a search term." >&2
        exit 1
    fi

    local escaped
    escaped=$(sqlite3_escape "$ARG_SEARCH")
    local where="WHERE (quote LIKE '%${escaped}%' COLLATE NOCASE OR character LIKE '%${escaped}%' COLLATE NOCASE OR source LIKE '%${escaped}%' COLLATE NOCASE)"

    local count
    count=$(sqlite3 "$DB" "SELECT COUNT(*) FROM quotes $where;")
    if [[ "$count" -eq 0 ]]; then
        echo "No quotes found matching '${ARG_SEARCH}'."
        return
    fi

    if [[ "$ARG_SIMPLE" == "true" ]]; then
        sqlite3 "$DB" "SELECT quote, character, source FROM quotes $where ORDER BY id;" | while IFS='|' read -r quote character source; do
            echo "\"${quote}\" — ${character}, ${source}"
        done
        return
    fi

    printf "${BOLD}%-4s %-42s %-12s %-20s %-6s %-8s${RESET}\n" "ID" "Quote" "Type" "Source" "Season" "Char"
    printf '%-4s %-42s %-12s %-20s %-6s %-8s\n' "----" "------------------------------------------" "------------" "--------------------" "------" "--------"

    sqlite3 "$DB" "SELECT id, quote, type, source, COALESCE(season, '-'), character FROM quotes $where ORDER BY id;" | while IFS='|' read -r id quote qtype source season character; do
        if [[ ${#quote} -gt 40 ]]; then
            quote="${quote:0:37}..."
        fi
        if [[ ${#source} -gt 20 ]]; then
            source="${source:0:17}..."
        fi
        if [[ ${#character} -gt 8 ]]; then
            character="${character:0:5}..."
        fi
        local type_label
        type_label=$(format_type "$qtype")
        printf "%-4s %-42s %-12s %-20s %-6s %-8s\n" "$id" "$quote" "$type_label" "$source" "$season" "$character"
    done
}

delete_quote() {
    if [[ -n "$ARG_DELETE" ]]; then
        local result
        result=$(sqlite3 "$DB" "SELECT id, quote, source, character FROM quotes WHERE id = $ARG_DELETE;" 2>/dev/null)
        if [[ -z "$result" ]]; then
            echo "Quote with ID $ARG_DELETE not found." >&2
            exit 1
        fi

        IFS='|' read -r id quote source character <<< "$result"

        if $HAS_GUM; then
            echo ""
            printf '"%s"\n  — %s, %s\n' "$quote" "$character" "$source" | gum style --border rounded --margin "1 2" --padding "0 2"
            echo ""
            if gum confirm "Delete this quote?"; then
                sqlite3 "$DB" "DELETE FROM quotes WHERE id = $ARG_DELETE;"
                gum style --foreground 2 "Quote deleted."
            else
                gum style --foreground 3 "Cancelled."
            fi
        else
            stty echo 2>/dev/null || true
            echo "Delete this quote?"
            echo "  ${BOLD}\"${quote}\"${RESET} — ${CYAN}${character}${RESET}, ${YELLOW}${source}${RESET}"
            echo ""
            read -rp "  Are you sure? [y/N] " confirm
            if [[ "$confirm" =~ ^[Yy]$ ]]; then
                sqlite3 "$DB" "DELETE FROM quotes WHERE id = $ARG_DELETE;"
                echo "Quote deleted."
            else
                echo "Cancelled."
            fi
        fi
    else
        if ! $HAS_FZF; then
            echo "Error: --delete without ID requires fzf. Install it or use --delete <id>." >&2
            exit 1
        fi

        local selected
        selected=$(sqlite3 "$DB" "SELECT id, quote, character, source FROM quotes ORDER BY id;" | \
            while IFS='|' read -r id quote character source; do
                printf "%-4s  %-50s  — %s, %s\n" "$id" "$quote" "$character" "$source"
            done | fzf \
                --height=~80% \
                --layout=reverse \
                --border=rounded \
                --header="Select a quote to delete (Esc to cancel)" \
                --no-multi \
                --ansi \
                --cycle 2>/dev/null)

        if [[ -n "$selected" ]]; then
            local sel_id
            sel_id=$(echo "$selected" | awk '{print $1}')
            ARG_DELETE="$sel_id" delete_quote
        fi
    fi
}

tui_mode() {
    if ! $HAS_FZF; then
        echo "Error: --tui requires fzf." >&2
        echo "Install it from https://github.com/junegunn/fzf" >&2
        exit 1
    fi

    local quote_count
    quote_count=$(sqlite3 "$DB" "SELECT COUNT(*) FROM quotes;" 2>/dev/null || echo "0")

    local use_gum=false
    $HAS_GUM && use_gum=true

    local header
    header="  quoter — ${quote_count} quotes in your collection"

    tui_wait() {
        fzf \
            --height=~10% \
            --layout=reverse \
            --border=rounded \
            --header="$1" \
            --no-multi \
            --disabled \
            --prompt="" \
            < /dev/null 2>/dev/null || true
    }

    tui_input() {
        local label="$1"
        fzf \
            --height=~15% \
            --layout=reverse \
            --border=rounded \
            --header="$label" \
            --no-multi \
            --disabled \
            --prompt="> " \
            --no-info \
            < /dev/null 2>/dev/null || true
    }

    tui_confirm() {
        local label="$1"
        local result
        result=$(printf "Yes\nNo\n" | fzf \
            --height=~20% \
            --layout=reverse \
            --border=rounded \
            --header="$label" \
            --no-multi \
            --prompt="> " \
            2>/dev/null) || result="No"
        [[ "$result" == "Yes" ]]
    }

    tui_add() {
        local quote source character season qtype

        quote=$(tui_input "Enter the quote")
        [[ -z "$quote" ]] && { echo "Cancelled."; return; }

        source=$(tui_input "Source (movie, TV show, or game title)")
        [[ -z "$source" ]] && { echo "Cancelled."; return; }

        character=$(tui_input "Character who said it")
        [[ -z "$character" ]] && { echo "Cancelled."; return; }

        qtype=$(printf "tv\nmovie\ngame\n" | fzf \
            --height=~25% \
            --layout=reverse \
            --border=rounded \
            --header="Select type" \
            --no-multi \
            --prompt="> " \
            --cycle \
            2>/dev/null) || qtype="tv"

        season=""
        if [[ "$qtype" == "tv" ]]; then
            season=$(tui_input "Season/Episode (e.g. S01E01) — leave empty to skip")
        fi

        local type_label
        type_label=$(format_type "$qtype")
        local season_display=""
        [[ -n "$season" ]] && season_display=" ($season)"
        echo ""
        printf '"%s"\n  — %s, %s [%s]%s\n' "$quote" "$character" "$source" "$type_label" "$season_display"

        if tui_confirm "Save this quote?"; then
            if [[ -n "$season" ]]; then
                sqlite3 "$DB" "INSERT INTO quotes (quote, source, character, season, type) VALUES ('$(sqlite3_escape "$quote")', '$(sqlite3_escape "$source")', '$(sqlite3_escape "$character")', '$(sqlite3_escape "$season")', '$(sqlite3_escape "$qtype")');"
            else
                sqlite3 "$DB" "INSERT INTO quotes (quote, source, character, type) VALUES ('$(sqlite3_escape "$quote")', '$(sqlite3_escape "$source")', '$(sqlite3_escape "$character")', '$(sqlite3_escape "$qtype")');"
            fi
            echo "Quote added!"
        else
            echo "Cancelled."
        fi
    }

    while true; do
        local choice
        choice=$(printf "%s\n%s\n%s\n%s\n%s\n%s\n%s" \
            "Random quote" \
            "Search quotes" \
            "List all quotes" \
            "Browse quotes" \
            "Add a quote" \
            "Delete a quote" \
            "Exit" \
            | fzf \
                --height=~40% \
                --layout=reverse \
                --border=rounded \
                --header="$header" \
                --prompt="> " \
                --cycle \
                --no-multi \
                --ansi \
                --marker="" \
                --pointer=">" \
                2>/dev/null)

        [[ -z "$choice" ]] && break

        case "$choice" in
            "Random quote")
                echo ""
                show_random
                echo ""
                tui_wait "Press Enter to continue..."
                ;;
            "Search quotes")
                local selected
                selected=$(sqlite3 "$DB" "SELECT id, quote, character, source, COALESCE(season, ''), COALESCE(type, 'tv') FROM quotes ORDER BY id;" | \
                    while IFS='|' read -r id quote character source season qtype; do
                        local type_label
                        type_label=$(format_type "$qtype")
                        local season_info=""
                        [[ -n "$season" ]] && season_info=" ($season)"
                        printf "%-4s  %-50s  — %s, %s [%s]%s\n" "$id" "$quote" "$character" "$source" "$type_label" "$season_info"
                    done | fzf \
                        --height=~70% \
                        --layout=reverse \
                        --border=rounded \
                        --header="Type to filter quotes — Enter to view, Esc to cancel" \
                        --prompt="> " \
                        --no-multi \
                        --ansi \
                        --cycle \
                        2>/dev/null)
                if [[ -n "$selected" ]]; then
                    local sel_id
                    sel_id=$(echo "$selected" | awk '{print $1}')
                    echo ""
                    show_quote_by_id "$sel_id"
                    echo ""
                fi
                tui_wait "Press Enter to continue..."
                ;;
            "List all quotes")
                local filter_type
                filter_type=$(printf "all\nmovie\ntv\ngame\n" \
                    | fzf \
                        --height=~30% \
                        --layout=reverse \
                        --border=rounded \
                        --header="Filter by type" \
                        --prompt="> " \
                        --no-multi \
                        --cycle \
                        2>/dev/null)
                if [[ -n "$filter_type" ]]; then
                    echo ""
                    if [[ "$filter_type" == "all" ]]; then
                        ARG_TYPE="" ARG_SIMPLE="true" list_quotes
                    else
                        ARG_TYPE="$filter_type" ARG_SIMPLE="true" list_quotes
                    fi
                    echo ""
                fi
                tui_wait "Press Enter to continue..."
                ;;
            "Browse quotes")
                browse_quotes
                tui_wait "Press Enter to continue..."
                ;;
            "Add a quote")
                echo ""
                tui_add
                echo ""
                quote_count=$(sqlite3 "$DB" "SELECT COUNT(*) FROM quotes;" 2>/dev/null || echo "0")
                header="  quoter — ${quote_count} quotes in your collection"
                tui_wait "Press Enter to continue..."
                ;;
            "Delete a quote")
                echo ""
                local selected
                selected=$(sqlite3 "$DB" "SELECT id, quote, character, source FROM quotes ORDER BY id;" | \
                    while IFS='|' read -r id quote character source; do
                        printf "%-4s  %-50s  — %s, %s\n" "$id" "$quote" "$character" "$source"
                    done | fzf \
                        --height=~60% \
                        --layout=reverse \
                        --border=rounded \
                        --header="Select a quote to delete (Esc to cancel)" \
                        --no-multi \
                        --ansi \
                        --cycle \
                        --prompt="> " \
                        2>/dev/null)
                if [[ -n "$selected" ]]; then
                    local sel_id
                    sel_id=$(echo "$selected" | awk '{print $1}')
                    local result
                    result=$(sqlite3 "$DB" "SELECT id, quote, source, character FROM quotes WHERE id = $sel_id;" 2>/dev/null)
                    if [[ -n "$result" ]]; then
                        IFS='|' read -r id quote source character <<< "$result"
                        printf '"%s"\n  — %s, %s\n' "$quote" "$character" "$source"
                        if tui_confirm "Delete this quote?"; then
                            sqlite3 "$DB" "DELETE FROM quotes WHERE id = $sel_id;"
                            echo "Quote deleted."
                        else
                            echo "Cancelled."
                        fi
                    fi
                fi
                echo ""
                quote_count=$(sqlite3 "$DB" "SELECT COUNT(*) FROM quotes;" 2>/dev/null || echo "0")
                header="  quoter — ${quote_count} quotes in your collection"
                tui_wait "Press Enter to continue..."
                ;;
            "Exit")
                break
                ;;
        esac
    done

    echo "  Bye!"
    echo ""
}

show_help() {
    cat << 'HELP'
quoter — Display quotes from movies, TV shows, and games

Usage:
  quoter                                    Show a random quote
  quoter --tui                              Launch interactive TUI mode
  quoter --add                              Add a quote (interactive)
  quoter --add -q "quote" -s "source" -c "character" [-t type] [-e "S01E01"]
                                            Add a quote (non-interactive)
  quoter --list [-s "source"] [-t type] [-c "character"]
                                            List quotes (optionally filtered)
  quoter --browse                           Browse quotes interactively (fzf)
  quoter --search "term"                    Search quotes, characters, sources
  quoter --delete [id]                      Delete a quote (fzf picker if no ID)
  quoter --import <file.sql>                 Import quotes from a SQL file
  quoter --help                             Show this help

Options:
  -a, --add              Add a new quote
  -q, --quote TEXT        Quote text (with --add)
  -s, --source TEXT       Source title (with --add or --list)
  -c, --char TEXT         Character name (with --add or --list)
  -e, --season TEXT       Season/episode e.g. S01E01 (with --add, optional)
  -t, --type TEXT         Type: movie, tv, game (with --add or --list)
  -l, --list              List all quotes
  -b, --browse            Browse quotes interactively (requires fzf)
  -S, --simple            Simple output: just quote, character and source
  -T, --tui               Launch interactive TUI mode (requires fzf)
  -i, --import FILE       Import quotes from a SQL file
  -f, --search TEXT       Search quotes, characters, and sources
  -d, --delete [ID]       Delete a quote by ID, or pick interactively
  -h, --help              Show this help message

TUI features:
  Install fzf for interactive browsing, deletion, and TUI mode
  Install gum for styled display and interactive adding

Data is stored in: ~/.local/share/quoter/quoter.db
Default quotes loaded from: ~/.local/share/quoter/quotes.sql
HELP
}

ACTION=""
ARG_QUOTE=""
ARG_SOURCE=""
ARG_CHARACTER=""
ARG_SEASON=""
ARG_TYPE=""
ARG_SEARCH=""
ARG_DELETE=""
ARG_SIMPLE="false"
ARG_IMPORT=""

while [[ $# -gt 0 ]]; do
    case "$1" in
        -a|--add)
            ACTION="add"
            shift
            ;;
        -q|--quote)
            ARG_QUOTE="$2"
            shift 2
            ;;
        -s|--source)
            ARG_SOURCE="$2"
            shift 2
            ;;
        -c|--char|--character)
            ARG_CHARACTER="$2"
            shift 2
            ;;
        -e|--season)
            ARG_SEASON="$2"
            shift 2
            ;;
        -t|--type)
            ARG_TYPE="$2"
            shift 2
            ;;
        -l|--list)
            ACTION="list"
            shift
            ;;
        -b|--browse)
            ACTION="browse"
            shift
            ;;
        -S|--simple)
            ARG_SIMPLE="true"
            shift
            ;;
        -T|--tui)
            ACTION="tui"
            shift
            ;;
        -i|--import)
            ACTION="import"
            ARG_IMPORT="$2"
            shift 2
            ;;
        -f|--search)
            ACTION="search"
            ARG_SEARCH="$2"
            shift 2
            ;;
        -d|--delete)
            ACTION="delete"
            if [[ $# -gt 1 ]] && [[ "$2" =~ ^[0-9]+$ ]]; then
                ARG_DELETE="$2"
                shift 2
            else
                shift
            fi
            ;;
        -h|--help)
            ACTION="help"
            shift
            ;;
        *)
            echo "Unknown option: $1" >&2
            echo "Run ${BOLD}quoter --help${RESET} for usage." >&2
            exit 1
            ;;
    esac
done

db_init
db_seed

case "$ACTION" in
    add)
        if [[ -n "$ARG_QUOTE" || -n "$ARG_SOURCE" || -n "$ARG_CHARACTER" || -n "$ARG_SEASON" || -n "$ARG_TYPE" ]]; then
            add_noninteractive
        else
            add_interactive
        fi
        ;;
    list)
        list_quotes
        ;;
    browse)
        browse_quotes
        ;;
    tui)
        tui_mode
        ;;
    import)
        import_quotes
        ;;
    search)
        search_quotes
        ;;
    delete)
        delete_quote
        ;;
    help)
        show_help
        ;;
    "")
        show_random
        ;;
    *)
        echo "Unknown action: $ACTION" >&2
        exit 1
        ;;
esac