<script setup lang="ts">
import type { AgentInfo } from '../types';

import { computed, nextTick, ref } from 'vue';

import { Delete, Plus, Rank } from '@element-plus/icons-vue';
import { ElButton, ElForm, ElFormItem, ElIcon, ElInput } from 'element-plus';

import {
  MAX_INPUT_PLACEHOLDER_LENGTH,
  MAX_SUGGESTED_QUESTION_COUNT,
  MAX_SUGGESTED_QUESTION_LENGTH,
  MAX_WELCOME_MESSAGE_LENGTH,
} from '../interaction-config';

const props = defineProps<{
  agent: AgentInfo;
}>();

const emit = defineEmits<{ change: [] }>();

const welcomeInput = ref();
const placeholderInput = ref();
const questionInputs = ref<any[]>([]);
const draggingIndex = ref<number>();

const questions = computed(
  () => props.agent.interactionConfigJson!.suggestedQuestions,
);
const duplicateQuestionIndexes = computed(() => {
  const firstIndexes = new Map<string, number>();
  const duplicates = new Set<number>();
  questions.value.forEach((question, index) => {
    const normalized = question.trim();
    if (!normalized) return;
    const firstIndex = firstIndexes.get(normalized);
    if (firstIndex === undefined) {
      firstIndexes.set(normalized, index);
      return;
    }
    duplicates.add(firstIndex);
    duplicates.add(index);
  });
  return duplicates;
});

function questionError(index: number) {
  const question = questions.value[index] || '';
  if (question.trim().length > MAX_SUGGESTED_QUESTION_LENGTH) {
    return '最多 80 个字符';
  }
  if (duplicateQuestionIndexes.value.has(index)) {
    return '内容重复';
  }
  return '';
}

async function addQuestion() {
  if (questions.value.length >= MAX_SUGGESTED_QUESTION_COUNT) return;
  questions.value.push('');
  emit('change');
  await nextTick();
  questionInputs.value.at(-1)?.focus?.();
}

function removeQuestion(index: number) {
  questions.value.splice(index, 1);
  emit('change');
}

function moveQuestion(from: number, to: number) {
  if (from === to || to < 0 || to >= questions.value.length) return;
  const [question] = questions.value.splice(from, 1);
  questions.value.splice(to, 0, question || '');
  emit('change');
  void nextTick(() => questionInputs.value[to]?.focus?.());
}

function handleDragStart(index: number, event: DragEvent) {
  draggingIndex.value = index;
  event.dataTransfer?.setData('text/plain', String(index));
  if (event.dataTransfer) event.dataTransfer.effectAllowed = 'move';
}

function handleDrop(index: number, event: DragEvent) {
  event.preventDefault();
  const from = draggingIndex.value;
  draggingIndex.value = undefined;
  if (from === undefined) return;
  moveQuestion(from, index);
}

function handleMoveKeydown(index: number, event: KeyboardEvent) {
  if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown') return;
  event.preventDefault();
  moveQuestion(index, index + (event.key === 'ArrowUp' ? -1 : 1));
}

async function focusField(field?: string) {
  await nextTick();
  if (field === 'interaction.welcomeMessage') {
    welcomeInput.value?.focus?.();
    return;
  }
  if (field === 'interaction.inputPlaceholder') {
    placeholderInput.value?.focus?.();
    return;
  }
  const match = field?.match(/^interaction\.suggestedQuestions\.(\d+)$/);
  if (match) questionInputs.value[Number(match[1])]?.focus?.();
}

defineExpose({ focusField });
</script>

