<template>
  <div class="chat-container" :style="{ '--chat-input-height': chatInputHeight + 'px' }">
    <div ref="messagesContainer" class="chat-messages" @scroll="handleScroll">
      <Message 
        v-for="message in messages"
        :key="message.id"
        :message="message"
      />
    </div>

    <div ref="chatInputRef" class="chat-input">
      <div class="input-area">
        <textarea
          ref="messageInputRef"
          :value="newMessage"
          @input="handleInput"
          placeholder="Введите сообщение..."
          :disabled="isLoading"
          rows="1"
          autofocus
          @keydown.enter.prevent="sendMessage"
          @focus="handleFocus"
          @blur="handleBlur"
        />
        <div class="chat-icons">
          <button 
            class="chat-icon-btn" 
            title="Удерживайте для записи аудио" 
            @mousedown="startAudioRecording" 
            @mouseup="stopAudioRecording"
            @mouseleave="stopAudioRecording"
            :class="{ 'recording': isAudioRecording }"
          >
            <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
              <path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z" fill="currentColor"/>
              <path d="M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z" fill="currentColor"/>
            </svg>
          </button>
          <button 
            class="chat-icon-btn" 
            title="Удерживайте для записи видео" 
            @mousedown="startVideoRecording" 
            @mouseup="stopVideoRecording"
            @mouseleave="stopVideoRecording"
            :class="{ 'recording': isVideoRecording }"
          >
            <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
              <path d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z" fill="currentColor"/>
            </svg>
          </button>
          <button class="chat-icon-btn" title="Прикрепить файл" @click="handleFileUpload">
            <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
              <path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z" fill="currentColor"/>
            </svg>
          </button>
          <button class="chat-icon-btn" title="Очистить поле ввода" @click="clearInput">
            <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
              <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="currentColor"/>
            </svg>
          </button>
          <button 
            class="chat-icon-btn send-button" 
            title="Отправить сообщение" 
            :disabled="isSendDisabled" 
            @click="sendMessage"
          >
            <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
              <path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z" fill="currentColor"/>
            </svg>
          </button>
        </div>
      </div>
      <div class="attachment-preview" v-if="localAttachments.length > 0">
        <div v-for="(file, index) in localAttachments" :key="index" class="preview-item">
          <img v-if="file.type.startsWith('image/')" :src="file.previewUrl" class="image-preview"/>
          <div v-else-if="file.type.startsWith('audio/')" class="audio-preview">
            <span>&#127925; {{ file.name }} ({{ formatFileSize(file.size) }})</span>
          </div>
          <div v-else-if="file.type.startsWith('video/')" class="video-preview">
            <span>&#127916; {{ file.name }} ({{ formatFileSize(file.size) }})</span>
          </div>
          <div v-else class="file-preview">
            <span>&#128196; {{ file.name }} ({{ formatFileSize(file.size) }})</span>
          </div>
          <button @click="removeAttachment(index)" class="remove-attachment-btn">×</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue';
import Message from './Message.vue';

const props = defineProps({
  messages: {
    type: Array,
    default: () => [],
  },
  isLoading: Boolean,
  newMessage: String, // Для v-model
  attachments: Array, // Для v-model
  // Добавляем пропс для проверки, есть ли еще сообщения для загрузки
  hasMoreMessages: Boolean,
});

const emit = defineEmits([
  'update:newMessage',
  'update:attachments',
  'send-message',
  'load-more', // Событие для загрузки старых сообщений
]);

const messagesContainer = ref(null);
const messageInputRef = ref(null);
const chatInputRef = ref(null); // Ref для chat-input
const chatInputHeight = ref(80); // Начальная высота (можно подобрать точнее)

// Локальное состояние для предпросмотра, синхронизированное с props.attachments
const localAttachments = ref([...props.attachments]);
watch(() => props.attachments, (newVal) => {
  // Обновляем локальное состояние, только если внешнее изменилось
  if (JSON.stringify(newVal) !== JSON.stringify(localAttachments.value)) {
      // Очищаем старые URL превью перед обновлением
      localAttachments.value.forEach(att => {
        if (att.previewUrl) {
          URL.revokeObjectURL(att.previewUrl);
        }
      });
      localAttachments.value = [...newVal];
  }
}, { deep: true });

