# Module: Error Handling Utilities
# Purpose: Centralized error handling, error messages, and exception management.
# Dependencies: logging

use ../config/accessor.nu *
use ./logging.nu *
use ./interface.nu [_ansi]

export def throw-error [
    error: string
    text?: string
    context?: string
    --span: record
    --code: int = 1
    --suggestion: string
] {
  #use utils/interface.nu _ansi
  let error = $"\n(_ansi red_bold)($error)(_ansi reset)"
  let msg = ($text | default "this caused an internal error")
  let suggestion = if ($suggestion | is-not-empty) { $"\n💡 Suggestion: (_ansi yellow)($suggestion)(_ansi reset)" } else { "" }

  # Log error for debugging
  if (is-debug-enabled) {
    print $"DEBUG: Error occurred at: (date now | format date '%Y-%m-%d %H:%M:%S')"
    print $"DEBUG: Context: ($context | default 'no context')"
    print $"DEBUG: Error code: ($code)"
  }

  if ($env.PROVISIONING_OUT? | default "" | is-empty)  {
    if $span == null and $context == null {
      error make --unspanned { msg: ( $error + "\n" + $msg + $suggestion) }
    } else if $span != null and (is-metadata-enabled) {
      error make {
        msg: $error
        label: {
          text: $"($msg) (_ansi blue)($context)(_ansi reset)($suggestion)"
          span: $span
        }
      }
    }  else {
      error make --unspanned { msg: ( $error + "\n" + $msg + "\n" + $"(_ansi blue)($context | default "" )(_ansi reset)($suggestion)") }
    }
  } else {
     _print ( $error + "\n" + $msg + "\n" + $"(_ansi blue)($context | default "" )(_ansi reset)($suggestion)")
  }
}

export def safe-execute [
    command: closure
    context: string
    --fallback: closure
] {
    let result = (do $command | complete)
    if $result.exit_code != 0 {
        print $"⚠️  Warning: Error in ($context): ($result.stderr)"
        if ($fallback | is-not-empty) {
            print "🔄 Executing fallback..."
            do $fallback
        } else {
            print $"🛑 Execution failed in ($context)"
            print $"   Error: ($result.stderr)"
        }
    } else {
        $result.stdout
    }
}
