<template>
  <div
    :class="[
      'message',
      message.sender_type === 'assistant' || message.role === 'assistant'
        ? 'ai-message'
        : message.sender_type === 'system' || message.role === 'system'
          ? 'system-message'
          : 'user-message',
      message.isLocal ? 'is-local' : '',
      message.hasError ? 'has-error' : '',
    ]"
  >
    <!-- Текстовый контент, если есть -->
    <!-- eslint-disable-next-line vue/no-v-html -->
    <div v-if="message.content" class="message-content" v-html="formattedContent" />

    <!-- Блок для отображения прикрепленного файла (теперь с плеерами/изображением/ссылкой) -->
    <div v-if="attachment" class="message-attachments">
      <div class="attachment-item">
        <!-- Изображение -->
        <img v-if="isImage" :src="objectUrl" :alt="attachment.originalname" class="attachment-preview image-preview"/>

        <!-- Аудио -->
        <audio v-else-if="isAudio" :src="objectUrl" controls class="attachment-preview audio-preview" />

        <!-- Видео -->
        <video v-else-if="isVideo" :src="objectUrl" controls class="attachment-preview video-preview" />

        <!-- Другие типы файлов (ссылка на скачивание) -->
        <div v-else class="attachment-info file-preview">
          <span class="attachment-icon">📄</span>
          <a :href="objectUrl" :download="attachment.originalname" class="attachment-name">
            {{ attachment.originalname }}
          </a>
          <span class="attachment-size">({{ formatFileSize(attachment.size) }})</span>
        </div>
      </div>
    </div>

    <div class="message-meta">
      <div class="message-time">
        {{ formattedTime }}
      </div>
      <div v-if="message.isLocal" class="message-status">
        <span class="sending-indicator">Отправка...</span>
      </div>
      <div v-if="message.hasError" class="message-status">
        <span class="error-indicator">Ошибка отправки</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { defineProps, computed, ref, watch, onUnmounted } from 'vue';
import DOMPurify from 'dompurify';
import { marked } from 'marked';

const props = defineProps({
  message: {
    type: Object,
    required: true,
  },
});

// --- Работа с вложениями --- 
const attachment = computed(() => {
    // Ожидаем массив attachments, даже если там только один элемент
    return props.message.attachments && props.message.attachments.length > 0
      ? props.message.attachments[0]
      : null;
});

const objectUrl = ref(null);
const isImage = ref(false);
const isAudio = ref(false);
const isVideo = ref(false);

// Функция для преобразования Base64 в Blob
const base64ToBlob = (base64, mimetype) => {
  try {
    const byteCharacters = atob(base64);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    return new Blob([byteArray], { type: mimetype });
  } catch (e) {
    console.error("Error decoding base64 string:", e);
    return null;
  }
};

// Наблюдаем за изменением вложения в сообщении
watch(attachment, (newAttachment) => {
  // Очищаем предыдущий URL, если он был
  if (objectUrl.value) {
    URL.revokeObjectURL(objectUrl.value);
    objectUrl.value = null;
  }
  // Сбрасываем типы
  isImage.value = false;
  isAudio.value = false;
  isVideo.value = false;

  if (newAttachment && newAttachment.data_base64 && newAttachment.mimetype) {
    const blob = base64ToBlob(newAttachment.data_base64, newAttachment.mimetype);
    if (blob) {
      objectUrl.value = URL.createObjectURL(blob);

      // Определяем тип для условного рендеринга
      const mimetype = newAttachment.mimetype.toLowerCase();
      if (mimetype.startsWith('image/')) {
        isImage.value = true;
      } else if (mimetype.startsWith('audio/')) {
        isAudio.value = true;
      } else if (mimetype.startsWith('video/')) {
        isVideo.value = true;
      }
    }
  }
}, { immediate: true }); // Выполняем сразу при монтировании

// Очистка при размонтировании
onUnmounted(() => {
  if (objectUrl.value) {
    URL.revokeObjectURL(objectUrl.value);
  }
});

// --- Форматирование контента и времени (остается как было) ---
const formattedContent = computed(() => {
  if (!props.message.content) return '';
  const rawHtml = marked.parse(props.message.content);
  return DOMPurify.sanitize(rawHtml);
});