// --- Логика записи медиа (остается здесь, так как связана с UI компонента) ---
const isAudioRecording = ref(false);
const isVideoRecording = ref(false);
const audioRecorder = ref(null);
const videoRecorder = ref(null);
const audioStream = ref(null);
const videoStream = ref(null);
const recordedAudioChunks = ref([]);
const recordedVideoChunks = ref([]);

const startAudioRecording = async () => {
  console.log('[ChatInterface] startAudioRecording called');
  try {
    if (isAudioRecording.value) return;
    audioStream.value = await navigator.mediaDevices.getUserMedia({ audio: true });
    console.log('[ChatInterface] Got audio stream:', audioStream.value);
    recordedAudioChunks.value = [];
    audioRecorder.value = new MediaRecorder(audioStream.value);
    audioRecorder.value.ondataavailable = (event) => {
      console.log('[ChatInterface] audioRecorder.ondataavailable fired');
      if (event.data.size > 0) recordedAudioChunks.value.push(event.data);
    };
    audioRecorder.value.onstop = () => {
        console.log('[ChatInterface] audioRecorder.onstop fired');
        setTimeout(() => {
            if (recordedAudioChunks.value.length === 0) {
                console.warn('[ChatInterface] No audio chunks recorded.');
                return;
            }
            console.log(`[ChatInterface] Creating audio Blob from ${recordedAudioChunks.value.length} chunks.`);
            const audioBlob = new Blob(recordedAudioChunks.value, { type: 'audio/webm' });
            const audioFile = new File([audioBlob], `audio-${Date.now()}.webm`, { type: 'audio/webm' });
            addAttachment(audioFile);
            recordedAudioChunks.value = [];
        }, 100);
    };
    audioRecorder.value.start();
    isAudioRecording.value = true;
    console.log('[ChatInterface] Audio recording started, recorder state:', audioRecorder.value.state);
  } catch (error) {
    console.error('[ChatInterface] Error starting audio recording:', error);
  }
};

const stopAudioRecording = async () => {
  console.log('[ChatInterface] stopAudioRecording called');
  if (!isAudioRecording.value || !audioRecorder.value || audioRecorder.value.state === 'inactive') {
      console.log('[ChatInterface] stopAudioRecording: Not recording or recorder inactive, state:', audioRecorder.value?.state);
      return;
  }
  try {
    audioRecorder.value.stop();
    console.log('[ChatInterface] audioRecorder.stop() called');
    isAudioRecording.value = false;
    if (audioStream.value) {
        audioStream.value.getTracks().forEach(track => track.stop());
        console.log('[ChatInterface] Audio stream tracks stopped.');
    }
  } catch (error) {
    console.error('[ChatInterface] Error stopping audio recording:', error);
    isAudioRecording.value = false;
    if (audioStream.value) audioStream.value.getTracks().forEach(track => track.stop());
  }
};

