<template>
  <div
    class="d-flex align-start ga-2 px-3 py-2 shrink-0 cmd-bar cmd-bar--tall"
    :class="{ 'opacity-50 pointer-events-none': disabled }"
    @contextmenu="$emit('context-menu', $event)"
  >
    <span class="cmd-bar__prompt font-mono text-primary shrink-0">❯</span>
    <div class="flex-grow-1 cmd-bar__input-wrap">
      <ShellHighlightField
        ref="fieldRef"
        :model-value="modelValue"
        multiline
        :rows="3"
        size="large"
        placeholder="输入命令，Enter 发送，Shift+Enter 换行"
        :disabled="disabled"
        @update:model-value="$emit('update:modelValue', $event)"
        @keydown="$emit('keydown', $event)"
      />
    </div>
    <v-btn
      size="default"
      variant="tonal"
      color="primary"
      class="mt-1"
      :disabled="disabled"
      @click="$emit('send')"
    >
      发送
    </v-btn>
    <div class="terminal-hotkeys shrink-0 pl-3">
      <div class="text-body-2 font-weight-medium text-medium-emphasis mb-2">快捷键</div>
      <div class="d-flex flex-column ga-2">
        <v-btn size="default" variant="outlined" block @click="$emit('ctrl', 'c')">中断 (Ctrl+C)</v-btn>
        <v-btn size="default" variant="outlined" block @click="$emit('ctrl', 'd')">退出 (Ctrl+D)</v-btn>
        <v-btn size="default" variant="outlined" block @click="$emit('key', '\t')">补全 (Tab)</v-btn>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import ShellHighlightField from '@/components/ShellHighlightField.vue'

defineProps<{
  modelValue: string
  disabled: boolean
}>()

defineEmits<{
  'update:modelValue': [value: string]
  keydown: [event: KeyboardEvent]
  send: []
  ctrl: [key: string]
  key: [key: string]
  'context-menu': [event: MouseEvent]
}>()

const fieldRef = ref<InstanceType<typeof ShellHighlightField> | null>(null)

function getInputEl() {
  return fieldRef.value?.getInputEl() ?? null
}

function getSelectionText() {
  return fieldRef.value?.getSelectionText() ?? ''
}

function selectAllInput() {
  fieldRef.value?.selectAllInput()
}

async function insertAtSelection(text: string) {
  await fieldRef.value?.insertAtSelection(text)
}

defineExpose({
  getInputEl,
  getSelectionText,
  selectAllInput,
  insertAtSelection,
})
</script>

<style scoped>
.cmd-bar {
  background: rgb(var(--v-theme-surface));
  border-top: 1px solid rgb(var(--v-theme-surface-variant));
}
.cmd-bar--tall {
  min-height: 120px;
}
.cmd-bar__prompt {
  font-size: 1.125rem;
  line-height: 1.55;
  padding-top: 12px;
}
.cmd-bar__input-wrap {
  min-width: 0;
}
.terminal-hotkeys {
  border-left: 1px solid rgb(var(--v-theme-surface-variant));
  min-width: 9.5rem;
}
.font-mono {
  font-family: 'Cascadia Code', 'Fira Code', 'JetBrains Mono', Menlo, monospace;
}
</style>
