/**
 * Frontend-side variable substitution for display during navigation.
 *
 * - [VAR:name] → replaced with variables[name]
 * - [USER_INPUT:prompt] → replaced with variables[prompt]
 * - [SAVE_AS:name] → removed from display
 */

export interface UnresolvedVariable {
  variableName: string
  token: string // e.g. "[VAR:server_name]"
}

export interface ResolveResult {
  text: string
  unresolvedVariables: UnresolvedVariable[]
}

/**
 * Resolve variables in text, replacing tokens with values.
 * Missing/empty values are replaced with "N/A".
 */
export function resolveVariables(text: string, variables: Record<string, string>): string {
  // Replace [VAR:name] — empty/missing values show "N/A"
  let result = text.replace(/\[VAR:([^\]]+)\]/g, (_, name) => {
    const key = name.trim()
    const value = variables[key]
    return value && value.trim() ? value : 'N/A'
  })

  // Replace [USER_INPUT:prompt]
  result = result.replace(/\[USER_INPUT:([^\]]+)\]/g, (_, prompt) => {
    const key = prompt.trim()
    const value = variables[key]
    return value && value.trim() ? value : 'N/A'
  })

  // Remove [SAVE_AS:name]
  result = result.replace(/\[SAVE_AS:[^\]]+\]/g, '')

  return result
}

/**
 * Resolve variables but also return info about which variables are unresolved.
 * Unresolved variables are left as their original tokens in the text (not replaced with N/A).
 */
export function resolveVariablesWithStatus(text: string, variables: Record<string, string>): ResolveResult {
  const unresolvedVariables: UnresolvedVariable[] = []

  // Replace [VAR:name] — resolved values get substituted, unresolved stay as tokens
  let result = text.replace(/\[VAR:([^\]]+)\]/g, (match, name) => {
    const key = name.trim()
    const value = variables[key]
    if (value && value.trim()) {
      return value
    }
    unresolvedVariables.push({ variableName: key, token: match })
    return match // Keep original token for inline prompt rendering
  })

  // Replace [USER_INPUT:prompt]
  result = result.replace(/\[USER_INPUT:([^\]]+)\]/g, (match, prompt) => {
    const key = prompt.trim()
    const value = variables[key]
    if (value && value.trim()) {
      return value
    }
    unresolvedVariables.push({ variableName: key, token: match })
    return match
  })

  // Remove [SAVE_AS:name]
  result = result.replace(/\[SAVE_AS:[^\]]+\]/g, '')

  return { text: result, unresolvedVariables }
}

/**
 * Extract all [USER_INPUT:prompt] tokens from text.
 * Returns array of prompt strings.
 */
export function extractUserInputPrompts(text: string): string[] {
  const prompts: string[] = []
  const re = /\[USER_INPUT:([^\]]+)\]/g
  let match
  while ((match = re.exec(text)) !== null) {
    const prompt = match[1].trim()
    if (!prompts.includes(prompt)) {
      prompts.push(prompt)
    }
  }
  return prompts
}

/**
 * Check if text contains any variable tokens.
 */
export function hasVariableTokens(text: string): boolean {
  return /\[(USER_INPUT|VAR|SAVE_AS):[^\]]+\]/.test(text)
}
