/**
 * Tool approval mode picker dialog.
 *
 * This dialog configures how the TUI handles tool permission approvals:
 * - `auto`: auto-approve all tools (no prompts).
 * - `normal`: auto-approve read-only tools, prompt for write/execute.
 * - `strict`: prompt for every tool call.
 */

import type { ToolApprovalsMode } from '#cli/core/model'
import type { PropType } from 'vue'
import { t } from '#cli/i18n'
import { TDialog, TText } from '@simon_he/vue-tui'
import { defineComponent, h, ref, watch } from 'vue'
import { useUiTheme } from '../theme'
import { clamp } from '../utils/math'

// Estimate wrapped line count based on text length and terminal width
function estimateLines(text: string, width: number): number {
  const avgCharWidth = 1
  const charsPerLine = Math.max(20, Math.floor(width / avgCharWidth))
  return Math.max(1, Math.ceil(text.length / charsPerLine))
}

export const DimSdkToolApprovalsDialog = defineComponent({
  name: 'DimSdkToolApprovalsDialog',
  props: {
    modelValue: { type: Boolean, required: true },
    mode: { type: String as PropType<ToolApprovalsMode>, required: true },
    w: { type: Number, required: true },
    h: { type: Number, required: true },
  },
  emits: {
    'update:modelValue': (_v: boolean) => true,
    select: (_v: ToolApprovalsMode) => true,
  },
  setup(props, { emit }) {
    const ui = useUiTheme()

    const focusedButtonIndex = ref(0)

    function defaultButtonIndex(mode: ToolApprovalsMode): number {
      if (mode === 'auto') return 0
      if (mode === 'normal') return 1
      if (mode === 'strict') return 2
      return 1
    }

    watch(
      [() => props.modelValue, () => props.mode],
      ([open]) => {
        if (!open) return
        focusedButtonIndex.value = defaultButtonIndex(props.mode)
      },
      { immediate: true },
    )

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

      const w = Math.max(0, props.w - 4) // border + padding
      const dialogBg = ui.token('dialog.chrome')?.bg
      const dialogBgStyle = dialogBg ? { bg: dialogBg } : undefined
      const highlight = ui.style(['select.item'], dialogBgStyle)
      const tipStyle = ui.style(['dialog.chrome', 'text.muted'])
      const descStyle = ui.style(['dialog.chrome', 'text.muted'])

      const buttons = [
        { label: t('toolApprovalsDialog.useAuto'), value: 'auto' as const },
        { label: t('toolApprovalsDialog.useNormal'), value: 'normal' as const },
        { label: t('toolApprovalsDialog.useStrict'), value: 'strict' as const },
        { label: t('toolApprovalsDialog.close'), value: 'close' as const },
      ]

      const idx = clamp(focusedButtonIndex.value, 0, buttons.length - 1)
      const focusedValue = buttons[idx]?.value ?? 'normal'

      const focusedTitle =
        focusedValue === 'auto'
          ? t('toolApprovalsDialog.focusedTitleAuto')
          : focusedValue === 'normal'
            ? t('toolApprovalsDialog.focusedTitleNormal')
            : focusedValue === 'strict'
              ? t('toolApprovalsDialog.focusedTitleStrict')
              : t('toolApprovalsDialog.focusedTitleClose')

      const focusedDesc =
        focusedValue === 'auto'
          ? t('toolApprovalsDialog.focusedDescAuto')
          : focusedValue === 'normal'
            ? t('toolApprovalsDialog.focusedDescNormal')
            : focusedValue === 'strict'
              ? t('toolApprovalsDialog.focusedDescStrict')
              : t('toolApprovalsDialog.focusedDescClose')

      // Calculate layout dynamically based on content
      const currentY = 0
      const titleY = currentY + 2
      const descLines = estimateLines(focusedDesc, w)
      const descHeight = descLines
      const descY = titleY + 1
      const tipHeight = 2
      const tipY = descY + descHeight + 1
      // Calculate required content height (before padding and border)
      const contentHeight = tipY + tipHeight
      // Add padding (2) and border (2) to get dialog height
      const dialogHeight = Math.max(props.h, contentHeight + 4)

      return h(
        TDialog as any,
        {
          modelValue: props.modelValue,
          'onUpdate:modelValue': (v: boolean) => emit('update:modelValue', v),
          onKeydownCapture: (e: any) => {
            if (e?.key === 'Escape') {
              e.preventDefault?.()
              e.stopPropagation?.()
              emit('update:modelValue', false)
              return
            }
            if (
              typeof e?.key === 'string' &&
              e.key.length === 1 &&
              !e.ctrlKey &&
              !e.metaKey &&
              !e.altKey
            ) {
              e.preventDefault?.()
              e.stopPropagation?.()
            }
          },
          onKeydown: (e: any) => {
            if (e?.key !== 'ArrowLeft' && e?.key !== 'ArrowRight') return
            const dir = e.key === 'ArrowLeft' ? -1 : 1
            const len = Math.max(1, buttons.length)
            focusedButtonIndex.value =
              (focusedButtonIndex.value + dir + len) % len
          },
          w: props.w,
          h: dialogHeight,
          title: t('toolApprovalsDialog.title'),
          placement: 'center',
          backdrop: false,
          padding: 1,
          style: ui.style(['dialog.chrome']),
          buttons: [
            {
              label: t('toolApprovalsDialog.useAuto'),
              value: 'auto',
              kind: props.mode === 'auto' ? 'primary' : undefined,
              default: props.mode === 'auto',
            },
            {
              label: t('toolApprovalsDialog.useNormal'),
              value: 'normal',
              kind: props.mode === 'normal' ? 'primary' : undefined,
              default: props.mode === 'normal',
            },
            {
              label: t('toolApprovalsDialog.useStrict'),
              value: 'strict',
              kind: props.mode === 'strict' ? 'primary' : undefined,
              default: props.mode === 'strict',
            },
            { label: t('toolApprovalsDialog.close'), value: 'close' },
          ],
          onConfirm: (btn: any) => {
            if (btn?.value === 'auto') emit('select', 'auto')
            else if (btn?.value === 'normal') emit('select', 'normal')
            else if (btn?.value === 'strict') emit('select', 'strict')
            emit('update:modelValue', false)
          },
          onClose: () => emit('update:modelValue', false),
        },
        () => [
          h(TText, {
            x: 0,
            y: currentY,
            w,
            value: t('toolApprovalsDialog.currentPrefix', { mode: props.mode }),
            style: ui.style(['dialog.chrome', 'text.muted']),
          }),
          h(TText, {
            x: 0,
            y: titleY,
            w,
            value: focusedTitle,
            style: highlight,
          }),
          h(TText, {
            x: 0,
            y: descY,
            w,
            h: descHeight,
            wrap: true,
            value: focusedDesc,
            style: descStyle,
          }),
          h(TText, {
            x: 0,
            y: tipY,
            w,
            h: 2,
            wrap: true,
            value: t('toolApprovalsDialog.tip'),
            style: tipStyle,
          }),
        ],
      )
    }
  },
})
