<template>
  <div class="comments-tab">
    <!-- Список комментариев -->
    <div class="comments-list" ref="commentsListRef">
      <div v-if="loading" class="comments-loading">
        <span class="loader"></span>
        Загрузка комментариев...
      </div>
      
      <div v-else-if="flatCommentsWithLevel.length === 0" class="comments-empty">
        <i data-lucide="message-circle"></i>
        <span>Пока нет комментариев</span>
      </div>
      
      <CommentItem
        v-else
        v-for="comment in flatCommentsWithLevel" 
        :key="comment.id"
        :comment="comment"
        :level="comment.level"
        :is-own="comment.id_accounts === currentUserId"
        :can-edit="canEditComment(comment)"
        :is-editing="editingCommentId === comment.id"
        :edit-text="editingCommentText"
        :get-full-url="getFullUrl"
        @update:edit-text="editingCommentText = $event"
        @reply="startReply"
        @edit="startEditComment"
        @delete="confirmDeleteComment"
        @cancel-edit="cancelEditComment"
        @save-edit="saveEditComment"
        @preview-file="(file) => previewFile(file, comment)"
      />
    </div>

    <!-- Форма добавления комментария -->
    <CommentForm
      v-model="newCommentText"
      :replying-to="replyingTo"
      :is-sending="isSendingComment"
      ref="commentFormRef"
      @send="sendComment"
      @cancel-reply="cancelReply"
    />

    <!-- Диалог удаления комментария -->
    <ConfirmDialog
      :show="showDeleteDialog"
      title="Удалить комментарий?"
      message="Комментарий будет удалён навсегда."
      confirm-text="Удалить"
      variant="danger"
      @confirm="deleteComment"
      @cancel="showDeleteDialog = false"
    />
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUpdated, onUnmounted, nextTick } from 'vue'
import CommentItem from './CommentItem.vue'
import CommentForm from './CommentForm.vue'
import ConfirmDialog from '../ConfirmDialog.vue'
import { commentsApi, commentImageApi, getFullUrl } from '../../api'

