/**
 * Argv preprocessing extracted from main()
 *
 * Handles rewriting process.argv for special modes:
 * - cc:// direct connect URLs
 * - assistant mode
 * - SSH remote sessions
 * - Deep link URIs
 */

import { feature } from 'bun:bundle'

// Set by early argv processing when `sandcode open <url>` is detected (interactive mode only)
export type PendingConnect = {
  url: string | undefined
  authToken: string | undefined
  dangerouslySkipPermissions: boolean
}

export const pendingConnect: PendingConnect | undefined = feature('DIRECT_CONNECT')
  ? { url: undefined, authToken: undefined, dangerouslySkipPermissions: false }
  : undefined

// Set by early argv processing when `sandcode assistant [sessionId]` is detected
export type PendingAssistantChat = {
  sessionId?: string
  discover: boolean
}

export const pendingAssistantChat: PendingAssistantChat | undefined = feature('KAIROS')
  ? { sessionId: undefined, discover: false }
  : undefined

// `sandcode ssh <host> [dir]`
export type PendingSSH = {
  host: string | undefined
  cwd: string | undefined
  permissionMode: string | undefined
  dangerouslySkipPermissions: boolean
  local: boolean
  extraCliArgs: string[]
}

export const pendingSSH: PendingSSH | undefined = feature('SSH_REMOTE')
  ? {
      host: undefined,
      cwd: undefined,
      permissionMode: undefined,
      dangerouslySkipPermissions: false,
      local: false,
      extraCliArgs: [],
    }
  : undefined

/**
 * Rewrite argv for cc:// URLs, assistant mode, SSH, and deep links.
 * Must run before Commander parses argv.
 */