const startVideoRecording = async () => {
  console.log('[ChatInterface] startVideoRecording called');
  try {
    if (isVideoRecording.value) return;
    videoStream.value = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
    console.log('[ChatInterface] Got video stream:', videoStream.value);
    recordedVideoChunks.value = [];
    let options = { mimeType: 'video/webm;codecs=vp9,opus' };
    if (!MediaRecorder.isTypeSupported(options.mimeType)) {
        console.warn(`MIME type ${options.mimeType} not supported, trying video/webm...`);
        options = { mimeType: 'video/webm' };
        if (!MediaRecorder.isTypeSupported(options.mimeType)) {
            console.warn(`MIME type ${options.mimeType} not supported, using default.`);
            options = {};
        }
    }
    console.log('[ChatInterface] Using MediaRecorder options:', options);
    videoRecorder.value = new MediaRecorder(videoStream.value, options);

    videoRecorder.value.ondataavailable = (event) => {
      console.log('[ChatInterface] videoRecorder.ondataavailable fired');
      if (event.data.size > 0) recordedVideoChunks.value.push(event.data);
    };
    videoRecorder.value.onstop = () => {
      console.log('[ChatInterface] videoRecorder.onstop fired');
      setTimeout(() => {
          if (recordedVideoChunks.value.length === 0) {
              console.warn('[ChatInterface] No video chunks recorded.');
              return;
          }
          console.log(`[ChatInterface] Creating video Blob from ${recordedVideoChunks.value.length} chunks.`);
          const videoBlob = new Blob(recordedVideoChunks.value, { type: videoRecorder.value.mimeType || 'video/webm' });
          const videoFile = new File([videoBlob], `video-${Date.now()}.webm`, { type: videoRecorder.value.mimeType || 'video/webm' });
          addAttachment(videoFile);
          recordedVideoChunks.value = [];
      }, 100);
    };
    videoRecorder.value.start();
    isVideoRecording.value = true;
    console.log('[ChatInterface] Video recording started, recorder state:', videoRecorder.value.state);
  } catch (error) {
    console.error('[ChatInterface] Error starting video recording:', error);
  }
};

const stopVideoRecording = async () => {
  console.log('[ChatInterface] stopVideoRecording called');
  if (!isVideoRecording.value || !videoRecorder.value || videoRecorder.value.state === 'inactive') {
      console.log('[ChatInterface] stopVideoRecording: Not recording or recorder inactive, state:', videoRecorder.value?.state);
      return;
  }
  try {
    videoRecorder.value.stop();
    console.log('[ChatInterface] videoRecorder.stop() called');
    isVideoRecording.value = false;
    if (videoStream.value) {
        videoStream.value.getTracks().forEach(track => track.stop());
        console.log('[ChatInterface] Video stream tracks stopped.');
    }
  } catch (error) {
    console.error('[ChatInterface] Error stopping video recording:', error);
    isVideoRecording.value = false;
    if (videoStream.value) videoStream.value.getTracks().forEach(track => track.stop());
  }
};

// --- Логика загрузки файлов --- 
const handleFileUpload = () => {
  const fileInput = document.createElement('input');
  fileInput.type = 'file';
  fileInput.multiple = true;
  fileInput.accept = '.txt,.pdf,.jpg,.jpeg,.png,.gif,.mp3,.wav,.mp4,.avi,.docx,.xlsx,.pptx,.odt,.ods,.odp,.zip,.rar,.7z';
  fileInput.onchange = (event) => {
    const files = event.target.files;
    if (files && files.length > 0) {
      Array.from(files).forEach(file => addAttachment(file));
    }
  };
  fileInput.click();
};

// --- Логика управления предпросмотром --- 
const addAttachment = (file) => {
  const attachment = {
    file: file,
    name: file.name,
    size: file.size,
    type: file.type,
    previewUrl: null
  };
  if (file.type.startsWith('image/')) {
    attachment.previewUrl = URL.createObjectURL(file);
  }
  const updatedAttachments = [...localAttachments.value, attachment];
  localAttachments.value = updatedAttachments; // Обновляем локальное состояние
  emit('update:attachments', updatedAttachments); // Обновляем состояние в родителе
  nextTick(updateChatInputHeight); // Обновляем высоту после добавления превью
};

const removeAttachment = (index) => {
  const attachment = localAttachments.value[index];
  if (attachment.previewUrl) {
    URL.revokeObjectURL(attachment.previewUrl);
  }
  const updatedAttachments = localAttachments.value.filter((_, i) => i !== index);
  localAttachments.value = updatedAttachments; // Обновляем локальное состояние
  emit('update:attachments', updatedAttachments); // Обновляем состояние в родителе
  nextTick(updateChatInputHeight); // Обновляем высоту после удаления превью
};

