# Nushell Configuration Template
# Default configuration for Nushell + Plugins distribution
# Created by nushell-plugins full distribution system

# =============================================================================
# CORE CONFIGURATION
# =============================================================================

$env.config = {
    # Show banner on startup
    show_banner: false

    # Editing mode (emacs, vi)
    edit_mode: emacs

    # Shell integration features
    shell_integration: true

    # Use ansi coloring
    use_ansi_coloring: true

    # Bracketed paste mode
    bracketed_paste: true

    # Render right prompt on the last line of the prompt
    render_right_prompt_on_last_line: false

    # =============================================================================
    # TABLE CONFIGURATION
    # =============================================================================

    table: {
        # Table rendering mode
        mode: rounded  # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other

        # Index column mode
        index_mode: always  # always, never, auto

        # Show empty tables
        show_empty: true

        # Table padding
        padding: { left: 1, right: 1 }

        # Trim table content
        trim: {
            methodology: wrapping  # wrapping, truncating
            wrapping_try_keep_words: true
            truncating_suffix: "..."
        }

        # Header styling
        header_on_separator: false
    }

    # =============================================================================
    # ERROR HANDLING
    # =============================================================================

    error_style: "fancy"  # fancy, plain

    # =============================================================================
    # DATETIME FORMATTING
    # =============================================================================

    datetime_format: {
        # Normal datetime format
        normal: '%a, %d %b %Y %H:%M:%S %z'    # Tue, 1 Jan 2023 12:00:00 +0000

        # Table datetime format (shorter for table display)
        table: '%m/%d/%y %I:%M:%S%p'          # 01/01/23 12:00:00AM
    }

    # =============================================================================
    # COMPLETIONS CONFIGURATION
    # =============================================================================

    completions: {
        # Case sensitivity for completions
        case_sensitive: false

        # Quick completions (don't wait for all to be calculated)
        quick: true

        # Partial completions (complete common prefix)
        partial: true

        # Completion algorithm
        algorithm: "prefix"    # prefix, fuzzy

        # External completer command
        external: {
            enable: true
            max_results: 100
            completer: null
        }
    }

    # =============================================================================
    # FILE SIZE FORMATTING
    # =============================================================================

    filesize: {
        # Use metric units (KB, MB, GB) vs binary (KiB, MiB, GiB)
        metric: false

        # Filesize format
        format: "auto"  # auto, b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib
    }

    # =============================================================================
    # CURSOR SHAPE CONFIGURATION
    # =============================================================================

    cursor_shape: {
        # Cursor shapes for different modes
        emacs: line      # line, block, underscore, blink_line, blink_block, blink_underscore
        vi_insert: block
        vi_normal: underscore
    }

    # =============================================================================
    # COLOR CONFIGURATION
    # =============================================================================

    color_config: {
        # Separator color
        separator: white

        # Leading trailing space
        leading_trailing_space_bg: { attr: n }

        # Header colors
        header: green_bold

        # Empty cell
        empty: blue

        # Boolean values
        bool: {
            true: light_cyan
            false: light_gray
        }

        # Integer types
        int: white
        float: white

        # String and date types
        string: white
        date: purple

        # Duration
        duration: white

        # File sizes
        filesize: {
            b: white
            kb: cyan
            mb: blue
            gb: green
            tb: red
            pb: purple
        }

        # Range
        range: white

        # Binary
        binary: cyan_bold

        # Lists
        list: white
        record: white

        # Nothing
        nothing: white

        # Block
        block: white

        # Hints
        hints: dark_gray

        # Search result
        search_result: {
            fg: white
            bg: red
        }

        # Shape colors
        shape_garbage: { fg: white bg: red attr: b}
        shape_binary: purple_bold
        shape_bool: light_cyan
        shape_int: purple_bold
        shape_float: purple_bold
        shape_range: yellow_bold
        shape_internalcall: cyan_bold
        shape_external: cyan
        shape_externalarg: green_bold
        shape_literal: blue
        shape_operator: yellow
        shape_signature: green_bold
        shape_string: green
        shape_string_interpolation: cyan_bold
        shape_datetime: cyan_bold
        shape_list: cyan_bold
        shape_table: blue_bold
        shape_record: cyan_bold
        shape_block: blue_bold
        shape_filepath: cyan
        shape_directory: cyan
        shape_globpattern: cyan_bold
        shape_variable: purple
        shape_flag: blue_bold
        shape_custom: green
        shape_nothing: light_cyan
        shape_matching_brackets: { attr: u }
    }

    # =============================================================================
    # HISTORY CONFIGURATION
    # =============================================================================

    history: {
        # Maximum number of history entries
        max_size: 100_000

        # Sync history on enter
        sync_on_enter: true

        # History file format
        file_format: "plaintext"  # sqlite, plaintext

        # Isolation mode
        isolation: false
    }

    # =============================================================================
    # KEYBINDINGS
    # =============================================================================

    keybindings: [
        {
            name: completion_menu
            modifier: none
            keycode: tab
            mode: [emacs vi_normal vi_insert]
            event: {
                until: [
                    { send: menu name: completion_menu }
                    { send: menunext }
                    { edit: complete }
                ]
            }
        }
        {
            name: history_menu
            modifier: control
            keycode: char_r
            mode: [emacs, vi_insert, vi_normal]
            event: { send: menu name: history_menu }
        }
        {
            name: help_menu
            modifier: none
            keycode: f1
            mode: [emacs, vi_insert, vi_normal]
            event: { send: menu name: help_menu }
        }
        {
            name: completion_previous
            modifier: shift
            keycode: backtab
            mode: [emacs, vi_normal, vi_insert]
            event: { send: menuprevious }
        }
        {
            name: next_page
            modifier: control
            keycode: char_x
            mode: emacs
            event: { send: menupagenext }
        }
        {
            name: undo_or_previous_page
            modifier: control
            keycode: char_z
            mode: emacs
            event: {
                until: [
                    { send: menupageprevious }
                    { edit: undo }
                ]
            }
        }
        {
            name: escape
            modifier: none
            keycode: escape
            mode: [emacs, vi_insert]
            event: { send: esc }
        }
        {
            name: cancel_command
            modifier: control
            keycode: char_c
            mode: [emacs, vi_insert, vi_normal]
            event: { send: ctrlc }
        }
        {
            name: quit_shell
            modifier: control
            keycode: char_d
            mode: [emacs, vi_insert, vi_normal]
            event: { send: ctrld }
        }
        {
            name: clear_screen
            modifier: control
            keycode: char_l
            mode: [emacs, vi_insert, vi_normal]
            event: { send: clearscreen }
        }
        {
            name: search_history
            modifier: control
            keycode: char_q
            mode: [emacs, vi_insert, vi_normal]
            event: { send: searchhistory }
        }
        {
            name: open_command_editor
            modifier: control
            keycode: char_o
            mode: [emacs, vi_insert, vi_normal]
            event: { send: openeditor }
        }
        {
            name: move_up
            modifier: none
            keycode: up
            mode: [emacs, vi_insert, vi_normal]
            event: {
                until: [
                    { send: menuup }
                    { send: up }
                ]
            }
        }
        {
            name: move_down
            modifier: none
            keycode: down
            mode: [emacs, vi_insert, vi_normal]
            event: {
                until: [
                    { send: menudown }
                    { send: down }
                ]
            }
        }
        {
            name: move_left
            modifier: none
            keycode: left
            mode: [emacs, vi_insert, vi_normal]
            event: {
                until: [
                    { send: menuleft }
                    { send: left }
                ]
            }
        }
        {
            name: move_right_or_take_history_hint
            modifier: none
            keycode: right
            mode: [emacs, vi_insert, vi_normal]
            event: {
                until: [
                    { send: historyhintcomplete }
                    { send: menuright }
                    { send: right }
                ]
            }
        }
        {
            name: move_one_word_left
            modifier: control
            keycode: left
            mode: [emacs, vi_insert, vi_normal]
            event: { edit: movewordleft }
        }
        {
            name: move_one_word_right_or_take_history_hint
            modifier: control
            keycode: right
            mode: [emacs, vi_insert, vi_normal]
            event: {
                until: [
                    { send: historyhintwordcomplete }
                    { edit: movewordright }
                ]
            }
        }
        {
            name: move_to_line_start
            modifier: none
            keycode: home
            mode: [emacs, vi_insert, vi_normal]
            event: { edit: movetolinestart }
        }
        {
            name: move_to_line_start_alt
            modifier: control
            keycode: char_a
            mode: [emacs, vi_insert]
            event: { edit: movetolinestart }
        }
        {
            name: move_to_line_end_or_take_history_hint
            modifier: none
            keycode: end
            mode: [emacs, vi_insert, vi_normal]
            event: {
                until: [
                    { send: historyhintcomplete }
                    { edit: movetolineend }
                ]
            }
        }
        {
            name: move_to_line_end_alt
            modifier: control
            keycode: char_e
            mode: [emacs, vi_insert]
            event: {
                until: [
                    { send: historyhintcomplete }
                    { edit: movetolineend }
                ]
            }
        }
        {
            name: move_to_line_start_vi
            modifier: none
            keycode: char_0
            mode: vi_normal
            event: { edit: movetolinestart }
        }
        {
            name: move_to_line_end_vi
            modifier: none
            keycode: char_4
            mode: vi_normal
            event: { edit: movetolineend }
        }
        {
            name: move_up_vi
            modifier: none
            keycode: char_k
            mode: vi_normal
            event: { send: up }
        }
        {
            name: move_down_vi
            modifier: none
            keycode: char_j
            mode: vi_normal
            event: { send: down }
        }
        {
            name: backspace
            modifier: none
            keycode: backspace
            mode: [emacs, vi_insert]
            event: { edit: backspace }
        }
        {
            name: delete_char
            modifier: none
            keycode: delete
            mode: [emacs, vi_insert]
            event: { edit: delete }
        }
        {
            name: delete_word
            modifier: control
            keycode: char_w
            mode: [emacs, vi_insert]
            event: { edit: backspaceword }
        }
        {
            name: cut_word_to_right
            modifier: control
            keycode: char_k
            mode: emacs
            event: { edit: cuttoend }
        }
        {
            name: cut_line_to_right
            modifier: control
            keycode: char_k
            mode: vi_insert
            event: { edit: cuttoend }
        }
        {
            name: cut_line_from_start
            modifier: control
            keycode: char_u
            mode: [emacs, vi_insert]
            event: { edit: cutfromstart }
        }
        {
            name: swap_graphemes
            modifier: control
            keycode: char_t
            mode: emacs
            event: { edit: swapgraphemes }
        }
        {
            name: move_one_word_left_vi
            modifier: none
            keycode: char_b
            mode: vi_normal
            event: { edit: movewordleft }
        }
        {
            name: move_one_word_right_vi
            modifier: none
            keycode: char_w
            mode: vi_normal
            event: { edit: movewordright }
        }
        {
            name: move_one_word_right_end_vi
            modifier: none
            keycode: char_e
            mode: vi_normal
            event: { edit: movewordrightend }
        }
        {
            name: move_one_big_word_left_vi
            modifier: shift
            keycode: char_b
            mode: vi_normal
            event: { edit: movebigwordleft }
        }
        {
            name: move_one_big_word_right_vi
            modifier: shift
            keycode: char_w
            mode: vi_normal
            event: { edit: movebigwordright }
        }
        {
            name: move_one_big_word_right_end_vi
            modifier: shift
            keycode: char_e
            mode: vi_normal
            event: { edit: movebigwordrightend }
        }
        {
            name: delete_one_character_backward_vi
            modifier: none
            keycode: char_x
            mode: vi_normal
            event: { edit: backspace }
        }
        {
            name: delete_one_word_backward_vi
            modifier: none
            keycode: char_X
            mode: vi_normal
            event: { edit: backspaceword }
        }
        {
            name: delete_to_end_of_line_vi
            modifier: shift
            keycode: char_d
            mode: vi_normal
            event: { edit: cuttoend }
        }
        {
            name: delete_line_vi
            modifier: none
            keycode: char_dd
            mode: vi_normal
            event: { edit: cutline }
        }
        {
            name: change_to_end_of_line_vi
            modifier: shift
            keycode: char_c
            mode: vi_normal
            event: [
                { edit: cuttoend }
                { edit: insertmode }
            ]
        }
        {
            name: change_line_vi
            modifier: none
            keycode: char_cc
            mode: vi_normal
            event: [
                { edit: cutline }
                { edit: insertmode }
            ]
        }
        {
            name: open_line_above_vi
            modifier: shift
            keycode: char_o
            mode: vi_normal
            event: [
                { edit: insertcharafter }
                { edit: newline }
                { edit: moveup }
                { edit: insertmode }
            ]
        }
        {
            name: open_line_below_vi
            modifier: none
            keycode: char_o
            mode: vi_normal
            event: [
                { edit: insertcharafter }
                { edit: newline }
                { edit: insertmode }
            ]
        }
        {
            name: enter_vi_insert_mode
            modifier: none
            keycode: char_i
            mode: vi_normal
            event: { edit: insertmode }
        }
        {
            name: enter_vi_append_mode
            modifier: none
            keycode: char_a
            mode: vi_normal
            event: [
                { edit: moveright }
                { edit: insertmode }
            ]
        }
        {
            name: enter_vi_append_mode_at_end_of_line
            modifier: shift
            keycode: char_a
            mode: vi_normal
            event: [
                { edit: movetolineend }
                { edit: insertmode }
            ]
        }
        {
            name: enter_vi_insert_mode_at_start_of_line
            modifier: shift
            keycode: char_i
            mode: vi_normal
            event: [
                { edit: movetolinestart }
                { edit: insertmode }
            ]
        }
        {
            name: yank_vi
            modifier: none
            keycode: char_y
            mode: vi_normal
            event: { edit: yank }
        }
        {
            name: yank_to_end_of_line_vi
            modifier: shift
            keycode: char_y
            mode: vi_normal
            event: { edit: yanktoend }
        }
        {
            name: yank_line_vi
            modifier: none
            keycode: char_yy
            mode: vi_normal
            event: { edit: yankline }
        }
        {
            name: paste_after_vi
            modifier: none
            keycode: char_p
            mode: vi_normal
            event: { edit: pasteafter }
        }
        {
            name: paste_before_vi
            modifier: shift
            keycode: char_p
            mode: vi_normal
            event: { edit: pastebefore }
        }
        {
            name: undo_vi
            modifier: none
            keycode: char_u
            mode: vi_normal
            event: { edit: undo }
        }
        {
            name: redo_vi
            modifier: control
            keycode: char_r
            mode: vi_normal
            event: { edit: redo }
        }
        {
            name: enter_vi_normal_mode
            modifier: none
            keycode: escape
            mode: vi_insert
            event: { edit: normalmode }
        }
    ]

    # =============================================================================
    # MENU CONFIGURATION
    # =============================================================================

    menus: [
        # Completion menu
        {
            name: completion_menu
            only_buffer_difference: false
            marker: "| "
            type: {
                layout: columnar
                columns: 4
                col_width: 20
                col_padding: 2
            }
            style: {
                text: green
                selected_text: { attr: r }
                description_text: yellow
                match_text: { attr: u }
                selected_match_text: { attr: ur }
            }
        }

        # History menu
        {
            name: history_menu
            only_buffer_difference: true
            marker: "? "
            type: {
                layout: list
                page_size: 10
            }
            style: {
                text: green
                selected_text: green_reverse
                description_text: yellow
            }
        }

        # Help menu
        {
            name: help_menu
            only_buffer_difference: true
            marker: "? "
            type: {
                layout: description
                columns: 4
                col_width: 20
                col_padding: 2
                selection_rows: 4
                description_rows: 10
            }
            style: {
                text: green
                selected_text: green_reverse
                description_text: yellow
            }
        }
    ]

    # =============================================================================
    # HOOKS CONFIGURATION
    # =============================================================================

    hooks: {
        pre_prompt: [
            # Update terminal title with current directory
            {||
                print -n $"\e]0;($env.PWD | path basename) - Nushell\e\\"
            }
        ]
        pre_execution: [
            # Add timestamp to long-running commands
            {||
                let start_time = (date now | format date '%Y-%m-%d %H:%M:%S')
                $env.COMMAND_START_TIME = $start_time
            }
        ]
        env_change: {
            PWD: [
                # Auto-activate direnv if available
                {|before, after|
                    if (which direnv | is-not-empty) {
                        direnv export json | from json | default {} | load-env
                    }
                }
            ]
        }
        command_not_found: {
            # Suggest alternatives for command not found
            |cmd_name| (
                try {
                    if (which thefuck | is-not-empty) {
                        $"💡 Did you mean: (thefuck --alias | str trim)"
                    } else {
                        $"❌ Command not found: ($cmd_name)"
                    }
                } catch {
                    $"❌ Command not found: ($cmd_name)"
                }
            )
        }
        display_output: {
            # Custom output formatting
            |output| (
                if ($output | describe) == "table" {
                    $output | table --expand
                } else {
                    $output
                }
            )
        }
    }

    # =============================================================================
    # PLUGIN CONFIGURATION
    # =============================================================================

    plugins: {
        # Plugin loading timeout (in seconds)
        timeout: 60

        # Auto-register plugins on startup
        auto_register: true

        # Plugin search paths
        search_paths: [
            ($nu.config-path | path dirname | path join "plugins")
        ]
    }

    # =============================================================================
    # PERFORMANCE SETTINGS
    # =============================================================================

    # Buffer size for commands
    buffer_editor: null

    # Use LSP for completions if available
    use_lsp: true

    # Maximum recursion depth
    recursion_limit: 50

    # Plugin call timeout
    plugin_timeout: 60_000  # milliseconds

    # =============================================================================
    # EXTERNAL INTEGRATIONS
    # =============================================================================

    # Carapace (external completer)
    carapace: {
        enable: false
        cache_dir: ($env.HOME | path join ".cache" "carapace")
    }

    # Starship prompt
    starship: {
        enable: (which starship | is-not-empty)
        config: ($nu.config-path | path dirname | path join "starship.toml")
    }

    # Zoxide integration
    zoxide: {
        enable: (which zoxide | is-not-empty)
        hook: "pwd"  # none, prompt, pwd
    }

    # =============================================================================
    # DEVELOPMENT AND DEBUG
    # =============================================================================

    # Debug mode
    debug_mode: false

    # Log level
    log_level: "warn"  # error, warn, info, debug, trace

    # Profiling
    profile: false
}

