<template>
  <div class="comments-tab">
    <!-- Список комментариев -->
    <div class="comments-list" ref="commentsListRef">
      <Loader v-if="loading" text="Загрузка комментариев..." :inline="true" />
      
      <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)"
        :can-reply="canComment"
        :get-full-url="getFullUrl"
        @reply="startReply"
        @edit="startEditComment"
        @delete="confirmDeleteComment"
        @preview-file="(file) => previewFile(file, comment)"
      />
    </div>

    <!-- Кнопка добавления комментария -->
    <div v-if="canComment" class="comment-action-bar">
      <button class="btn-new-comment" @click="openEditorForCreate">
        <i data-lucide="message-square-plus"></i>
        Написать комментарий
      </button>
    </div>

    <!-- Диалог удаления комментария -->
    <ConfirmDialog
      :show="showDeleteDialog"
      type="deleteComment"
      :action="deleteComment"
      @confirm="showDeleteDialog = false"
      @cancel="showDeleteDialog = false"
    />

    <!-- Универсальная панель редактора -->
    <ContentEditorPanel
      :show="editorOpen"
      :title="editorTitle"
      :subtitle="editorSubtitle"
      :avatar-url="editorAvatarUrl"
      :text="editorText"
      :existing-files="editorExistingFiles"
      :is-saving="isSavingEditor"
      placeholder="Текст комментария..."
      text-label="Текст комментария"
      :save-button-text="editorMode === 'create' ? 'Отправить' : 'Сохранить'"
      @save="handleEditorSave"
      @close="closeEditor"
    />
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import CommentItem from './CommentItem.vue'
import ConfirmDialog from '../ConfirmDialog.vue'
import ContentEditorPanel from './ContentEditorPanel.vue'
import Loader from '../ui/Loader.vue'
import { commentsApi, commentImageApi, getFullUrl } from '../../api'
import { useLucideIcons } from '../../composables/useLucideIcons'
import { useAutoRefresh } from '../../composables/useAutoRefresh'

const props = defineProps({
  taskId: {
    type: Number,
    default: null
  },
  currentUserId: {
    type: Number,
    default: null
  },
  currentUserName: {
    type: String,
    default: ''
  },
  currentUserAvatar: {
    type: String,
    default: ''
  },
  isProjectAdmin: {
    type: Boolean,
    default: false
  },
  active: {
    type: Boolean,
    default: false
  },
  canComment: {
    type: Boolean,
    default: true
  }
})

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

const { refreshIcons } = useLucideIcons()

// Состояние списка комментариев
const comments = ref([])
const loading = ref(false)
const commentToDelete = ref(null)
const showDeleteDialog = ref(false)

// Состояние редактора
const editorOpen = ref(false)
const editorMode = ref('create') // 'create' | 'edit'
const editorText = ref('')
const editorExistingFiles = ref([])
const editingCommentId = ref(null)
const editingComment = ref(null)
const replyingTo = ref(null)
const isSavingEditor = ref(false)

// Computed для редактора
const editorTitle = computed(() => {
  if (editorMode.value === 'edit') return 'Редактирование'
  if (replyingTo.value) return 'Ответ'
  return 'Новый комментарий'
})

const editorSubtitle = computed(() => {
  if (editorMode.value === 'edit' && editingComment.value) {
    return editingComment.value.author_name
  }
  if (replyingTo.value) {
    return `для ${replyingTo.value.author_name}`
  }
  return props.currentUserName || ''
})

const editorAvatarUrl = computed(() => {
  if (editorMode.value === 'edit' && editingComment.value?.author_avatar) {
    return getFullUrl(editingComment.value.author_avatar)
  }
  if (props.currentUserAvatar) {
    return getFullUrl(props.currentUserAvatar)
  }
  return ''
})

// Refs
const commentsListRef = ref(null)

// Автообновление комментариев
const { start: startRefresh, stop: stopRefresh } = useAutoRefresh('comments', async () => {
  if (props.active && props.taskId) {
    await loadComments(true)
  }
})

// Построение дерева комментариев
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)
        
        // Для первичной загрузки: убираем loading, ждём рендер, прокручиваем мгновенно
        if (!silent) {
          loading.value = false
          await nextTick()
          refreshIcons()
          // Мгновенная прокрутка к последнему комментарию
          if (commentsListRef.value) {
            commentsListRef.value.scrollTop = commentsListRef.value.scrollHeight
          }
        } else {
          await nextTick()
          refreshIcons()
        }
      }
    }
  } catch (e) {
    console.error('Ошибка загрузки комментариев:', e)
  } finally {
    if (!silent && loading.value) {
      loading.value = false
    }
  }
}

// startRefresh и stopRefresh определены через useAutoRefresh выше

// ========== Редактор: открытие/закрытие ==========

const openEditorForCreate = () => {
  editorMode.value = 'create'
  editorText.value = ''
  editorExistingFiles.value = []
  editingCommentId.value = null
  editingComment.value = null
  replyingTo.value = null
  editorOpen.value = true
}

const startReply = (comment) => {
  editorMode.value = 'create'
  editorText.value = ''
  editorExistingFiles.value = []
  editingCommentId.value = null
  editingComment.value = null
  replyingTo.value = comment
  editorOpen.value = true
}

const startEditComment = (comment) => {
  editorMode.value = 'edit'
  editorText.value = comment.text
  editorExistingFiles.value = [...(comment.file_img || [])]
  editingCommentId.value = comment.id
  editingComment.value = comment
  replyingTo.value = null
  editorOpen.value = true
}

const closeEditor = () => {
  editorOpen.value = false
  editorMode.value = 'create'
  editorText.value = ''
  editorExistingFiles.value = []
  editingCommentId.value = null
  editingComment.value = null
  replyingTo.value = null
}