// --- Очистка ввода --- 
const clearInput = () => {
  emit('update:newMessage', ''); // Очищаем текстовое поле через emit
  // Очищаем локальные превью и родительское состояние
  localAttachments.value.forEach(att => {
      if (att.previewUrl) {
          URL.revokeObjectURL(att.previewUrl);
      }
  });
  localAttachments.value = [];
  emit('update:attachments', []);
  nextTick(adjustTextareaHeight); // Сбросить высоту textarea
};

// --- Отправка сообщения --- 
const isSendDisabled = computed(() => {
  return props.isLoading || (!props.newMessage.trim() && localAttachments.value.length === 0);
});

const sendMessage = () => {
  if (isSendDisabled.value) return;
  // Отправляем событие с текстом и текущими прикрепленными файлами
  emit('send-message', { 
      message: props.newMessage, 
      attachments: localAttachments.value.map(att => att.file) // Отправляем только сами файлы
  });
  // Очищаем поле ввода и превью после отправки
  clearInput();
  nextTick(adjustTextareaHeight); // Сбросить высоту textarea после отправки
};

// --- Прокрутка и UI --- 
const scrollToBottom = () => {
  if (messagesContainer.value) {
    // Используем nextTick для ожидания обновления DOM
    nextTick(() => {
        messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
    });
  }
};

// Вызываем scrollToBottom при изменении количества сообщений
watch(() => props.messages.length, () => {
  scrollToBottom();
}, { flush: 'post' }); // flush: 'post' гарантирует выполнение после обновления DOM

// Обработчик скролла для подгрузки сообщений
const handleScroll = () => {
  const element = messagesContainer.value;
  if (element && element.scrollTop === 0 && props.hasMoreMessages) {
    emit('load-more');
  }
};

const handleFocus = () => {
  // Логика добавления класса 'focused' удалена, т.к. высота управляется ResizeObserver
  // Можно добавить другую логику при фокусе, если нужно
};

const handleBlur = () => {
  // Логика удаления класса 'focused' удалена
  // Можно добавить другую логику при потере фокуса, если нужно
};

// Форматирование размера файла
const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 Байт';
  const k = 1024;
  const sizes = ['Байт', 'КБ', 'МБ', 'ГБ'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

// --- Автоматическое изменение высоты textarea ---
const adjustTextareaHeight = () => {
  const textarea = messageInputRef.value;
  if (textarea) {
    textarea.style.height = 'auto'; // Сброс высоты для пересчета
    const scrollHeight = textarea.scrollHeight;
    // Ограничиваем максимальную высоту (соответствует max-height в CSS)
    const newHeight = Math.min(scrollHeight, 120);
    textarea.style.height = `${newHeight}px`;
    // Высота родительского блока (.chat-input) обновится через ResizeObserver
    // nextTick(updateChatInputHeight); // Убрано отсюда
  }
};

// Вызываем при изменении текста
const handleInput = (event) => {
  emit('update:newMessage', event.target.value);
  adjustTextareaHeight();
  // Явно вызовем обновление высоты родителя после изменения textarea
  // Это может быть надежнее, чем полагаться только на ResizeObserver в некоторых случаях
  nextTick(updateChatInputHeight);
};

// --- Динамическое изменение высоты ---
let resizeObserver;

const updateChatInputHeight = () => {
  if (chatInputRef.value) {
    chatInputHeight.value = chatInputRef.value.offsetHeight;
  }
};

onMounted(() => {
  // Начальная установка высоты textarea и блока ввода
  adjustTextareaHeight();
  updateChatInputHeight();

  if (chatInputRef.value) {
    resizeObserver = new ResizeObserver(updateChatInputHeight);
    resizeObserver.observe(chatInputRef.value);
  }
  // Убедимся, что высота input установлена после монтирования
  nextTick(updateChatInputHeight);
});

onUnmounted(() => {
  if (resizeObserver && chatInputRef.value) {
    resizeObserver.unobserve(chatInputRef.value);
  }
  if (resizeObserver) {
    resizeObserver.disconnect();
  }
});

</script>

<style scoped>
.chat-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  margin: var(--spacing-lg) 0;
  padding: 0;
  min-height: 500px;
  width: 100%;
  position: relative;
}

