export type DimSdkSlashCommand =
  | Readonly<{ kind: 'none' }>
  | Readonly<{ kind: 'removed'; command: string }>
  | Readonly<{ kind: 'resume' }>
  | Readonly<{ kind: 'theme' }>
  | Readonly<{ kind: 'approvals' }>
  | Readonly<{ kind: 'approvals_invalid_args' }>
  | Readonly<{ kind: 'mcp_settings' }>
  | Readonly<{ kind: 'plugins' }>
  | Readonly<{ kind: 'codex_login' }>
  | Readonly<{ kind: 'connect' }>
  | Readonly<{ kind: 'models' }>
  | Readonly<{ kind: 'language' }>
  | Readonly<{ kind: 'settings' }>
  | Readonly<{ kind: 'sessions' }>
  | Readonly<{ kind: 'timeline' }>
  | Readonly<{ kind: 'trace' }>
  | Readonly<{ kind: 'new' }>
  | Readonly<{ kind: 'redo' }>
  | Readonly<{ kind: 'rename'; title: string }>
  | Readonly<{ kind: 'rename_invalid_args' }>
  | Readonly<{ kind: 'compact' }>
  | Readonly<{ kind: 'skills' }>
  | Readonly<{ kind: 'exit' }>

export function isDimSdkLocalUiSlashCommand(cmd: DimSdkSlashCommand): boolean {
  // These commands are purely local UI actions (no store.send), so they should be allowed even while the
  // model is responding. Keep /compact as non-local because it triggers async store/agent work.
  return (
    cmd.kind !== 'none' &&
    cmd.kind !== 'compact'
  )
}

/**
 * Parse DimSdk TUI slash commands.
 *
 * Input is expected to be trimmed (but we handle whitespace defensively).
 */
export function parseDimSdkSlashCommand(input: string): DimSdkSlashCommand {
  const text = String(input ?? '').trim()
  if (!text.startsWith('/')) return { kind: 'none' }

  // Removed commands we still intercept to avoid accidentally sending them to the model.
  if (
    text === '/?' ||
    text === '/commands' ||
    text === '/help' ||
    text === '/pins' ||
    text === '/pinned' ||
    text === '/pin' ||
    text === '/status' ||
    text === '/retry' ||
    text === '/tool-settings' ||
    text === '/toolsettings'
  ) {
    return { kind: 'removed', command: text }
  }

  if (text === '/theme') return { kind: 'theme' }

  if (text === '/resume') return { kind: 'resume' }

  if (text === '/approvals' || text === '/approval')
    return { kind: 'approvals' }
  if (text.startsWith('/approvals ') || text.startsWith('/approval '))
    return { kind: 'approvals_invalid_args' }

  if (
    text === '/mcp' ||
    text === '/mcp-hub' ||
    text === '/mcphub' ||
    text === '/mcp-settings' ||
    text === '/mcpsettings'
  )
    return { kind: 'mcp_settings' }

  if (text === '/plugins' || text === '/plugin')
    return { kind: 'plugins' }

  if (text === '/connect') return { kind: 'connect' }

  if (text === '/models') return { kind: 'models' }

  if (text === '/language' || text === '/lang' || text === '/locale')
    return { kind: 'language' }

  if (text === '/settings' || text === '/config') return { kind: 'settings' }

  if (text === '/sessions') return { kind: 'sessions' }

  if (text === '/timeline' || text === '/tl') return { kind: 'timeline' }

  if (text === '/trace') return { kind: 'trace' }

  if (text === '/new') return { kind: 'new' }

  if (text === '/redo') return { kind: 'redo' }

  if (text === '/rename') return { kind: 'rename_invalid_args' }
  if (text.startsWith('/rename ')) {
    const title = text.slice('/rename '.length).trim()
    if (!title) return { kind: 'rename_invalid_args' }
    return { kind: 'rename', title }
  }

  if (text === '/compact') return { kind: 'compact' }

  if (text === '/skills' || text === '/skill') return { kind: 'skills' }

  if (text === '/exit') return { kind: 'exit' }
  return { kind: 'none' }
}
