import { t } from '#cli/i18n'
import { TBox, TDialog, TInput, TText, wrapByCells } from '@simon_he/vue-tui'
import { defineComponent, h, ref, watch } from 'vue'
import { useUiTheme } from '../theme'
import { withFocusedInputTip } from './input-clear-tip'

export const DimSdkCustomProviderModelsDialog = defineComponent({
  name: 'DimSdkCustomProviderModelsDialog',
  props: {
    modelValue: { type: Boolean, required: true },
    w: { type: Number, required: true },
    h: { type: Number, required: true },
    modelsDraft: { type: String, required: true },
    fetching: { type: Boolean, default: false },
  },
  emits: {
    'update:modelValue': (_v: boolean) => true,
    'update:modelsDraft': (_v: string) => true,
    'apply': () => true,
    'fetch': () => true,
    'cancel': () => true,
  },
  setup(props, { emit }) {
    const ui = useUiTheme()
    const focused = ref(false)

    watch(
      () => props.modelValue,
      (open) => {
        focused.value = open
      },
      { immediate: true },
    )

    return () => {
      if (!props.modelValue)
        return null

      const dialogW = Math.max(52, Math.floor(props.w))
      const dialogH = Math.max(14, Math.floor(props.h))
      const innerW = Math.max(0, dialogW - 4)
      const innerH = Math.max(0, dialogH - 4)
      const fieldBoxH = Math.max(5, Math.min(7, innerH - 3))
      const inputH = Math.max(1, fieldBoxH - 2)

      const dialogBg = ui.token('dialog.chrome')?.bg
      const dialogBgStyle = dialogBg ? { bg: dialogBg } : undefined
      const boxStyle = ui.style(['dialog.chrome', 'border.default'])
      const fieldStyle = ui.style(['input.field'], dialogBgStyle)
      const hintStyle = ui.style(['dialog.chrome', 'text.muted'])
      const hintText = props.fetching
        ? t('providerDialogs.modelsDialog.fetching')
        : t('providerDialogs.modelsDialog.hint')
      const hintLines = hintText
        .split('\n')
        .flatMap(line => wrapByCells(line, Math.max(1, innerW)))
        .slice(0, Math.max(1, innerH - fieldBoxH - 1))
      const hintH = Math.max(1, hintLines.length)
      const hintY = Math.max(0, innerH - hintH)

      return h(
        TDialog as any,
        {
          'modelValue': props.modelValue,
          'onUpdate:modelValue': (v: boolean) => emit('update:modelValue', v),
          'w': dialogW,
          'h': dialogH,
          'title': t('providerDialogs.modelsDialog.title'),
          'placement': 'center',
          'padding': 1,
          'backdrop': false,
          'closeOnBackdrop': false,
          'style': ui.style(['dialog.chrome']),
          'buttons': [
            {
              label: t('providerDialogs.modelsDialog.fetch'),
              value: 'fetch',
              kind: 'accent',
            },
            {
              label: t('common.apply'),
              value: 'apply',
              kind: 'primary',
              default: true,
            },
            { label: t('common.cancel'), value: 'cancel', kind: 'muted' },
          ],
          'closeOnConfirm': false,
          'onConfirm': (btn: any) => {
            if (btn?.value === 'apply')
              emit('apply')
            else if (btn?.value === 'fetch')
              emit('fetch')
            else emit('cancel')
          },
          'onClose': () => emit('cancel'),
          'onKeydownCapture': (e: any) => {
            if (e?.key === 'Escape') {
              e.preventDefault?.()
              emit('cancel')
            }
          },
        },
        () => [
          h(
            TBox,
            {
              x: 0,
              y: 0,
              w: innerW,
              h: fieldBoxH,
              border: true,
              title: withFocusedInputTip(
                t('providerDialogs.modelsDialog.modelsTitle'),
                focused.value,
                t('common.inputClearTip'),
              ),
              padding: 0,
              style: boxStyle,
              clear: true,
            },
            () =>
              h(TInput, {
                'x': 0,
                'y': 0,
                'w': Math.max(0, innerW - 2),
                'h': inputH,
                'modelValue': props.modelsDraft,
                'onUpdate:modelValue': (v: string) =>
                  emit('update:modelsDraft', v),
                'placeholder': t(
                  'providerDialogs.modelsDialog.modelsPlaceholder',
                ),
                'cursorToEndOnFirstFocus': true,
                'cursorToEndOnExternalUpdate': true,
                'style': fieldStyle,
                'zIndex': 1002,
                'autoFocus': true,
                'onFocus': () => {
                  focused.value = true
                },
                'onBlur': () => {
                  focused.value = false
                },
              }),
          ),
          h(TText, {
            x: 0,
            y: hintY,
            w: innerW,
            h: hintH,
            wrap: true,
            value: hintLines.join('\n'),
            style: hintStyle,
          }),
        ],
      )
    }
  },
})
