#!/usr/bin/env nu

# Plugin Status Dashboard
# Shows the current status of all plugins and their upstream sync state

# Version check - mandatory for all plugin operations
def version_check [] {
    try {
        nu scripts/check_version.nu --quiet | ignore
    } catch {
        print "❌ Nushell version mismatch detected!"
        print "🔧 Run: nu scripts/check_version.nu --fix"
        exit 1
    }
}

# Load plugin registry
def load_registry [] {
    let registry_path = "etc/plugin_registry.toml"
    if not ($registry_path | path exists) {
        error make {msg: "Plugin registry not found. Please run from repository root directory."}
    }
    open $registry_path
}

# Load exclusions configuration
def load_exclusions [] {
    let exclude_path = "etc/upstream_exclude.toml"
    if ($exclude_path | path exists) {
        let config = open $exclude_path
        {
            all: ($config.exclude.plugins? | default []),
            check: ($config.exclude.check.plugins? | default []),
            merge: ($config.exclude.merge.plugins? | default []),
            patterns: ($config.exclude.patterns.plugins? | default [])
        }
    } else {
        {all: [], check: [], merge: [], patterns: []}
    }
}

# Check if plugin should be excluded
def is_plugin_excluded [plugin_name: string, exclusions: record] {
    # Check direct exclusions
    if $plugin_name in $exclusions.all {
        return true
    }

    # Check pattern exclusions
    for pattern in $exclusions.patterns {
        if ($plugin_name | str contains ($pattern | str replace "*" "")) {
            return true
        }
    }

    false
}

# Filter plugins to only include existing directories and non-excluded plugins
def filter_plugins [plugins: record, exclusions: record] {
    $plugins
    | transpose name config
    | where {
        let plugin_name = $in.name
        let plugin_path = $in.config.local_path

        # Check if directory exists
        let dir_exists = ($plugin_path | path exists)

        # Check if plugin is excluded
        let is_excluded = (is_plugin_excluded $plugin_name $exclusions)

        $dir_exists and not $is_excluded
    }
    | reduce -f {} {|it, acc|
        $acc | insert $it.name $it.config
    }
}

# Save plugin registry
def save_registry [registry: record] {
    $registry | to toml | save -f "etc/plugin_registry.toml"
}

# Get status emoji and description
def get_status_emoji [status: string] {
    match $status {
        "ok" => "✅",
        "pending" => "⚠️",
        "error" => "❌",
        "local_only" => "🏠",
        "unknown" => "❓",
        "conflict" => "🔥",
        _ => "📦"
    }
}

# Get status description
def get_status_description [status: string] {
    match $status {
        "ok" => "Synchronized with upstream",
        "pending" => "Changes detected - needs review",
        "error" => "Error during upstream check",
        "local_only" => "No upstream - local development",
        "unknown" => "Not yet checked",
        "conflict" => "Merge conflicts detected",
        _ => "Unknown status"
    }
}

# Format date for display
def format_date [date_str: string] {
    if ($date_str | is-empty) {
        "Never"
    } else {
        try {
            $date_str | str substring 0..9  # Show just the date part
        } catch {
            $date_str
        }
    }
}

# Get plugin directory status
def get_directory_status [local_path: string] {
    let full_path = $local_path
    if ($full_path | path exists) {
        if ($"($full_path)/Cargo.toml" | path exists) {
            "📂 Present"
        } else {
            "📁 No Cargo.toml"
        }
    } else {
        "❌ Missing"
    }
}

# Display summary statistics
def show_summary [plugins: record] {
    print "📊 Plugin Status Summary"
    print "=================================================="

    let status_counts = $plugins
    | values
    | group-by status
    | transpose status plugins
    | each {|entry| {
        status: $entry.status,
        count: ($entry.plugins | length),
        emoji: (get_status_emoji $entry.status)
    }}
    | sort-by count --reverse

    let total_plugins = ($plugins | values | length)
    print $"📦 Total Plugins: ($total_plugins)"
    print ""

    for status in $status_counts {
        let description = get_status_description $status.status
        print $"($status.emoji) ($description): ($status.count) plugins"
    }

    print ""

    # Show breakdown by type
    let upstream_plugins = $plugins | values | where ($it.upstream_url | is-not-empty) | length
    let local_plugins = $plugins | values | where ($it.upstream_url | is-empty) | length

    print "📋 Plugin Types:"
    print $"  🔗 With Upstream: ($upstream_plugins) plugins"
    print $"  🏠 Local Only: ($local_plugins) plugins"
    print ""
}

# Show detailed plugin table
def show_plugin_table [plugins: record, show_all: bool] {
    let plugin_data = $plugins
    | transpose name config
    | each {|plugin|
        {
            Plugin: $plugin.name,
            Status: $"(get_status_emoji $plugin.config.status) ($plugin.config.status)",
            "Last Check": (format_date $plugin.config.last_checked_date),
            "Directory": (get_directory_status $plugin.config.local_path),
            "Upstream": (if ($plugin.config.upstream_url | is-empty) { "None" } else { "📡 Yes" }),
            "Auto-OK": (if $plugin.config.auto_ok_on_nu_deps_only { "✓" } else { "✗" }),
            "Description": $plugin.config.description
        }
    }

    let filtered_data = if $show_all {
        $plugin_data
    } else {
        $plugin_data | where Status !~ "local_only"
    }

    $filtered_data | table --expand
}