export async function preprocessArgv(): Promise<void> {
  // Check for cc:// or cc+unix:// URL in argv
  if (feature('DIRECT_CONNECT') && pendingConnect) {
    const rawCliArgs = process.argv.slice(2)
    const ccIdx = rawCliArgs.findIndex(a => a.startsWith('cc://') || a.startsWith('cc+unix://'))
    if (ccIdx !== -1) {
      const ccUrl = rawCliArgs[ccIdx]!
      const { parseConnectUrl } = await import('../server/parseConnectUrl.js')
      const parsed = parseConnectUrl(ccUrl)
      pendingConnect.dangerouslySkipPermissions = rawCliArgs.includes(
        '--dangerously-skip-permissions',
      )
      if (rawCliArgs.includes('-p') || rawCliArgs.includes('--print')) {
        const stripped = rawCliArgs.filter((_, i) => i !== ccIdx)
        const dspIdx = stripped.indexOf('--dangerously-skip-permissions')
        if (dspIdx !== -1) stripped.splice(dspIdx, 1)
        process.argv = [process.argv[0]!, process.argv[1]!, 'open', ccUrl, ...stripped]
      } else {
        pendingConnect.url = parsed.serverUrl
        pendingConnect.authToken = parsed.authToken
        const stripped = rawCliArgs.filter((_, i) => i !== ccIdx)
        const dspIdx = stripped.indexOf('--dangerously-skip-permissions')
        if (dspIdx !== -1) stripped.splice(dspIdx, 1)
        process.argv = [process.argv[0]!, process.argv[1]!, ...stripped]
      }
    }
  }

  // Handle deep link URIs early
  if (feature('LODESTONE')) {
    const handleUriIdx = process.argv.indexOf('--handle-uri')
    if (handleUriIdx !== -1 && process.argv[handleUriIdx + 1]) {
      const { enableConfigs } = await import('../utils/config.js')
      enableConfigs()
      const uri = process.argv[handleUriIdx + 1]!
      const { handleDeepLinkUri } = await import('../utils/deepLink/protocolHandler.js')
      const exitCode = await handleDeepLinkUri(uri)
      process.exit(exitCode)
    }

    if (
      process.platform === 'darwin' &&
      process.env.__CFBundleIdentifier === 'com.anthropic.sandcode-url-handler'
    ) {
      const { enableConfigs } = await import('../utils/config.js')
      enableConfigs()
      const { handleUrlSchemeLaunch } = await import('../utils/deepLink/protocolHandler.js')
      const urlSchemeResult = await handleUrlSchemeLaunch()
      process.exit(urlSchemeResult ?? 1)
    }
  }

  // `sandcode assistant [sessionId]`
  if (feature('KAIROS') && pendingAssistantChat) {
    const rawArgs = process.argv.slice(2)
    if (rawArgs[0] === 'assistant') {
      const nextArg = rawArgs[1]
      if (nextArg && !nextArg.startsWith('-')) {
        pendingAssistantChat.sessionId = nextArg
        rawArgs.splice(0, 2)
        process.argv = [process.argv[0]!, process.argv[1]!, ...rawArgs]
      } else if (!nextArg) {
        pendingAssistantChat.discover = true
        rawArgs.splice(0, 1)
        process.argv = [process.argv[0]!, process.argv[1]!, ...rawArgs]
      }
    }
  }

  // `sandcode ssh <host> [dir]`
  if (feature('SSH_REMOTE') && pendingSSH) {
    const rawCliArgs = process.argv.slice(2)
    if (rawCliArgs[0] === 'ssh') {
      const localIdx = rawCliArgs.indexOf('--local')
      if (localIdx !== -1) {
        pendingSSH.local = true
        rawCliArgs.splice(localIdx, 1)
      }
      const dspIdx = rawCliArgs.indexOf('--dangerously-skip-permissions')
      if (dspIdx !== -1) {
        pendingSSH.dangerouslySkipPermissions = true
        rawCliArgs.splice(dspIdx, 1)
      }
      const pmIdx = rawCliArgs.indexOf('--permission-mode')
      if (pmIdx !== -1 && rawCliArgs[pmIdx + 1] && !rawCliArgs[pmIdx + 1]!.startsWith('-')) {
        pendingSSH.permissionMode = rawCliArgs[pmIdx + 1]
        rawCliArgs.splice(pmIdx, 2)
      }
      const pmEqIdx = rawCliArgs.findIndex(a => a.startsWith('--permission-mode='))
      if (pmEqIdx !== -1) {
        pendingSSH.permissionMode = rawCliArgs[pmEqIdx]!.split('=')[1]
        rawCliArgs.splice(pmEqIdx, 1)
      }
      const extractFlag = (
        flag: string,
        opts: { hasValue?: boolean; as?: string } = {},
      ) => {
        const i = rawCliArgs.indexOf(flag)
        if (i !== -1) {
          pendingSSH.extraCliArgs.push(opts.as ?? flag)
          const val = rawCliArgs[i + 1]
          if (opts.hasValue && val && !val.startsWith('-')) {
            pendingSSH.extraCliArgs.push(val)
            rawCliArgs.splice(i, 2)
          } else {
            rawCliArgs.splice(i, 1)
          }
        }
        const eqI = rawCliArgs.findIndex(a => a.startsWith(`${flag}=`))
        if (eqI !== -1) {
          pendingSSH.extraCliArgs.push(opts.as ?? flag, rawCliArgs[eqI]!.slice(flag.length + 1))
          rawCliArgs.splice(eqI, 1)
        }
      }
      extractFlag('-c', { as: '--continue' })
      extractFlag('--continue')
      extractFlag('--resume', { hasValue: true })
      extractFlag('--model', { hasValue: true })
    }
    if (rawCliArgs[0] === 'ssh' && rawCliArgs[1] && !rawCliArgs[1].startsWith('-')) {
      pendingSSH.host = rawCliArgs[1]
      let consumed = 2
      if (rawCliArgs[2] && !rawCliArgs[2].startsWith('-')) {
        pendingSSH.cwd = rawCliArgs[2]
        consumed = 3
      }
      const rest = rawCliArgs.slice(consumed)

      if (rest.includes('-p') || rest.includes('--print')) {
        process.stderr.write(
          'Error: headless (-p/--print) mode is not supported with sandcode ssh\n',
        )
        const { gracefulShutdownSync } = await import('src/utils/gracefulShutdown.js')
        gracefulShutdownSync(1)
        return
      }

      process.argv = [process.argv[0]!, process.argv[1]!, ...rest]
    }
  }
}
