<script setup lang="ts">
import { Send, Square } from "@lucide/vue";
import { nextTick, ref } from "vue";

defineProps<{
  loading: boolean;
  disabled: boolean;
}>();

const emit = defineEmits<{
  send: [message: string, complete: (success: boolean) => void];
  stop: [];
}>();

const input = ref("");
const textarea = ref<HTMLTextAreaElement | null>(null);

function resize() {
  const element = textarea.value;
  if (!element) return;
  element.style.height = "auto";
  element.style.height = `${Math.min(element.scrollHeight, 108)}px`;
  element.style.overflowY = element.scrollHeight > 108 ? "auto" : "hidden";
}

async function send() {
  const text = input.value.trim();
  if (!text) return;
  // Sending has been accepted by the composer. Clear immediately instead of
  // keeping the submitted text visible until the entire AI stream finishes.
  input.value = "";
  await nextTick();
  resize();
  emit("send", text, async (success) => {
    // Restore only when the parent rejected/failed the request and the user has
    // not entered replacement text in the meantime.
    if (!success && !input.value) {
      input.value = text;
      await nextTick();
      resize();
      textarea.value?.focus();
    }
  });
}

function onKeydown(event: KeyboardEvent) {
  if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
    event.preventDefault();
    send();
  }
}
</script>

<template>
  <form class="chat-composer" @submit.prevent="send">
    <textarea
      ref="textarea"
      v-model="input"
      rows="1"
      placeholder="请输入你的问题"
      aria-label="请输入你的问题"
      :disabled="disabled"
      @input="resize"
      @keydown="onKeydown"
    />
    <button v-if="loading" type="button" class="composer-stop" aria-label="停止生成" @click="emit('stop')">
      <Square :size="17" fill="currentColor" aria-hidden="true" />
      <span>停止</span>
    </button>
    <button v-else type="submit" class="composer-send" :disabled="disabled || !input.trim()">
      <Send :size="18" aria-hidden="true" />
      <span>发送</span>
    </button>
  </form>
</template>