const props = defineProps({
  taskId: {
    type: Number,
    default: null
  },
  currentUserId: {
    type: Number,
    default: null
  },
  isProjectAdmin: {
    type: Boolean,
    default: false
  },
  active: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['comments-loaded', 'preview-file'])

// Состояние
const comments = ref([])
const loading = ref(false)
const newCommentText = ref('')
const isSendingComment = ref(false)
const editingCommentId = ref(null)
const editingCommentText = ref('')
const commentToDelete = ref(null)
const showDeleteDialog = ref(false)
const replyingTo = ref(null)

// Refs
const commentsListRef = ref(null)
const commentFormRef = ref(null)

// Интервал обновления
let refreshInterval = null

// Построение дерева комментариев
const commentsTree = computed(() => {
  const map = new Map()
  const roots = []
  
  comments.value.forEach(c => {
    map.set(c.id, { ...c, children: [] })
  })
  
  comments.value.forEach(c => {
    const comment = map.get(c.id)
    if (c.id_answer && map.has(c.id_answer)) {
      map.get(c.id_answer).children.push(comment)
    } else {
      roots.push(comment)
    }
  })
  
  return roots
})

// Плоский список с уровнями вложенности
const flatCommentsWithLevel = computed(() => {
  const result = []
  
  const flatten = (items, level = 0) => {
    items.forEach(item => {
      result.push({ ...item, level })
      if (item.children?.length) {
        flatten(item.children, level + 1)
      }
    })
  }
  
  flatten(commentsTree.value)
  return result
})

// Загрузка комментариев
const loadComments = async (silent = false) => {
  if (!props.taskId) return
  
  if (!silent) {
    loading.value = true
  }
  
  try {
    const result = await commentsApi.getByTask(props.taskId)
    if (result.success) {
      const newData = result.data
      const oldData = comments.value
      
      // Проверяем изменения
      const hasChanges = 
        newData.length !== oldData.length ||
        newData.some((newComment, i) => {
          const oldComment = oldData[i]
          return !oldComment || 
                 newComment.id !== oldComment.id ||
                 newComment.text !== oldComment.text
        })
      
      if (hasChanges) {
        comments.value = newData
        emit('comments-loaded', newData.length)
        await nextTick()
        refreshIcons()
      }
    }
  } catch (e) {
    console.error('Ошибка загрузки комментариев:', e)
  } finally {
    if (!silent) {
      loading.value = false
    }
  }
}

// Автообновление
const startRefresh = () => {
  stopRefresh()
  const interval = (window.APP_CONFIG?.IDLE_REFRESH_SECONDS || 30) * 1000
  refreshInterval = setInterval(async () => {
    if (props.active && props.taskId) {
      await loadComments(true)
    }
  }, interval)
}

const stopRefresh = () => {
  if (refreshInterval) {
    clearInterval(refreshInterval)
    refreshInterval = null
  }
}

// Отправка комментария
const sendComment = async () => {
  const hasText = newCommentText.value.trim()
  const files = commentFormRef.value?.getFiles() || []
  const hasFiles = files.length > 0
  
  if ((!hasText && !hasFiles) || !props.taskId) return
  
  isSendingComment.value = true
  try {
    const id_answer = replyingTo.value?.id || null
    // Если нет текста но есть файлы — отправляем пустой текст (или пробел)
    const text = hasText ? newCommentText.value : ' '
    const result = await commentsApi.create(props.taskId, text, id_answer)
    
    if (result.success) {
      const commentId = result.comment.id
      
      // Загружаем файлы к созданному комментарию
      if (hasFiles) {
        const uploadedFiles = []
        for (const file of files) {
          try {
            const uploadResult = await commentImageApi.upload(commentId, file.data, file.name)
            if (uploadResult.success) {
              uploadedFiles.push(uploadResult.file)
            }
          } catch (e) {
            console.error('Ошибка загрузки файла:', e)
          }
        }
        // Обновляем file_img в комментарии
        result.comment.file_img = uploadedFiles
      }
      
      comments.value.push(result.comment)
      emit('comments-loaded', comments.value.length)
      newCommentText.value = ''
      commentFormRef.value?.setContent('')
      commentFormRef.value?.clearFiles()
      replyingTo.value = null
      await nextTick()
      scrollToBottom()
      refreshIcons()
    }
  } catch (e) {
    console.error('Ошибка отправки комментария:', e)
  } finally {
    isSendingComment.value = false
  }
}

// Ответ
const startReply = (comment) => {
  replyingTo.value = comment
  commentFormRef.value?.focus()
  nextTick(refreshIcons)
}

const cancelReply = () => {
  replyingTo.value = null
}

// Редактирование
const canEditComment = (comment) => {
  return comment.id_accounts === props.currentUserId || props.isProjectAdmin
}

const startEditComment = (comment) => {
  editingCommentId.value = comment.id
  editingCommentText.value = comment.text
}

const cancelEditComment = () => {
  editingCommentId.value = null
  editingCommentText.value = ''
}

const saveEditComment = async () => {
  if (!editingCommentText.value.trim() || !editingCommentId.value) return
  
  try {
    const result = await commentsApi.update(editingCommentId.value, editingCommentText.value)
    if (result.success) {
      const index = comments.value.findIndex(c => c.id === editingCommentId.value)
      if (index !== -1) {
        comments.value[index] = result.comment
      }
      cancelEditComment()
      refreshIcons()
    }
  } catch (e) {
    console.error('Ошибка обновления комментария:', e)
  }
}

// Удаление
const confirmDeleteComment = (comment) => {
  commentToDelete.value = comment
  showDeleteDialog.value = true
}

const deleteComment = async () => {
  if (!commentToDelete.value) return
  
  try {
    const result = await commentsApi.delete(commentToDelete.value.id)
    if (result.success) {
      comments.value = comments.value.filter(c => c.id !== commentToDelete.value.id)
      emit('comments-loaded', comments.value.length)
    }
  } catch (e) {
    console.error('Ошибка удаления комментария:', e)
  } finally {
    showDeleteDialog.value = false
    commentToDelete.value = null
  }
}

// Превью файла (пробрасываем в родитель)
const previewFile = (file, comment) => {
  // Проверяем права на удаление: автор комментария или админ проекта
  const canDelete = comment.id_accounts === props.currentUserId || props.isProjectAdmin
  
  emit('preview-file', {
    name: file.name,
    size: file.size,
    preview: file.url,
    source: 'comment',
    commentId: comment.id,
    canDelete
  })
}

// Хелперы
const scrollToBottom = () => {
  if (commentsListRef.value) {
    commentsListRef.value.scrollTop = commentsListRef.value.scrollHeight
  }
}

const refreshIcons = () => {
  if (window.lucide) {
    window.lucide.createIcons()
  }
}

// Сброс состояния
const reset = () => {
  comments.value = []
  newCommentText.value = ''
  editingCommentId.value = null
  editingCommentText.value = ''
  replyingTo.value = null
  stopRefresh()
}

// Watch для активации/деактивации
watch(() => props.active, (newVal) => {
  if (newVal && props.taskId) {
    if (comments.value.length === 0) {
      loadComments()
    }
    startRefresh()
  } else {
    stopRefresh()
  }
})

// Watch для смены задачи
watch(() => props.taskId, (newVal, oldVal) => {
  if (newVal !== oldVal) {
    reset()
    if (props.active && newVal) {
      loadComments()
      startRefresh()
    }
  }
})

onMounted(() => {
  if (props.active && props.taskId) {
    loadComments()
    startRefresh()
  }
  refreshIcons()
})

onUpdated(refreshIcons)
onUnmounted(stopRefresh)

// Expose для родителя
defineExpose({
  reset,
  loadComments,
  commentsCount: computed(() => comments.value.length)
})
</script>

<style scoped>
.comments-tab {
  height: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0; /* Важно для flex overflow */
}

.comments-list {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 2px;  /* Для outline при редактировании */
  padding-right: 6px;
  margin-bottom: 16px;
  min-height: 100px;
  max-height: calc(100vh - 400px);
}

/* Mobile: убираем max-height, используем flex */
@media (max-width: 768px) {
  .comments-list {
    max-height: none;
    min-height: 50px;
    margin-bottom: 12px;
  }
}

.comments-loading,
.comments-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 40px 20px;
  color: var(--text-muted);
  font-size: 14px;
}

.comments-empty i {
  width: 32px;
  height: 32px;
  opacity: 0.5;
}

.loader {
  width: 24px;
  height: 24px;
  border: 2px solid rgba(255, 255, 255, 0.1);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
