# User Configuration Management Module
# Manages central user configuration file for workspace switching and preferences

use ../utils/nickel_processor.nu [ncl-eval-soft]

# Get path to user config file
export def get-user-config-path [] {
    let user_config_dir = ([$env.HOME "Library" "Application Support" "provisioning"] | path join)

    if not ($user_config_dir | path exists) {
        mkdir $user_config_dir
    }

    $user_config_dir | path join "user_config.yaml"
}

# Create default configuration record content
def create-default-user-config-content [] {
    {
        active_workspace: null,
        workspaces: [],
        preferences: {
            editor: "vim"
            output_format: "yaml"
            confirm_delete: true
            confirm_deploy: true
            default_log_level: "info"
            preferred_provider: "local"
        },
        metadata: {
            created: (date now | format date "%Y-%m-%dT%H:%M:%SZ"),
            last_updated: (date now | format date "%Y-%m-%dT%H:%M:%SZ"),
            version: "1.0.0"
        }
    }
}

# Load user configuration
export def load-user-config [] {
    # Build path with explicit string concatenation
    let config_path_str = $"($env.HOME)/Library/Application Support/provisioning/user_config.yaml"

    # Check if file exists
    let file_exists = ($config_path_str | path exists)

    if not $file_exists {
        # Create directory if needed
        let config_dir = $"($env.HOME)/Library/Application Support/provisioning"
        let dir_exists = ($config_dir | path exists)
        if not $dir_exists {
            mkdir $config_dir
        }
        # Create and save default config file
        # Store default content and write via bash
        let cmd_script = $"
mkdir -p \"($config_dir)\"
cat > \"($config_path_str)\" <<'YAML'
active_workspace: null
workspaces: []
preferences:
  editor: vim
  output_format: yaml
  confirm_delete: true
  confirm_deploy: true
  default_log_level: info
  preferred_provider: local
metadata:
  created: null
  last_updated: null
  version: \"1.0.0\"
YAML
"
        ^bash -c $cmd_script
        return (create-default-user-config-content)
    }

    # Check file type
    let file_type_result = ($config_path_str | path type)
    if $file_type_result != "file" {
        return-default-config "Config path is not a file"
    }

    # Load and parse config file
    let raw_content = (open -r $config_path_str)
    let config = ($raw_content | from yaml)

    # Merge with defaults to ensure all fields exist
    let defaults = (create-default-user-config-content)

    # Return config with defaults filled in for missing fields
    return {
        active_workspace: ($config.active_workspace? | default $defaults.active_workspace)
        workspaces: ($config.workspaces? | default $defaults.workspaces)
        preferences: (
            ($config.preferences? | default {})
            | merge $defaults.preferences
        )
        metadata: ($config.metadata? | default $defaults.metadata)
    }
}

# Return default configuration as fallback
def return-default-config [reason: string] {
    if ($env.PROVISIONING_DEBUG? | default false) {
        print $"(ansi yellow)⚠ Using default config: ($reason)(ansi reset)" | debug
    }

    {
        active_workspace: null,
        workspaces: [],
        preferences: {
            editor: "vim"
            output_format: "yaml"
            confirm_delete: true
            confirm_deploy: true
            default_log_level: "info"
            preferred_provider: "local"
        },
        metadata: {
            created: (date now | format date "%Y-%m-%dT%H:%M:%SZ"),
            last_updated: (date now | format date "%Y-%m-%dT%H:%M:%SZ"),
            version: "1.0.0"
        }
    }
}

# Create default user configuration
export def create-default-user-config [] {
    let config_path = (get-user-config-path)

    let default_config = {
        active_workspace: null,
        workspaces: [],
        preferences: {
            editor: "vim",
            output_format: "yaml",
            confirm_delete: true,
            confirm_deploy: true,
            default_log_level: "info",
            preferred_provider: "local"
        },
        metadata: {
            created: (date now | format date "%Y-%m-%dT%H:%M:%SZ"),
            last_updated: (date now | format date "%Y-%m-%dT%H:%M:%SZ"),
            version: "1.0.0"
        }
    }

    $default_config | to yaml | save -f $config_path
}

# Save user configuration
export def save-user-config [config: record] {
    let config_path = (get-user-config-path)

    # Update last_updated timestamp
    let updated_config = (
        $config | update metadata.last_updated (date now | format date "%Y-%m-%dT%H:%M:%SZ")
    )

    $updated_config | to yaml | save -f $config_path
}

# Get active workspace name
export def get-active-workspace [] {
    let config = (load-user-config)

    if ($config.active_workspace == null) {
        return null
    }

    $config.active_workspace
}

# Get active workspace details
export def get-active-workspace-details [] {
    let config = (load-user-config)

    if ($config.active_workspace == null) {
        return null
    }

    let workspace_name = $config.active_workspace

    # Find workspace in list
    let workspace = ($config.workspaces | where name == $workspace_name | first)

    if ($workspace | is-empty) {
        return null
    }

    $workspace
}