const formattedTime = computed(() => {
  const timestamp = props.message.timestamp || props.message.created_at;
  if (!timestamp) return '';
  try {
    const date = new Date(timestamp);
    if (isNaN(date.getTime())) {
      console.warn('Invalid timestamp in Message.vue:', timestamp);
      return '';
    }
    return date.toLocaleString([], {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    });
  } catch (error) {
    console.error('Error formatting time in Message.vue:', error, timestamp);
    return '';
  }
});

// Форматирование размера файла
const formatFileSize = (bytes) => {
  if (!bytes || bytes === 0) return '0 Bytes'; // Добавлена проверка на undefined/null
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

</script>

<style scoped>
/* Стили сообщений, полностью перенесенные из home.css */
.message {
  margin-bottom: var(--spacing-md);
  padding: var(--spacing-sm) var(--spacing-md);
  border-radius: var(--radius-lg);
  max-width: 75%;
  word-wrap: break-word;
  position: relative;
  box-shadow: var(--shadow-sm);
}

.user-message {
  background-color: var(--color-user-message);
  align-self: flex-end;
  margin-left: auto;
  margin-right: var(--spacing-sm);
  border-bottom-right-radius: 2px;
}

.ai-message {
  background-color: var(--color-ai-message);
  align-self: flex-start;
  margin-right: auto;
  margin-left: var(--spacing-sm);
  word-break: break-word;
  max-width: 70%;
  border-bottom-left-radius: 2px;
}

.system-message {
  background-color: var(--color-system-message);
  align-self: center;
  margin-left: auto;
  margin-right: auto;
  font-style: italic;
  color: var(--color-system-text);
  text-align: center;
  max-width: 90%;
}

.message-content {
  margin-bottom: var(--spacing-xs);
  white-space: pre-wrap;
  word-break: break-word;
  font-size: var(--font-size-md);
  line-height: 1.5;
}

.message-content :deep(p) {
    margin-bottom: 0.5em;
}
.message-content :deep(ul),
.message-content :deep(ol) {
    margin-left: 1.5em;
}
.message-content :deep(pre) {
    background-color: #eee;
    padding: 0.5em;
    border-radius: 4px;
    overflow-x: auto;
}
.message-content :deep(code) {
    font-family: monospace;
}

.message-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: var(--spacing-xs);
}

.message-time {
  font-size: var(--font-size-xs);
  color: var(--color-grey);
  text-align: right;
}

.message-status {
  font-size: var(--font-size-xs);
  color: var(--color-grey);
}

.sending-indicator {
  color: var(--color-secondary);
  font-style: italic;
}

.error-indicator {
  color: var(--color-danger);
  font-weight: bold;
}

.is-local {
  opacity: 0.7;
}

.has-error {
  border: 1px solid var(--color-danger);
}

/* Стили для вложений */
.message-attachments {
  margin-top: var(--spacing-sm);
  border-top: 1px solid rgba(0, 0, 0, 0.1);
  padding-top: var(--spacing-sm);
}

.attachment-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.attachment-preview {
  max-width: 100%;
  max-height: 300px;
  margin-bottom: var(--spacing-xs);
  border-radius: var(--radius-md);
}

.image-preview {
  object-fit: cover;
}

.audio-preview {
  width: 100%;
}

.video-preview {
  width: 100%;
}

.file-preview {
  display: flex;
  align-items: center;
  font-size: var(--font-size-sm);
}

.attachment-icon {
  margin-right: var(--spacing-xs);
}

.attachment-name {
  font-weight: 500;
  margin-right: var(--spacing-xs);
  color: var(--color-primary);
  text-decoration: none;
}

.attachment-name:hover {
  text-decoration: underline;
}

.attachment-size {
  color: var(--color-grey);
  font-size: var(--font-size-xs);
}

/* Адаптивные стили для разных экранов */
@media (max-width: 768px) {
  .message {
    max-width: 85%;
    padding: var(--spacing-xs) var(--spacing-sm);
  }
  
  .ai-message {
    max-width: 80%;
  }
}

@media (max-width: 480px) {
  .message {
    max-width: 95%;
    font-size: var(--font-size-sm);
  }
  
  .ai-message {
    max-width: 90%;
  }
  
  .message-time {
    font-size: calc(var(--font-size-xs) - 1px);
  }
  
  .attachment-preview {
    max-height: 200px;
  }
}
</style> 