<template>
  <ElForm label-position="top" class="agent-interaction-form">
    <ElFormItem label="欢迎语">
      <ElInput
        ref="welcomeInput"
        v-model="agent.interactionConfigJson!.welcomeMessage"
        type="textarea"
        :rows="5"
        resize="vertical"
        :maxlength="MAX_WELCOME_MESSAGE_LENGTH"
        show-word-limit
        placeholder="留空时使用默认欢迎语"
        @input="emit('change')"
      />
    </ElFormItem>

    <div class="agent-interaction-form__section-head">
      <div>
        <div class="agent-interaction-form__section-title">猜你想问</div>
        <div class="agent-interaction-form__section-hint">
          新会话中展示，点击后直接发送
        </div>
      </div>
      <span class="agent-interaction-form__count">
        {{ questions.length }}/{{ MAX_SUGGESTED_QUESTION_COUNT }}
      </span>
    </div>

    <div v-if="questions.length > 0" class="agent-interaction-form__questions">
      <div
        v-for="(_, index) in questions"
        :key="index"
        class="agent-interaction-form__question"
        :class="{ 'is-dragging': draggingIndex === index }"
        @dragover.prevent
        @drop="handleDrop(index, $event)"
      >
        <button
          class="agent-interaction-form__drag"
          type="button"
          draggable="true"
          :aria-label="`调整第 ${index + 1} 条问题顺序`"
          title="拖动排序，或使用上下方向键"
          @dragend="draggingIndex = undefined"
          @dragstart="handleDragStart(index, $event)"
          @keydown="handleMoveKeydown(index, $event)"
        >
          <ElIcon><Rank /></ElIcon>
        </button>
        <div class="agent-interaction-form__question-input">
          <ElInput
            :ref="(element) => (questionInputs[index] = element)"
            v-model="questions[index]"
            :maxlength="MAX_SUGGESTED_QUESTION_LENGTH"
            :placeholder="`问题 ${index + 1}`"
            @input="emit('change')"
          />
          <span
            v-if="questionError(index)"
            class="agent-interaction-form__error"
          >
            {{ questionError(index) }}
          </span>
        </div>
        <ElButton
          :icon="Delete"
          circle
          text
          type="danger"
          :aria-label="`删除第 ${index + 1} 条问题`"
          @click="removeQuestion(index)"
        />
      </div>
    </div>
    <div v-else class="agent-interaction-form__empty">暂无建议问题</div>

    <ElButton
      class="agent-interaction-form__add"
      :icon="Plus"
      :disabled="questions.length >= MAX_SUGGESTED_QUESTION_COUNT"
      @click="addQuestion"
    >
      添加问题
    </ElButton>

    <ElFormItem label="输入提示" class="agent-interaction-form__placeholder">
      <ElInput
        ref="placeholderInput"
        v-model="agent.interactionConfigJson!.inputPlaceholder"
        :maxlength="MAX_INPUT_PLACEHOLDER_LENGTH"
        show-word-limit
        placeholder="输入消息"
        @input="emit('change')"
      />
    </ElFormItem>
  </ElForm>
</template>

<style scoped>
.agent-interaction-form {
  padding: var(--space-4);
}

.agent-interaction-form__section-head {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: var(--space-3);
}

.agent-interaction-form__section-title {
  font-size: 14px;
  font-weight: 600;
  color: hsl(var(--text-strong));
}

.agent-interaction-form__section-hint,
.agent-interaction-form__count {
  margin-top: var(--space-1);
  font-size: 12px;
  line-height: 18px;
  color: hsl(var(--text-muted));
}

.agent-interaction-form__questions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.agent-interaction-form__question {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) 32px;
  gap: var(--space-2);
  align-items: start;
  padding: var(--space-2);
  background: hsl(var(--surface-subtle));
  border: 1px solid hsl(var(--line-subtle));
  border-radius: var(--radius-toolbar);
  transition:
    border-color var(--motion-duration-fast) var(--motion-ease-standard),
    opacity var(--motion-duration-fast) var(--motion-ease-standard);
}

.agent-interaction-form__question:focus-within {
  border-color: var(--el-color-primary-light-5);
}

.agent-interaction-form__question.is-dragging {
  opacity: 0.56;
}

.agent-interaction-form__drag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 32px;
  padding: 0;
  color: hsl(var(--text-muted));
  cursor: grab;
  background: transparent;
  border: 0;
  border-radius: var(--radius-control);
}

.agent-interaction-form__drag:hover {
  color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
}

.agent-interaction-form__drag:focus-visible {
  outline: 2px solid var(--el-color-primary-light-5);
  outline-offset: 1px;
}

.agent-interaction-form__question-input {
  min-width: 0;
}

.agent-interaction-form__error {
  display: block;
  margin-top: var(--space-1);
  font-size: 12px;
  color: var(--el-color-danger);
}

.agent-interaction-form__empty {
  padding: var(--space-4);
  font-size: 13px;
  color: hsl(var(--text-muted));
  text-align: center;
  background: hsl(var(--surface-subtle));
  border-radius: var(--radius-toolbar);
}

.agent-interaction-form__add {
  width: 100%;
  margin-top: var(--space-2);
  border-style: dashed;
}

.agent-interaction-form__placeholder {
  margin-top: var(--space-6);
}

@media (prefers-reduced-motion: reduce) {
  .agent-interaction-form__question {
    transition: none;
  }
}
</style>
