import type { AnsiColorName } from '@simon_he/vue-tui'
import type { Ref } from 'vue'
import type { UiThemeContext } from '../../ui/theme'
import { t } from '#cli/i18n'
import {
  padEndByCells,
  sliceByCells,
  spaces,
  textCellWidth,
  TText,
  wrapByCells,
} from '@simon_he/vue-tui'
import { h } from 'vue'

export function renderCopyToastOverlay(
  opts: Readonly<{
    visible: Ref<boolean>
    text: Ref<string>
    cols: Readonly<{ value: number }> | number
    ui?: UiThemeContext
  }>,
): any[] {
  if (!opts.visible.value) return []

  const raw = String(opts.text.value ?? '').trim()
  if (!raw) return []

  const cols = typeof opts.cols === 'number' ? opts.cols : opts.cols.value

  const isError = /\bfail(?:ed)?\b/i.test(raw) || /\berror\b/i.test(raw)
  const message =
    raw === t('chatPage.toast.copySuccess')
      ? t('copyToast.copiedToClipboard')
      : raw
  const baseText = message

  // Opencode-style: dark background, cyan side bars, left-aligned text.
  const bg = 'blackBright' as const
  // Use dark text on light backgrounds, light text on dark backgrounds
  const isLightTheme =
    opts.ui?.palette?.whiteBright === '#ffffff' &&
    opts.ui?.palette?.blackBright === '#f3f3f3'
  const fg: AnsiColorName = isLightTheme ? 'black' : 'whiteBright'
  const accentBg = isError ? 'redBright' : 'cyanBright'

  const barW = 1
  const paddingX = 3
  const paddingY = 0

  const safeCols = Math.max(0, Math.floor(cols ?? 0))
  const maxToastW = Math.max(22, Math.min(88, safeCols - 4))
  const minToastW = Math.min(28, maxToastW)
  const baseWidth = textCellWidth(baseText) + barW * 2 + paddingX * 2
  const toastW = Math.min(Math.max(baseWidth, minToastW), maxToastW)
  const contentW = Math.max(1, toastW - barW * 2 - paddingX * 2)

  const maxLines = isError ? 3 : 2
  let lines = [...wrapByCells(baseText, contentW)]
  if (lines.length > maxLines) {
    lines = lines.slice(0, maxLines)
    const lastIndex = maxLines - 1
    if (contentW > 1)
      lines[lastIndex] = `${sliceByCells(lines[lastIndex], contentW - 1)}…`
    else lines[lastIndex] = '…'
  }
  const alignedLines = lines.map((line) => {
    const clipped = sliceByCells(line, contentW)
    return padEndByCells(clipped, contentW)
  })

  const toastH = Math.max(1, alignedLines.length) + paddingY * 2
  const toastX = Math.max(2, safeCols - toastW - 2)
  const toastY = 1

  const baseZ = 2100
  return [
    h(TText, {
      key: 'copy-toast-bg',
      x: toastX,
      y: toastY,
      w: toastW,
      h: toastH,
      value: spaces(toastW),
      style: { bg },
      zIndex: baseZ,
    }),
    h(TText, {
      key: 'copy-toast-accent-left',
      x: toastX,
      y: toastY,
      w: barW,
      h: toastH,
      value: spaces(barW),
      style: { bg: accentBg },
      zIndex: baseZ + 1,
    }),
    h(TText, {
      key: 'copy-toast-accent-right',
      x: toastX + toastW - barW,
      y: toastY,
      w: barW,
      h: toastH,
      value: spaces(barW),
      style: { bg: accentBg },
      zIndex: baseZ + 1,
    }),
    h(TText, {
      key: 'copy-toast-text',
      x: toastX + barW + paddingX,
      y: toastY + paddingY,
      w: contentW,
      h: alignedLines.length,
      value: alignedLines.join('\n'),
      style: { fg, bg, bold: true },
      zIndex: baseZ + 2,
    }),
  ]
}
