import type { VNode } from 'vue'
import type { UiThemeContext } from '../../theme'
import { TBox, TDialog, TSelect, TText } from '@simon_he/vue-tui'
import { h } from 'vue'
import {
  computeLanguageDialogLayout,
  getLanguageDialogStrings,
} from './view-model'

export type LanguageDialogProps = Readonly<{
  modelValue: boolean
  w: number
  h: number
  backdrop?: boolean
  locale: string
}>

export type LanguageDialogEmits = Readonly<{
  updateModelValue: (v: boolean) => void
  updateLocale: (v: string) => void
  apply: () => void
  cancel: () => void
}>

type KeydownEventLike = Readonly<{
  key?: string
  preventDefault?: () => void
  stopPropagation?: () => void
}>

type ConfirmButtonLike = Readonly<{ value?: string }>

export function renderLanguageDialog(
  props: LanguageDialogProps,
  emit: LanguageDialogEmits,
  ui: UiThemeContext,
): VNode | null {
  if (!props.modelValue) return null

  const layout = computeLanguageDialogLayout({ w: props.w, h: props.h })
  const strings = getLanguageDialogStrings()

  const dialogBg = ui.token('dialog.chrome')?.bg
  const dialogBgStyle = dialogBg ? { bg: dialogBg } : undefined
  const chromeStyle = ui.style(['dialog.chrome'])
  const bodyStyle = chromeStyle
  const hintStyle = ui.style(['dialog.chrome', 'text.muted'])
  const boxStyle = ui.style(['dialog.chrome', 'dialog.chrome'])
  const fieldStyle = ui.style(['dialog.chrome', 'text.primary'], dialogBgStyle)
  const highlightStyle = ui.style(['select.item'])

  const localeOptions = [strings.languageEnglish, strings.languageChinese]
  const localeValues = ['en', 'zh-CN']
  const localeIndex = Math.max(0, localeValues.indexOf(props.locale))

  const topHintNode = layout.showHint
    ? h(TText, {
        x: 0,
        y: 0,
        w: layout.innerW,
        value: strings.hint,
        style: hintStyle,
      })
    : null

  return h(
    TDialog as any,
    {
      modelValue: props.modelValue,
      'onUpdate:modelValue': (v: boolean) => emit.updateModelValue(v),
      onKeydownCapture: (e: KeydownEventLike) => {
        if (e?.key === 'Escape') {
          e.preventDefault?.()
          e.stopPropagation?.()
          emit.cancel()
          emit.updateModelValue(false)
        }
      },
      w: layout.dialogW,
      h: layout.dialogH,
      title: strings.title,
      placement: 'center',
      backdrop: Boolean(props.backdrop),
      closeOnBackdrop: false,
      padding: 1,
      style: chromeStyle,
      buttons: [
        {
          label: strings.apply,
          value: 'apply',
          kind: 'primary',
          default: true,
        },
        { label: strings.cancel, value: 'cancel' },
      ],
      onConfirm: (btn: ConfirmButtonLike | null | undefined) => {
        if (btn?.value === 'apply') emit.apply()
        else emit.cancel()
      },
      onClose: () => emit.cancel(),
    },
    () => [
      h(TText, {
        x: 0,
        y: 0,
        w: layout.innerW,
        h: layout.contentH,
        value: '',
        style: bodyStyle,
      }),
      topHintNode,
      h(
        TBox,
        {
          x: 0,
          y: layout.languageY,
          w: layout.innerW,
          h: layout.fieldBoxH,
          border: true,
          title: strings.languageTitle,
          padding: 0,
          style: boxStyle,
          clear: true,
        },
        () =>
          h(TSelect, {
            x: 0,
            y: 0,
            w: Math.max(0, layout.innerW - 2),
            h: layout.inputH,
            options: [...localeOptions],
            modelValue: localeIndex,
            'onUpdate:modelValue': (v: number) => {
              const idx = Math.max(0, Math.min(localeValues.length - 1, v))
              emit.updateLocale(localeValues[idx] ?? 'en')
            },
            style: fieldStyle,
            highlightStyle: highlightStyle,
            autoFocus: true,
            zIndex: 1002,
          }),
      ),
    ],
  )
}
