<script setup lang="ts">
import type { AiChatMessage, AiToolApprovalPayload } from './types';
import type { ChatImageAttachment, ChatImageLoader } from '@easyflow/common-ui';

import { Close } from '@element-plus/icons-vue';
import { ElButton } from 'element-plus';

import AiConversation from './AiConversation.vue';
import AiPromptInput from './AiPromptInput.vue';

withDefaults(
  defineProps<{
    approvalLoading?: boolean;
    closable?: boolean;
    emptyText?: string;
    loading?: boolean;
    images?: ChatImageAttachment[];
    imageEnabled?: boolean;
    imageLoader?: ChatImageLoader;
    modelValue?: string;
    messages: AiChatMessage[];
    placeholder?: string;
    subtitle?: string;
    title: string;
  }>(),
  { imageEnabled: true },
);

const emit = defineEmits<{
  addFiles: [files: File[]];
  approve: [payload: AiToolApprovalPayload];
  close: [];
  reject: [payload: AiToolApprovalPayload];
  send: [text: string];
  removeImage: [item: ChatImageAttachment];
  retryImage: [item: ChatImageAttachment];
  stop: [];
  'update:modelValue': [value: string];
}>();

defineSlots<{
  default?: () => any;
  headerActions?: () => any;
}>();
</script>

<template>
  <section class="ai-chat-panel">
    <header class="ai-chat-panel__header">
      <div class="ai-chat-panel__title-wrap">
        <div class="ai-chat-panel__title">{{ title }}</div>
        <div v-if="subtitle" class="ai-chat-panel__subtitle">
          {{ subtitle }}
        </div>
      </div>
      <div class="ai-chat-panel__actions">
        <slot name="headerActions"></slot>
        <ElButton
          v-if="closable"
          :icon="Close"
          circle
          text
          aria-label="关闭"
          @click="emit('close')"
        />
      </div>
    </header>
    <slot>
      <AiConversation
        :messages="messages"
        :empty-text="emptyText"
        :approval-loading="approvalLoading"
        @approve="emit('approve', $event)"
        @reject="emit('reject', $event)"
      />
    </slot>
    <AiPromptInput
      :model-value="modelValue"
      :images="images"
      :image-enabled="imageEnabled"
      :image-loader="imageLoader"
      :loading="loading"
      :placeholder="placeholder"
      @send="emit('send', $event)"
      @add-files="emit('addFiles', $event)"
      @remove-image="emit('removeImage', $event)"
      @retry-image="emit('retryImage', $event)"
      @stop="emit('stop')"
      @update:model-value="emit('update:modelValue', $event)"
    />
  </section>
</template>

<style scoped>
.ai-chat-panel {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.ai-chat-panel__header {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
  min-height: 48px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--el-border-color-lighter);
}

.ai-chat-panel__title-wrap {
  flex: 1;
  min-width: 0;
}

.ai-chat-panel__actions {
  display: inline-flex;
  flex: 0 0 auto;
  gap: 2px;
  align-items: center;
}

.ai-chat-panel__actions :deep(.el-button.is-circle) {
  width: 32px;
  height: 32px;
}

.ai-chat-panel__title {
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 15px;
  font-weight: 600;
  color: var(--el-text-color-primary);
  white-space: nowrap;
}

.ai-chat-panel__subtitle {
  margin-top: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12px;
  color: var(--el-text-color-secondary);
  white-space: nowrap;
}
</style>