# Set active workspace
export def set-active-workspace [
    workspace_name: string
    workspace_path: string
] {
    let config = (load-user-config)

    # Check if workspace exists in list
    let workspace_exists = ($config.workspaces | where name == $workspace_name | length) > 0

    let updated_config = if $workspace_exists {
        # Update last_used for existing workspace
        $config
        | update workspaces ($config.workspaces | each { |ws|
            if $ws.name == $workspace_name {
                $ws | update last_used (date now | format date "%Y-%m-%dT%H:%M:%SZ")
            } else {
                $ws
            }
        })
        | update active_workspace $workspace_name
    } else {
        # Add new workspace to list
        let new_workspace = {
            name: $workspace_name,
            path: $workspace_path,
            last_used: (date now | format date "%Y-%m-%dT%H:%M:%SZ")
        }

        $config
        | update workspaces ($config.workspaces | append $new_workspace)
        | update active_workspace $workspace_name
    }

    save-user-config $updated_config

    print $"(ansi green)✓(ansi reset) Workspace '($workspace_name)' activated"
}

# List all known workspaces
export def list-workspaces [] {
    let config = (load-user-config)

    if ($config.workspaces | is-empty) {
        return []
    }

    let active_workspace = $config.active_workspace

    # Build list without piping through each to avoid eval block issues
    mut workspace_list = []
    for ws in $config.workspaces {
        let is_active = ($ws.name == $active_workspace)
        let ws_record = {
            name: $ws.name
            path: $ws.path
            active: $is_active
            last_used: $ws.last_used
        }
        $workspace_list = ($workspace_list | append $ws_record)
    }

    $workspace_list
}

# Remove workspace from known list
export def remove-workspace [workspace_name: string] {
    let config = (load-user-config)

    let updated_workspaces = ($config.workspaces | where name != $workspace_name)

    let updated_config = $config | update workspaces $updated_workspaces

    # If removed workspace was active, clear active_workspace
    let final_config = if $config.active_workspace == $workspace_name {
        $updated_config | update active_workspace null
    } else {
        $updated_config
    }

    save-user-config $final_config

    print $"(ansi green)✓(ansi reset) Workspace '($workspace_name)' removed from known list"
}

# Add workspace to known list without activating
export def register-workspace [
    workspace_name: string
    workspace_path: string
] {
    let config = (load-user-config)

    # Check if workspace already exists
    let workspace_exists = ($config.workspaces | where name == $workspace_name | length) > 0

    if $workspace_exists {
        print $"(ansi yellow)⚠(ansi reset) Workspace '($workspace_name)' already registered"
        return
    }

    let new_workspace = {
        name: $workspace_name,
        path: $workspace_path,
        last_used: (date now | format date "%Y-%m-%dT%H:%M:%SZ")
    }

    let updated_config = $config | update workspaces ($config.workspaces | append $new_workspace)

    save-user-config $updated_config

    print $"(ansi green)✓(ansi reset) Workspace '($workspace_name)' registered"
}

# Get user preference
export def get-user-preference [preference_key: string] {
    let config = (load-user-config)

    if ($preference_key in $config.preferences) {
        $config.preferences | get $preference_key
    } else {
        null
    }
}

# Set user preference
export def set-user-preference [
    preference_key: string
    value: any
] {
    let config = (load-user-config)

    let updated_config = $config | update preferences {
        $config.preferences | upsert $preference_key $value
    }

    save-user-config $updated_config

    print $"(ansi green)✓(ansi reset) Preference '($preference_key)' updated to '($value)'"
}

# Validate workspace exists
export def validate-workspace-exists [workspace_name: string] {
    let config = (load-user-config)

    ($config.workspaces | where name == $workspace_name | length) > 0
}

# Get workspace path by name
export def get-workspace-path [workspace_name: string] {
    let config = (load-user-config)

    let workspace = ($config.workspaces | where name == $workspace_name | first)

    if ($workspace | is-empty) {
        return null
    }

    $workspace.path
}

# Get default infrastructure for workspace
export def get-workspace-default-infra [workspace_name: string] {
    let config = (load-user-config)

    # Find workspace in config
    let workspace = ($config.workspaces | where name == $workspace_name | first)

    if ($workspace | is-empty) {
        return null
    }

    # First check user config for default_infra
    let user_infra = ($workspace.default_infra? | default null)
    if ($user_infra | is-not-empty) {
        return $user_infra
    }

    # Fallback: check workspace's provisioning.ncl for current_infra
    let ws_path = (get-workspace-path $workspace_name)
    let ws_config_file = ([$ws_path "config" "provisioning.ncl"] | path join)
    if ($ws_config_file | path exists) {
        let result = (ncl-eval-soft $ws_config_file [] null)
        if ($result | is-not-empty) {
            let current_infra = ($result.current_infra? | default null)
            if ($current_infra | is-not-empty) {
                return $current_infra
            }
        }
    }

    null
}

# Set default infrastructure for workspace
export def set-workspace-default-infra [
    workspace_name: string
    infra_name: string
] {
    let config = (load-user-config)

    # Update workspace entry with default_infra
    mut updated_workspaces = []
    for ws in $config.workspaces {
        if $ws.name == $workspace_name {
            let updated_ws = {
                name: $ws.name
                path: $ws.path
                last_used: (date now | format date "%Y-%m-%dT%H:%M:%SZ")
                default_infra: $infra_name
            }
            $updated_workspaces = ($updated_workspaces | append $updated_ws)
        } else {
            $updated_workspaces = ($updated_workspaces | append $ws)
        }
    }

    # Save updated config
    let updated_config = {
        active_workspace: $config.active_workspace
        workspaces: $updated_workspaces
        preferences: $config.preferences
        metadata: $config.metadata
    }

    save-user-config $updated_config
}