# =============================================================================
# PLUGIN LOADING AND REGISTRATION
# =============================================================================

# Auto-load common plugins if they're available
# NOTE: nu_plugin_example is excluded from distributions - it's for reference and development only
let plugin_binaries = [
    "nu_plugin_clipboard"
    "nu_plugin_desktop_notifications"
    "nu_plugin_hashes"
    "nu_plugin_highlight"
    "nu_plugin_image"
    "nu_plugin_kcl"
    "nu_plugin_tera"
    "nu_plugin_custom_values"
    "nu_plugin_formats"
    "nu_plugin_gstat"
    "nu_plugin_inc"
    "nu_plugin_polars"
    "nu_plugin_query"
]

# Register plugins that are available
for plugin in $plugin_binaries {
    try {
        # Check if plugin is already registered
        if (plugin list | where name == $plugin | is-empty) {
            # Try to find and register the plugin
            let plugin_path = (which $plugin | get path.0?)
            if ($plugin_path | is-not-empty) {
                plugin add $plugin_path
            }
        }
    } catch {
        # Silently ignore plugin loading errors
    }
}

# =============================================================================
# CUSTOM FUNCTIONS AND ALIASES
# =============================================================================

# Enhanced ls with better colors and formatting
def --env la [...rest] {
    ls -la $rest | sort-by type name
}

