#!/usr/bin/env nu
# Main version management interface
# Completely configuration-driven, no hardcoded components

use version_core.nu *
use version_loader.nu *
use version_formatter.nu *
use interface.nu *

# Check versions for discovered components
export def check-versions [
    --path: string = ""           # Base path to search
    --types: list = []           # Filter by types
    --fetch-latest = false       # Fetch latest versions
    --respect-fixed = true       # Respect fixed flag
    --config-file: string = ""   # Use specific config file
]: nothing -> list {
    # Load configurations
    let configs = if ($config_file | is-not-empty) {
        load-configuration-file $config_file
    } else {
        discover-configurations --base-path=$path --types=$types
    }

    # Check each configuration
    $configs | each { |config|
        check-version $config --fetch-latest=$fetch_latest --respect-fixed=$respect_fixed
    }
}

# Display version status
export def show-versions [
    --path: string = ""
    --types: list = []
    --fetch-latest = true
    --group-by: string = "type"
    --format: string = "table"  # table, json, yaml
]: nothing -> nothing {
    let results = (check-versions --path=$path --types=$types --fetch-latest=$fetch_latest)

    match $format {
        "table" => {
            format-results $results --group-by=$group_by
        }
        "json" => {
            print ($results | to json -i 2)
        }
        "yaml" => {
            print ($results | to yaml)
        }
        _ => {
            format-results $results
        }
    }
}

# Check for available updates (does not modify configs)
export def check-available-updates [
    --path: string = ""
    --types: list = []
]: nothing -> nothing {
    let results = (check-versions --path=$path --types=$types --fetch-latest=true --respect-fixed=true)
    let updates = ($results | where status == "update_available")

    if ($updates | is-empty) {
        _print "✅ All components are up to date"
        return
    }

    _print "Updates available:"
    _print ($updates | select id configured latest | rename id configured "latest available" | table)

    # Show installation guidance for each update
    for update in $updates {
        let config = (discover-configurations --types=[$update.type]
            | where id == $update.id
            | get -o 0)

        if ($config | is-not-empty) {
            show-installation-guidance $config $update.latest
        }
    }

    _print $"\n💡 After installing, run 'tools apply-updates' to update configuration files"
}

# Apply updates to configuration files (after manual installation)
export def apply-config-updates [
    --path: string = ""
    --types: list = []
    --dry-run = false
    --force = false  # Update even if fixed
]: nothing -> nothing {
    let results = (check-versions --path=$path --types=$types --fetch-latest=false --respect-fixed=(not $force))

    # Find components where installed version is newer than configured
    let updates = ($results | where status == "ahead_config")

    if ($updates | is-empty) {
        _print "✅ All configurations match installed versions"
        return
    }

    _print "Configuration updates available (installed version newer than configured):"
    _print ($updates | select id configured installed | table)

    if $dry_run {
        _print "\n🔍 Dry run mode - no changes will be made"
        return
    }

    let proceed = (input "Update configurations to match installed versions? (y/n): ")
    if $proceed != "y" { return }

    # Update each component's configuration file to match installed version
    for update in $updates {
        let config = (discover-configurations --types=[$update.type]
            | where id == $update.id
            | get -o 0)

        if ($config | is-not-empty) {
            let source_file = $config.metadata.source_file
            update-configuration-file $source_file $update.id $update.installed
            _print $"✅ Updated config ($update.id): ($update.configured) -> ($update.installed)"
        }
    }
}

# Show agnostic installation guidance
export def show-installation-guidance [
    config: record
    version: string
]: nothing -> nothing {
    _print $"\n📦 To install ($config.id) ($version):"

    # Show documentation/site links from configuration
    if ($config.metadata.site | is-not-empty) {
        _print $"  • Documentation: ($config.metadata.site)"
    }

    # Show source repository if available
    if ($config.source.type? | default "" | str contains "github") {
        let repo = ($config.source.repo? | default "")
        if ($repo | is-not-empty) {
            _print $"  • Releases: https://github.com/($repo)/releases"
        }
    }

    # Show generic installation command if available in metadata
    if ($config.metadata.install_cmd? | default "" | is-not-empty) {
        _print $"  • Install: ($config.metadata.install_cmd)"
    }

    _print $"\n🔍 Configuration updated, manual installation required"
    _print $"💡 Run 'tools check ($config.id)' after installation to verify"
}

# Update configuration file
export def update-configuration-file [
    file_path: string
    component_id: string
    new_version: string
]: nothing -> nothing {
    if not ($file_path | path exists) { return }

    let ext = ($file_path | path parse | get extension)

    match $ext {
        "yaml" | "yml" => {
            let data = (open $file_path)
            let updated = ($data | upsert $component_id ($data | get $component_id | upsert version $new_version))
            $updated | save -f $file_path
        }
        "json" => {
            let data = (open $file_path)
            let updated = ($data | upsert $component_id ($data | get $component_id | upsert version $new_version))
            $updated | to json -i 2 | save -f $file_path
        }
        "toml" => {
            # TOML update would need proper TOML writer
            print $"⚠️ TOML update not implemented for ($file_path)"
        }
        "k" => {
            # KCL update would need KCL parser/writer
            print $"⚠️ KCL update not implemented for ($file_path)"
        }
        _ => {
            print $"⚠️ Unknown file type: ($ext)"
        }
    }
}

# Pin/unpin component version
export def set-fixed [
    component_id: string
    fixed: bool
    --path: string = ""
]: nothing -> nothing {
    let configs = (discover-configurations --base-path=$path)
    let config = ($configs | where id == $component_id | get -o 0)

    if ($config | is-empty) {
        print $"❌ Component '($component_id)' not found"
        return
    }

    let source_file = $config.metadata.source_file
    let data = (open $source_file)
    let updated = ($data | upsert $component_id ($data | get $component_id | upsert fixed $fixed))
    $updated | save -f $source_file

    if $fixed {
        print $"🔒 Pinned ($component_id) to version ($config.version)"
    } else {
        print $"🔓 Unpinned ($component_id)"
    }
}