import type { VNode } from 'vue'
import type { UiThemeContext } from '../../theme'
import type { SessionsDialogViewModel } from './view-model'
import { t } from '#cli/i18n'
import {
  sliceByCells,
  TDialog,
  textCellWidth,
  TSelect,
  TText,
} from '@simon_he/vue-tui'
import { h } from 'vue'
import { clamp } from './view-model'

export type SessionsDialogAction =
  | 'open'
  | 'delete'
  | 'scope'
  | 'refresh'
  | 'close'

export function renderSessionsDialog(
  opts: Readonly<{
    modelValue: boolean
    deleteArmed: boolean
    cwdOnly: boolean
    vm: SessionsDialogViewModel
    ui: UiThemeContext
    hintText: string
    focusText: string
    onUpdateModelValue: (v: boolean) => void
    onUpdateSelectedIndex: (v: number) => void
    onUpdateCwdOnly: (v: boolean) => void
    onOpen: () => void
    onDelete: () => void
    onRefresh: () => void
    onKeydownCapture: (e: any) => void
    onListFocus: () => void
    onListBlur: () => void
    onConfirm: (btn: any) => void
    onClose: () => void
  }>,
): VNode | null {
  if (!opts.modelValue) return null

  const dialogBg = opts.ui.token('dialog.chrome')?.bg
  const dialogBgStyle = dialogBg ? { bg: dialogBg } : undefined
  const activeStyle = opts.ui.style(['chip.meta'], dialogBgStyle)
  const highlightStyle = opts.ui.style(['select.item'])
  const hintStyle = opts.ui.style(['dialog.chrome', 'text.muted'])
  const focusStyle = opts.ui.style(['dialog.chrome', 'accent.cyan'])
  const options = opts.vm.options.map((option) =>
    option.isActive ? { ...option, style: activeStyle } : option,
  )
  const focusText = String(opts.focusText ?? '').trim()
  const hintText = String(opts.hintText ?? '').trim()
  const focusW = focusText ? textCellWidth(focusText) : 0
  const hintW = Math.max(0, opts.vm.innerW - (focusW ? focusW + 1 : 0))
  const hintValue = hintW > 0 ? sliceByCells(hintText, hintW) : ''

  return h(
    TDialog as any,
    {
      modelValue: opts.modelValue,
      'onUpdate:modelValue': (v: boolean) => opts.onUpdateModelValue(v),
      onKeydownCapture: (e: any) => opts.onKeydownCapture(e),
      w: opts.vm.w,
      h: opts.vm.h,
      title: opts.vm.title,
      placement: 'center',
      backdrop: false,
      padding: 1,
      style: opts.ui.style(['dialog.chrome']),
      closeOnConfirm: false,
      buttons: [
        {
          label: t('sessionsDialog.buttons.open'),
          value: 'open',
          kind: 'primary',
          default: !opts.deleteArmed,
        },
        {
          label: opts.deleteArmed
            ? t('sessionsDialog.buttons.deleteConfirm')
            : t('sessionsDialog.buttons.delete'),
          value: 'delete',
          kind: 'danger',
          default: opts.deleteArmed,
        },
        {
          label: t('sessionsDialog.buttons.scope', {
            scope: opts.cwdOnly
              ? t('sessionsDialog.buttons.scopeCwd')
              : t('sessionsDialog.buttons.scopeAll'),
          }),
          value: 'scope',
        },
        { label: t('sessionsDialog.buttons.refresh'), value: 'refresh' },
        { label: t('common.close'), value: 'close' },
      ],
      onConfirm: (btn: any) => opts.onConfirm(btn),
      onClose: () => opts.onClose(),
    },
    () => [
      h(TText, {
        x: 0,
        y: 0,
        w: opts.vm.innerW,
        value: opts.vm.headerText,
        style: opts.ui.style(['dialog.chrome', 'text.muted']),
      }),
      hintValue
        ? h(TText, { x: 0, y: 1, w: hintW, value: hintValue, style: hintStyle })
        : null,
      focusText
        ? h(TText, {
            x: Math.max(0, opts.vm.innerW - focusW),
            y: 1,
            w: focusW,
            value: focusText,
            style: focusStyle,
          })
        : null,
      h(TSelect, {
        x: 0,
        y: opts.vm.listY,
        w: opts.vm.innerW,
        h: opts.vm.listH,
        options: options as any,
        modelValue: opts.vm.selectedOptionIndex,
        'onUpdate:modelValue': (v: number) => {
          const nextIdx = clamp(
            opts.vm.offset + v,
            0,
            Math.max(0, opts.vm.totalSessions - 1),
          )
          opts.onUpdateSelectedIndex(nextIdx)
        },
        onKeydownCapture: opts.onKeydownCapture,
        onChange: (v: string | null) => {
          if (!v) return
          opts.onOpen()
        },
        onFocus: () => opts.onListFocus(),
        onBlur: () => opts.onListBlur(),
        autoFocus: true,
        style: opts.ui.style(['dialog.chrome', 'text.primary']),
        highlightStyle: highlightStyle,
        // Keep this local to the dialog stacking context so higher-priority dialogs
        // (e.g. SwitchSessionDialog) can stay above SessionsDialog.
        zIndex: 5,
      }),
    ],
  )
}