# Quick directory navigation
def --env .. [] {
    cd ..
}

def --env ... [] {
    cd ../..
}

def --env .... [] {
    cd ../../..
}

# Git shortcuts (if git is available)
if (which git | is-not-empty) {
    def gs [] { git status --short }
    def ga [...files] { git add $files }
    def gc [message: string] { git commit -m $message }
    def gp [] { git push }
    def gl [] { git log --oneline -10 }
}

# System information
def sysinfo [] {
    {
        OS: $nu.os-info.name
        Arch: $nu.os-info.arch
        Version: $nu.os-info.version
        Kernel: $nu.os-info.kernel_version
        Hostname: (hostname)
        Shell: $"Nushell (version)"
        Plugins: (plugin list | length)
        Config: $nu.config-path
    }
}

# Plugin management helpers
def plugin-info [] {
    plugin list | select name version is_running pid
}

def plugin-restart [name: string] {
    plugin stop $name
    plugin use $name
}

# Quick file operations
def --env take [name: string] {
    mkdir $name
    cd $name
}

def trash [path: string] {
    if (which trash | is-not-empty) {
        ^trash $path
    } else {
        print $"⚠️  No trash command available, use 'rm ($path)' to delete permanently"
    }
}

# Enhanced which command
def which-all [command: string] {
    which -a $command | select path
}