.chat-messages {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding: var(--spacing-lg);
  background: var(--color-white);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-grey-light);
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: calc(var(--chat-input-height, 80px) + 15px);
  transition: bottom var(--transition-normal);
}

.chat-input {
  display: flex;
  flex-direction: column;
  padding: var(--spacing-sm) var(--spacing-md);
  background: var(--color-white);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-grey-light);
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  transition: all var(--transition-normal);
  z-index: 10;
  box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.05);
}

.chat-input textarea {
  width: 100%;
  border: none;
  background: transparent;
  resize: none;
  outline: none;
  font-size: var(--font-size-md);
  line-height: 1.5;
  padding: var(--spacing-sm);
  min-height: var(--chat-input-min-height, 40px);
  max-height: var(--chat-input-max-height, 120px);
  transition: all var(--transition-fast);
  color: var(--color-dark);
  overflow-y: hidden;
  height: auto;
}

.chat-input textarea:focus {
  outline: none;
}

.input-area {
  display: flex;
  align-items: flex-end;
  gap: var(--spacing-sm);
  width: 100%;
}

.chat-icons {
  display: flex;
  gap: 6px;
  flex-wrap: nowrap;
  align-items: center;
}

.chat-icon-btn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: transparent;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all var(--transition-fast);
  color: var(--color-grey);
  padding: 0;
  position: relative;
}

.chat-icon-btn:hover {
  color: var(--color-primary);
  background-color: rgba(0, 0, 0, 0.05);
}

.chat-icon-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.chat-icon-btn.send-button {
  background-color: var(--color-primary);
  color: white;
  width: 36px;
  height: 36px;
}

.chat-icon-btn.send-button:hover:not(:disabled) {
  background-color: var(--color-primary-dark);
  color: white;
  transform: scale(1.05);
}

.chat-icon-btn.send-button:disabled {
  background-color: #ccc;
  opacity: 0.7;
}

.chat-icon-btn.recording {
  color: var(--color-danger);
  animation: pulse 1.5s infinite;
}

.chat-icon-btn.recording::after {
  content: '';
  position: absolute;
  width: 8px;
  height: 8px;
  background-color: var(--color-danger);
  border-radius: 50%;
  top: 2px;
  right: 2px;
}

@keyframes pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.1); }
  100% { transform: scale(1); }
}

.attachment-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--color-grey-light);
  max-height: 100px;
  overflow-y: auto;
}

.preview-item {
  position: relative;
  display: flex;
  align-items: center;
  background-color: var(--color-light);
  border-radius: var(--radius-md);
  padding: 4px 8px;
  font-size: var(--font-size-sm);
}

.image-preview {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  margin-right: 8px;
}

.audio-preview,
.video-preview,
.file-preview {
  display: flex;
  align-items: center;
  gap: 5px;
}

.remove-attachment-btn {
  position: absolute;
  top: -5px;
  right: -5px;
  width: 18px;
  height: 18px;
  background-color: rgba(0, 0, 0, 0.6);
  color: white;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  line-height: 1;
  padding: 0;
}

/* Добавляем адаптивные стили для мобильных устройств */
@media (max-width: 768px) {
  .chat-container {
    margin: var(--spacing-sm) auto;
  }
  
  .chat-messages {
    padding: var(--spacing-md);
  }
  
  .chat-input {
    padding: var(--spacing-xs) var(--spacing-sm);
  }
  
  .chat-icon-btn {
    width: 32px;
    height: 32px;
  }
  
  .chat-icon-btn svg {
    width: 20px;
    height: 20px;
  }
}

@media (max-width: 480px) {
  .chat-container {
    margin: var(--spacing-xs) auto;
  }
  
  .chat-messages {
    padding: var(--spacing-sm);
  }
  
  .input-area {
    gap: 4px;
  }
  
  .chat-icon-btn {
    width: 28px;
    height: 28px;
  }
  
  .chat-icon-btn svg {
    width: 18px;
    height: 18px;
  }
  
  .preview-item {
    font-size: var(--font-size-xs);
  }
}
</style> 