<script setup lang="ts">
import { onBeforeUnmount, ref } from 'vue';

import { Check, Copy, RotateCw } from '@easyflow/icons';

import ChatVariantNavigator from './ChatVariantNavigator.vue';

const props = withDefaults(
  defineProps<{
    align?: 'end' | 'start';
    allowCopy?: boolean;
    allowRegenerate?: boolean;
    copyAction?: () => boolean | Promise<boolean>;
    disabledVariantNext?: boolean;
    disabledVariantPrevious?: boolean;
    regenerateDisabled?: boolean;
    showVariantNavigator?: boolean;
    variantCurrent?: number;
    variantLoading?: boolean;
    variantTotal?: number;
  }>(),
  {
    align: 'start',
    allowCopy: false,
    allowRegenerate: false,
    copyAction: undefined,
    disabledVariantNext: false,
    disabledVariantPrevious: false,
    regenerateDisabled: false,
    showVariantNavigator: false,
    variantCurrent: 1,
    variantLoading: false,
    variantTotal: 1,
  },
);

const emit = defineEmits<{
  copy: [];
  regenerate: [];
  selectNextVariant: [];
  selectPreviousVariant: [];
}>();

const copied = ref(false);
const copying = ref(false);
const COPIED_FEEDBACK_DURATION_MS = 3000;
let copiedResetTimer: ReturnType<typeof setTimeout> | undefined;

async function handleCopy() {
  if (copying.value) {
    return;
  }
  if (!props.copyAction) {
    emit('copy');
    return;
  }

  copying.value = true;
  try {
    const success = await props.copyAction();
    if (!success) {
      return;
    }
    copied.value = true;
    if (copiedResetTimer) {
      clearTimeout(copiedResetTimer);
    }
    copiedResetTimer = setTimeout(() => {
      copied.value = false;
      copiedResetTimer = undefined;
    }, COPIED_FEEDBACK_DURATION_MS);
  } catch (error) {
    console.error('复制消息失败:', error);
  } finally {
    copying.value = false;
  }
}

function handleRegenerate() {
  if (props.regenerateDisabled) {
    return;
  }
  emit('regenerate');
}

onBeforeUnmount(() => {
  if (copiedResetTimer) {
    clearTimeout(copiedResetTimer);
  }
});
</script>

<template>
  <div
    v-if="allowCopy || allowRegenerate || showVariantNavigator"
    class="chat-message-toolbar"
    :class="`is-${align}`"
  >
    <button
      v-if="allowCopy"
      type="button"
      class="chat-message-toolbar__button"
      :aria-busy="copying"
      :aria-label="copied ? '复制成功' : '复制消息'"
      :title="copied ? '复制成功' : '复制'"
      @click="handleCopy"
    >
      <Transition name="chat-message-toolbar__icon" mode="out-in">
        <Check v-if="copied" key="check" />
        <Copy v-else key="copy" />
      </Transition>
    </button>
    <button
      v-if="allowRegenerate"
      type="button"
      class="chat-message-toolbar__button"
      :disabled="regenerateDisabled"
      aria-label="重新生成"
      title="重新生成"
      @click="handleRegenerate"
      >
      <RotateCw />
    </button>
    <ChatVariantNavigator
      v-if="showVariantNavigator"
      class="chat-message-toolbar__navigator"
      :current="variantCurrent"
      :total="variantTotal"
      :disabled-next="disabledVariantNext"
      :disabled-previous="disabledVariantPrevious"
      :loading="variantLoading"
      @next="emit('selectNextVariant')"
      @previous="emit('selectPreviousVariant')"
    />
  </div>
</template>

<style scoped>
.chat-message-toolbar {
  display: flex;
  width: 100%;
  gap: 4px;
  align-items: center;
  margin-top: 4px;
}

.chat-message-toolbar.is-end {
  justify-content: flex-end;
}

.chat-message-toolbar__navigator {
  margin-left: auto;
}

.chat-message-toolbar__button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  color: var(--el-text-color-secondary);
  cursor: pointer;
  background: transparent;
  border: 0;
  border-radius: 6px;
  transition:
    color 0.18s ease,
    background-color 0.18s ease,
    opacity 0.18s ease;
}

.chat-message-toolbar__button:hover:not(:disabled) {
  color: var(--el-text-color-primary);
  background: var(--el-fill-color-light);
}

.chat-message-toolbar__button:focus-visible {
  outline: 2px solid var(--el-color-primary-light-5);
  outline-offset: 2px;
}

.chat-message-toolbar__button:disabled {
  cursor: not-allowed;
  opacity: 0.42;
}

.chat-message-toolbar__button :deep(svg) {
  width: 14px;
  height: 14px;
}

.chat-message-toolbar__icon-enter-active,
.chat-message-toolbar__icon-leave-active {
  transition:
    opacity var(--motion-duration-fast) var(--motion-ease-standard),
    transform var(--motion-duration-fast) var(--motion-ease-standard);
}

.chat-message-toolbar__icon-enter-from,
.chat-message-toolbar__icon-leave-to {
  opacity: 0;
  transform: scale(0.88);
}
</style>