// ========== Сохранение ==========

const handleEditorSave = async ({ text, newFiles, filesToDelete }) => {
  if (isSavingEditor.value) return
  
  const hasText = text.trim()
  const hasFiles = newFiles.length > 0
  
  if (!hasText && !hasFiles) return
  
  isSavingEditor.value = true
  
  try {
    if (editorMode.value === 'create') {
      await createComment(text, newFiles)
    } else {
      await updateComment(text, newFiles, filesToDelete)
    }
    
    closeEditor()
    refreshIcons()
  } catch (e) {
    console.error('Ошибка сохранения:', e)
  } finally {
    isSavingEditor.value = false
  }
}

const createComment = async (text, newFiles) => {
  const id_answer = replyingTo.value?.id || null
  const commentText = text.trim() ? text : ' '
  
  const result = await commentsApi.create(props.taskId, commentText, id_answer)
  
  if (result.success) {
    const commentId = result.comment.id
    
    // Загружаем файлы к созданному комментарию
    if (newFiles.length > 0) {
      const uploadedFiles = []
      for (const file of newFiles) {
        try {
          const uploadResult = await commentImageApi.upload(commentId, file.data, file.name)
          if (uploadResult.success) {
            uploadedFiles.push(uploadResult.file)
          }
        } catch (e) {
          console.error('Ошибка загрузки файла:', e)
        }
      }
      result.comment.file_img = uploadedFiles
    }
    
    comments.value.push(result.comment)
    emit('comments-loaded', comments.value.length)
    await nextTick()
    scrollToBottom()
  }
}

const updateComment = async (text, newFiles, filesToDelete) => {
  if (!editingCommentId.value) return
  
  // 1. Обновляем текст комментария
  const result = await commentsApi.update(editingCommentId.value, text)
  if (!result.success) throw new Error('Ошибка обновления текста')
  
  // 2. Удаляем отмеченные файлы
  if (filesToDelete.length > 0) {
    await commentImageApi.delete(editingCommentId.value, filesToDelete)
  }
  
  // 3. Загружаем новые файлы
  const uploadedFiles = []
  for (const file of newFiles) {
    try {
      const uploadResult = await commentImageApi.upload(editingCommentId.value, file.data, file.name)
      if (uploadResult.success) {
        uploadedFiles.push(uploadResult.file)
      }
    } catch (e) {
      console.error('Ошибка загрузки файла:', e)
    }
  }
  
  // 4. Обновляем комментарий в списке
  const index = comments.value.findIndex(c => c.id === editingCommentId.value)
  if (index !== -1) {
    const updatedComment = result.comment
    // Обновляем file_img: убираем удалённые, добавляем новые
    const remainingFiles = (editorExistingFiles.value || []).filter(f => !filesToDelete.includes(f.name))
    updatedComment.file_img = [...remainingFiles, ...uploadedFiles]
    comments.value[index] = updatedComment
  }
}

// ========== Редактирование (права) ==========

const canEditComment = (comment) => {
  // Для архивных задач — нельзя редактировать комментарии
  if (!props.canComment) return false
  return comment.id_accounts === props.currentUserId || props.isProjectAdmin
}

// ========== Удаление ==========

const confirmDeleteComment = (comment) => {
  commentToDelete.value = comment
  showDeleteDialog.value = true
}

const deleteComment = async () => {
  if (!commentToDelete.value) {
    throw new Error('Комментарий не выбран')
  }
  
  const result = await commentsApi.delete(commentToDelete.value.id)
  if (!result.success) {
    throw new Error('Ошибка удаления комментария')
  }
  
  comments.value = comments.value.filter(c => c.id !== commentToDelete.value.id)
  emit('comments-loaded', comments.value.length)
  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 = () => {
  setTimeout(() => {
    if (commentsListRef.value) {
      commentsListRef.value.scrollTop = commentsListRef.value.scrollHeight
    }
  }, 100)
}

// Сброс состояния
const reset = () => {
  comments.value = []
  closeEditor()
  stopRefresh()
}

// ========== Watchers ==========

watch(() => props.active, (newVal) => {
  if (newVal && props.taskId) {
    if (comments.value.length === 0) {
      loadComments()
    }
    startRefresh()
  } else {
    stopRefresh()
  }
})

watch(() => props.taskId, (newVal, oldVal) => {
  if (newVal !== oldVal) {
    reset()
    if (props.active && newVal) {
      loadComments()
      startRefresh()
    }
  }
})

// ========== Lifecycle ==========

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

onUnmounted(stopRefresh)

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

<style scoped>
.comments-tab {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  overflow: hidden;
}

.comments-list {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0 6px 16px 2px;
  min-height: 0;
}

/* Стилизация скроллбара */
.comments-list::-webkit-scrollbar {
  width: 6px;
}

.comments-list::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.04);
  border-radius: 3px;
}

.comments-list::-webkit-scrollbar-thumb {
  background: rgba(0, 212, 170, 0.3);
  border-radius: 3px;
}

.comments-list::-webkit-scrollbar-thumb:hover {
  background: rgba(0, 212, 170, 0.5);
}

.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;
}

/* ========== Action Bar ========== */
.comment-action-bar {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  padding-top: 16px;
  padding-bottom: calc(var(--safe-area-bottom, 0px));
  margin-top: auto;
}

.btn-new-comment {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 14px;
  background: var(--accent);
  border: none;
  border-radius: 10px;
  color: #000;
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s;
}

.btn-new-comment i {
  width: 18px;
  height: 18px;
}

.btn-new-comment:hover {
  filter: brightness(1.1);
}

.btn-new-comment:active {
  filter: brightness(0.9);
}
</style>