# =============================================================================
# PROMPT CONFIGURATION
# =============================================================================

# Custom prompt function (used if starship is not available)
def create_left_prompt [] {
    let home = $nu.home-path
    let dir = ([
        ($env.PWD | str substring 0..($home | str length) | str replace $home "~")
        ($env.PWD | str substring ($home | str length)..)
    ] | str join)

    let path_color = (if (is-admin) { ansi red_bold } else { ansi green_bold })
    let separator_color = (ansi light_gray)
    let path_segment = $"($path_color)($dir)"

    # Git information if in a git repo
    let git_info = if (ls -la | where name == .git | is-not-empty) {
        try {
            let branch = (git branch --show-current 2>/dev/null | str trim)
            if not ($branch | is-empty) {
                let git_color = ansi yellow
                $" ($git_color)($branch)(ansi reset)"
            } else { "" }
        } catch { "" }
    } else { "" }

    $"($path_segment)($git_info)($separator_color) ❯ (ansi reset)"
}

def create_right_prompt [] {
    # Show current time and execution duration
    let time_segment = (date now | format date '%H:%M:%S')

    let duration = if "COMMAND_START_TIME" in $env {
        let start = ($env.COMMAND_START_TIME | into datetime)
        let duration = ((date now) - $start)
        if ($duration > 1sec) {
            $" took (ansi yellow)($duration)(ansi reset)"
        } else { "" }
    } else { "" }

    $"(ansi light_gray)($time_segment)($duration)(ansi reset)"
}

# Set prompt functions if starship is not available
if not (which starship | is-not-empty) {
    $env.PROMPT_COMMAND = { || create_left_prompt }
    $env.PROMPT_COMMAND_RIGHT = { || create_right_prompt }
}

# =============================================================================
# STARTUP MESSAGE
# =============================================================================

# Uncomment to show welcome message
# print $"🚀 Welcome to Nushell + Plugins!"
# print $"📦 (plugin list | length) plugins loaded"
# print $"💡 Type 'help' for commands or 'sysinfo' for system information"
# print ""

# =============================================================================
# USER CUSTOMIZATION
# =============================================================================

# Load user-specific configuration if it exists
let user_config_file = ($nu.config-path | path dirname | path join "user_config.nu")
if ($user_config_file | path exists) {
    source $user_config_file
}

# Load local project configuration if it exists
let local_config_file = (pwd | path join ".nu_config")
if ($local_config_file | path exists) {
    source $local_config_file
}