# Show plugins that need attention
def show_attention_needed [plugins: record] {
    let needs_attention = $plugins
    | transpose name config
    | where $it.config.status in ["pending", "error", "conflict", "unknown"]

    if ($needs_attention | length) > 0 {
        print "\n🚨 Plugins Requiring Attention:"
        print "========================================"

        for plugin in $needs_attention {
            let emoji = get_status_emoji $plugin.config.status
            print $"($emoji) ($plugin.name): ($plugin.config.status)"
            if not ($plugin.config.upstream_url | is-empty) {
                print $"   Upstream: ($plugin.config.upstream_url)"
            }
            if not ($plugin.config.last_checked_date | is-empty) {
                print $"   Last checked: ($plugin.config.last_checked_date)"
            }
            print ""
        }
    }
}

# Show recent activity
def show_recent_activity [plugins: record] {
    let recent_plugins = $plugins
    | transpose name config
    | where not ($it.config.last_checked_date | is-empty)
    | sort-by config.last_checked_date --reverse
    | first 5

    if ($recent_plugins | length) > 0 {
        print "\n📅 Recently Checked Plugins:"
        print "=" * 35

        for plugin in $recent_plugins {
            let emoji = get_status_emoji $plugin.config.status
            print $"($emoji) ($plugin.name) - ($plugin.config.last_checked_date)"
        }
        print ""
    }
}

# Update plugin status manually
def update_plugin_status [plugin_name: string, new_status: string] {
    let registry = load_registry

    if not ($plugin_name in ($registry.plugins | columns)) {
        error make {msg: $"Plugin '($plugin_name)' not found in registry"}
    }

    let valid_statuses = ["ok", "pending", "error", "conflict", "unknown", "local_only"]
    if not ($new_status in $valid_statuses) {
        error make {msg: $"Invalid status. Valid options: ($valid_statuses | str join ', ')"}
    }

    let updated_registry = $registry | upsert $"plugins.($plugin_name).status" $new_status
    save_registry $updated_registry

    print $"✅ Updated ($plugin_name) status to '($new_status)'"
}

# Show help information
def show_help [] {
    print "Plugin Status Dashboard - Nushell Plugin Upstream Tracker"
    print ""
    print "USAGE:"
    print "  nu plugin_status.nu [OPTIONS] [COMMAND]"
    print ""
    print "OPTIONS:"
    print "  --all, -a          Show all plugins including local-only"
    print "  --json, -j         Output in JSON format"
    print "  --help, -h         Show this help message"
    print ""
    print "COMMANDS:"
    print "  status             Show plugin status dashboard (default)"
    print "  update <plugin> <status>  Update plugin status manually"
    print "  summary            Show summary statistics only"
    print "  attention          Show only plugins needing attention"
    print ""
    print "STATUS VALUES:"
    print "  ✅ ok        - Synchronized with upstream"
    print "  ⚠️  pending   - Changes detected - needs review"
    print "  ❌ error     - Error during upstream check"
    print "  🔥 conflict  - Merge conflicts detected"
    print "  ❓ unknown   - Not yet checked"
    print "  🏠 local_only - No upstream - local development"
    print ""
    print "EXAMPLES:"
    print "  nu plugin_status.nu                        # Show status dashboard"
    print "  nu plugin_status.nu --all                  # Show all plugins"
    print "  nu plugin_status.nu summary                # Show summary only"
    print "  nu plugin_status.nu update highlight ok    # Mark plugin as OK"
}

# Main function
def main [
    command?: string             # Command to execute
    plugin?: string             # Plugin name (for update command)
    status?: string             # New status (for update command)
    --all (-a)                  # Show all plugins including local-only
    --json (-j)                 # Output in JSON format
    --help (-h)                 # Show help
] {
    if $help {
        show_help
        return
    }

    # Mandatory version check before any plugin operations
    version_check

    # Ensure we're in the repository root directory
    if not ("nu_plugin_clipboard" | path exists) {
        error make {msg: "Please run this script from the nushell-plugins repository root directory"}
    }

    # Load registry and exclusions
    let registry = load_registry
    let exclusions = load_exclusions
    let filtered_plugins = filter_plugins $registry.plugins $exclusions

    match ($command | default "status") {
        "status" => {
            if $json {
                $filtered_plugins | to json
            } else {
                show_summary $filtered_plugins
                show_plugin_table $filtered_plugins $all
                show_attention_needed $filtered_plugins
                show_recent_activity $filtered_plugins

                print $"\n💡 Tips:"
                print "  • Run 'nu check_upstream_changes.nu' to check for updates"
                print "  • Use 'nu plugin_status.nu --all' to see all plugins"
                print "  • Use 'nu plugin_status.nu update <plugin> <status>' to manually update status"
            }
        },
        "summary" => {
            show_summary $filtered_plugins
        },
        "attention" => {
            show_attention_needed $filtered_plugins
        },
        "update" => {
            if ($plugin | is-empty) or ($status | is-empty) {
                error make {msg: "Update command requires plugin name and status. Use: update <plugin> <status>"}
            }
            update_plugin_status $plugin $status
        },
        _ => {
            error make {msg: $"Unknown command: ($command). Use --help for usage information."}
        }
    }
}

if ($env.NUSHELL_EXECUTION_CONTEXT? | default "" | str contains "run") {
    main
}