import { sanitizeTerminalText } from './chat/sanitize-terminal-text'

type StdoutLike
  = | Readonly<{ isTTY?: boolean, write: (chunk: string) => unknown }>
    | null
    | undefined
type EnvLike = Readonly<Record<string, string | undefined>> | null | undefined
const ESC = '\u001B'
const BEL = '\u0007'

function readEnv(opts?: Readonly<{ env?: EnvLike }>): EnvLike {
  if (opts?.env)
    return opts.env
  const proc: any = (globalThis as any).process
  return proc?.env
}

function isAppleTerminal(opts?: Readonly<{ env?: EnvLike }>): boolean {
  const env = readEnv(opts)
  const termProgram = String(env?.TERM_PROGRAM ?? '').trim()
  const term = String(env?.TERM ?? '').trim()
  return (
    termProgram === 'Apple_Terminal'
    || term === 'nsterm'
    || term === 'nsterm-256color'
  )
}

export function supportsTerminalTitleStack(
  opts?: Readonly<{ env?: EnvLike }>,
): boolean {
  return !isAppleTerminal(opts)
}

export function sanitizeTerminalTitle(
  input: unknown,
  maxLen: number = 120,
): string {
  const cleaned = sanitizeTerminalText(String(input ?? ''))
    .replace(/[\r\n]+/g, ' ')
    .replace(/\s+/g, ' ')
    .trim()

  if (!cleaned)
    return ''

  const n = Math.max(0, Math.floor(maxLen))
  if (n > 0 && cleaned.length > n)
    return `${cleaned.slice(0, Math.max(0, n - 1))}…`

  return cleaned
}

export function setTerminalTitle(
  title: unknown,
  opts?: Readonly<{
    stdout?: StdoutLike
    force?: boolean
    maxLen?: number
    env?: EnvLike
  }>,
): void {
  const proc: any = (globalThis as any).process
  const stdout: StdoutLike = opts?.stdout ?? proc?.stdout
  if (!stdout || typeof stdout.write !== 'function')
    return

  if (!opts?.force && !stdout.isTTY)
    return

  const safe = sanitizeTerminalTitle(title, opts?.maxLen ?? 120)
  if (!safe)
    return

  if (isAppleTerminal(opts)) {
    // Terminal.app advertises title set/clear via OSC 2 + BEL in terminfo (`tsl`/`dsl`).
    stdout.write(`${ESC}]2;${safe}${BEL}`)
    return
  }

  stdout.write(`${ESC}]0;${safe}${ESC}\\`)
}

export function saveTerminalTitle(
  opts?: Readonly<{ stdout?: StdoutLike, force?: boolean, env?: EnvLike }>,
): void {
  const proc: any = (globalThis as any).process
  const stdout: StdoutLike = opts?.stdout ?? proc?.stdout
  if (!stdout || typeof stdout.write !== 'function')
    return

  if (!opts?.force && !stdout.isTTY)
    return

  if (!supportsTerminalTitleStack(opts))
    return

  // xterm-style window op: save icon/window title on the terminal stack.
  stdout.write(`${ESC}[22;0t`)
}

export function restoreTerminalTitle(
  opts?: Readonly<{ stdout?: StdoutLike, force?: boolean, env?: EnvLike }>,
): void {
  const proc: any = (globalThis as any).process
  const stdout: StdoutLike = opts?.stdout ?? proc?.stdout
  if (!stdout || typeof stdout.write !== 'function')
    return

  if (!opts?.force && !stdout.isTTY)
    return

  if (!supportsTerminalTitleStack(opts)) {
    // Terminal.app does not reliably honor xterm's title save/restore stack.
    // Clearing the explicit title lets it fall back to the profile/shell-managed default.
    stdout.write(`${ESC}]2;${BEL}`)
    return
  }

  // xterm-style window op: restore the previously saved icon/window title.
  stdout.write(`${ESC}[23;0t`)
}
