import type { PropType } from 'vue'
import { t } from '#cli/i18n'
import {
  createNodePathPickerProvider,
  resolveUserPath,
  TDialog,
  TPathPicker,
  TText,
} from '@simon_he/vue-tui'
import { defineComponent, h, watch } from 'vue'
import { useUiTheme } from '../theme'

export const DimSdkPathPickerDialog = defineComponent({
  name: 'DimSdkPathPickerDialog',
  props: {
    modelValue: { type: Boolean, required: true },
    w: { type: Number, required: true },
    h: { type: Number, required: true },
    title: { type: String, required: true },
    workspace: { type: String, required: true },
    mode: { type: String as PropType<'directory' | 'file'>, required: true },
    query: { type: String, required: true },
    placeholder: { type: String, required: true },
  },
  emits: {
    'update:modelValue': (_v: boolean) => true,
    'update:query': (_v: string) => true,
    invalid: (_reason: string) => true,
    select: (_absPath: string) => true,
    close: () => true,
  },
  setup(props, { emit }) {
    const ui = useUiTheme()
    const baseProvider = createNodePathPickerProvider()
    let preferActiveSelection = false

    function clearPreferActiveSelection(): void {
      preferActiveSelection = false
    }

    function markPreferActiveSelection(e: any): void {
      const key = e?.key
      if (key === 'ArrowUp' || key === 'ArrowDown') {
        preferActiveSelection = true
        return
      }
      if (
        (e?.ctrlKey || e?.metaKey) &&
        !e?.altKey &&
        (key === 'p' || key === 'P' || key === 'n' || key === 'N')
      ) {
        preferActiveSelection = true
      }
    }

    const provider = {
      listDir: baseProvider.listDir,
      suggest: async (info: any) => {
        return baseProvider.suggest
          ? baseProvider.suggest(info)
          : {
              baseDirAbs: props.workspace,
              dirPrefix: '',
              query: '',
              suggestions: [],
            }
      },
      resolvePath: async (workspaceAbs: string, input: string) => {
        if (baseProvider.resolvePath)
          return baseProvider.resolvePath(workspaceAbs, input)
        return resolveUserPath(workspaceAbs, input)
      },
      stat: async (absPath: string) => {
        if (preferActiveSelection) {
          const typedAbs = baseProvider.resolvePath
            ? await baseProvider.resolvePath(props.workspace, props.query)
            : resolveUserPath(props.workspace, props.query)
          if (absPath === typedAbs) {
            preferActiveSelection = false
            return { exists: false, kind: 'other' as const }
          }
        }
        return baseProvider.stat(absPath)
      },
    }

    watch(
      () => props.modelValue,
      (next) => {
        if (!next) clearPreferActiveSelection()
      },
    )

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

      const innerW = Math.max(0, props.w - 2)
      const innerH = Math.max(0, props.h - 2)
      const dialogBg = ui.token('dialog.chrome')?.bg
      const dialogBgStyle = dialogBg ? { bg: dialogBg } : undefined

      return h(
        TDialog as any,
        {
          modelValue: props.modelValue,
          'onUpdate:modelValue': (v: boolean) => emit('update:modelValue', v),
          w: props.w,
          h: props.h,
          title: props.title,
          placement: 'center',
          backdrop: false,
          padding: 1,
          style: ui.style(['dialog.chrome']),
          onClose: () => {
            clearPreferActiveSelection()
            emit('update:modelValue', false)
            emit('close')
          },
        },
        () => [
          h(TText, {
            x: 0,
            y: 0,
            w: innerW,
            value: t('pathPickerDialog.hint'),
            style: ui.style(['dialog.chrome', 'text.muted']),
          }),
          h(TPathPicker as any, {
            x: 0,
            y: 2,
            w: innerW,
            h: Math.max(0, innerH - 3),
            workspace: props.workspace,
            mode: props.mode,
            provider: provider,
            modelValue: props.query,
            'onUpdate:modelValue': (v: string) => {
              clearPreferActiveSelection()
              emit('update:query', v)
            },
            placeholder: props.placeholder,
            autoFocus: true,
            style: ui.style(['input.field'], dialogBgStyle),
            onKeydown: (e: any) => {
              markPreferActiveSelection(e)
              if (e?.key !== 'Escape') return
              // Close the dialog even when the search input's own prompt handling consumes Esc.
              e?.preventDefault?.()
              clearPreferActiveSelection()
              emit('update:modelValue', false)
              emit('close')
            },
            onInvalid: (info: any) => {
              clearPreferActiveSelection()
              emit('invalid', String(info?.reason ?? 'invalid'))
            },
            onSelect: (absPath: string) => {
              clearPreferActiveSelection()
              emit('select', absPath)
            },
          }),
        ],
      )
    }
  },
})
