<template>
  <SlidePanel 
    :show="show" 
    @close="tryClose"
  >
    <template #header>
      <div class="header-title-block">
        <h2>{{ panelTitle }}</h2>
        <span v-if="!isNew && card?.dateCreate" class="header-date">
          Создано: {{ formatFull(card.dateCreate) }}
        </span>
      </div>
      
      <!-- Вкладки (только для существующих задач) -->
      <TabsPanel
        v-if="!isNew"
        v-model="activeTab"
        :tabs="tabsConfig"
        class="header-tabs"
      />
    </template>

    <template #default>
      <!-- Вкладка редактирования -->
      <TaskEditTab
        v-show="activeTab === 'edit' || isNew"
        ref="editTabRef"
        :card="card"
        :departments="store.departments"
        :labels="store.labels"
        :users="store.users"
        :can-edit="canEdit"
        @preview-image="openImagePreview"
      />

      <!-- Вкладка комментариев -->
      <TaskCommentsTab
        v-show="activeTab === 'comments'"
        ref="commentsTabRef"
        :task-id="card?.id"
        :current-user-id="store.currentUserId"
        :current-user-name="store.currentUserName"
        :current-user-avatar="store.currentUserAvatar"
        :is-project-admin="store.isProjectAdmin"
        :active="activeTab === 'comments'"
        :can-comment="canComment"
        @comments-loaded="commentsCount = $event"
        @preview-file="openImagePreview"
      />
    </template>

    <!-- Footer: скрываем на вкладке комментариев, показываем если есть права редактировать или это архивная задача -->
    <template #footer v-if="activeTab !== 'comments' && (canEdit || isArchived)">
      <div class="footer-left">
        <IconButton 
          v-if="!isNew" 
          icon="trash-2" 
          variant="danger" 
          title="Удалить"
          @click="handleDelete"
        />
        <IconButton 
          v-if="!isNew && canArchive && !isArchived" 
          icon="archive" 
          variant="warning" 
          title="В архив"
          @click="handleArchive"
        />
        <IconButton 
          v-if="!isNew && isArchived" 
          icon="archive-restore" 
          variant="warning" 
          title="Из архива"
          @click="handleRestore"
        />
      </div>
      <!-- Кнопки сохранения — только для редактируемых задач -->
      <ActionButtons
        v-if="canEdit"
        :save-text="isNew ? 'Создать' : 'Сохранить'"
        :loading="isSaving"
        :disabled="!canSave"
        @save="handleSave"
        @cancel="tryClose"
      />
      <!-- Для архивных — только кнопка закрытия -->
      <button v-else class="btn-close-panel" @click="tryClose">
        Закрыть
      </button>
    </template>
  </SlidePanel>

  <!-- Диалог несохранённых изменений -->
  <ConfirmDialog
    :show="showUnsavedDialog"
    type="unsavedChanges"
    @confirm="confirmSave"
    @cancel="cancelClose"
    @discard="confirmDiscard"
  />

  <!-- Диалог удаления задачи -->
  <ConfirmDialog
    :show="showDeleteDialog"
    type="deleteTask"
    :action="confirmDelete"
    @confirm="showDeleteDialog = false"
    @cancel="showDeleteDialog = false"
  />

  <!-- Диалог архивации задачи -->
  <ConfirmDialog
    :show="showArchiveDialog"
    type="archive"
    :action="confirmArchive"
    @confirm="showArchiveDialog = false"
    @cancel="showArchiveDialog = false"
  />

  <!-- Диалог разархивации задачи -->
  <ConfirmDialog
    :show="showRestoreDialog"
    type="restore"
    :action="confirmRestore"
    @confirm="showRestoreDialog = false"
    @cancel="showRestoreDialog = false"
  />

  <!-- Модальное окно просмотра изображения -->
  <ImagePreview 
    :file="previewImage"
    :get-full-url="getFullUrl"
    :show-delete="previewImage?.source === 'comment' ? previewImage?.canDelete : true"
    @close="closeImagePreview"
    @delete="deleteFromPreview"
  />
</template>

<script setup>
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import SlidePanel from '../ui/SlidePanel.vue'
import TabsPanel from '../ui/TabsPanel.vue'
import IconButton from '../ui/IconButton.vue'
import ActionButtons from '../ui/ActionButtons.vue'
import ImagePreview from '../ui/ImagePreview.vue'
import ConfirmDialog from '../ConfirmDialog.vue'
import TaskEditTab from './TaskEditTab.vue'
import TaskCommentsTab from './TaskCommentsTab.vue'
import { taskImageApi, commentImageApi, getFullUrl } from '../../api'
import { useMobile } from '../../composables/useMobile'
import { useLucideIcons } from '../../composables/useLucideIcons'
import { useDateFormat } from '../../composables/useDateFormat'
import { useProjectsStore } from '../../stores/projects'
import { useToast } from '../../composables/useToast'

const { isMobile } = useMobile()
const { refreshIcons } = useLucideIcons()
const toast = useToast()
const { formatFull } = useDateFormat()
const store = useProjectsStore()

// Состояние загрузки для кнопки сохранения
const isSaving = ref(false)

const props = defineProps({
  show: Boolean,
  card: Object,
  columnId: [String, Number],
  isArchived: {
    type: Boolean,
    default: false
  },
  // Callbacks (возвращают Promise)
  onSave: {
    type: Function,
    default: null
  },
  onDelete: {
    type: Function,
    default: null
  },
  onArchive: {
    type: Function,
    default: null
  },
  onRestore: {
    type: Function,
    default: null
  }
})

const emit = defineEmits(['close', 'save', 'delete', 'archive', 'restore'])

// State
const isNew = ref(true)
const activeTab = ref('edit')
const commentsCount = ref(0)

// Refs
const editTabRef = ref(null)
const commentsTabRef = ref(null)

// Dialogs
const showUnsavedDialog = ref(false)
const showDeleteDialog = ref(false)
const showArchiveDialog = ref(false)
const showRestoreDialog = ref(false)

// Image preview
const previewImage = ref(null)

// Panel title
const panelTitle = computed(() => {
  if (isNew.value) return 'Новая задача'
  if (activeTab.value === 'comments') return 'Комментарии'
  return canEdit.value ? 'Редактирование' : 'Просмотр'
})

// Tabs config
const tabsConfig = computed(() => [
  { id: 'edit', icon: 'pencil', title: 'Редактирование' },
  { id: 'comments', icon: 'message-circle', title: 'Комментарии', badge: commentsCount.value || null }
])

// Can save
const canSave = computed(() => {
  const form = editTabRef.value?.form
  return form?.title?.trim() && form?.departmentId
})

// Can archive (только если колонка "Готово")
const canArchive = computed(() => {
  return store.doneColumnId && Number(props.columnId) === store.doneColumnId
})

// Право на редактирование (для новой — create_task, для существующей — canEditTask)
// Архивные задачи нельзя редактировать
const canEdit = computed(() => {
  if (props.isArchived) return false
  if (isNew.value) return store.can('create_task')
  return store.canEditTask(props.card)
})

// Право на создание комментариев
// Архивные задачи нельзя комментировать
const canComment = computed(() => {
  if (isNew.value) return false // В новой задаче нельзя комментировать
  if (props.isArchived) return false // Архивные нельзя комментировать
  return store.canCreateComment(props.card)
})

// Close handling
const tryClose = () => {
  if (editTabRef.value?.hasChanges) {
    showUnsavedDialog.value = true
  } else {
    emit('close')
  }
}

const confirmSave = () => {
  showUnsavedDialog.value = false
  handleSave()
}

const confirmDiscard = () => {
  showUnsavedDialog.value = false
  emit('close')
}

const cancelClose = () => {
  showUnsavedDialog.value = false
}

// Save
const handleSave = async () => {
  if (!canSave.value || isSaving.value) return
  
  isSaving.value = true
  editTabRef.value.fileError = ''
  
  try {
    if (props.card?.id) {
      // Upload new files
      const newFiles = editTabRef.value.getNewFiles()
      for (const file of newFiles) {
        const result = await taskImageApi.upload(props.card.id, file.preview, file.name)
        if (result.success) {
          file.isNew = false
          file.name = result.file.name
          file.preview = result.file.url
        } else {
          editTabRef.value.fileError = result.errors?.file || 'Ошибка загрузки файла'
          return
        }
      }
      
      // Delete marked files
      const filesToDelete = editTabRef.value.getFilesToDelete()
      if (filesToDelete.length > 0) {
        const fileNames = filesToDelete.map(f => f.name)
        const result = await taskImageApi.delete(props.card.id, fileNames)
        if (!result.success) {
          editTabRef.value.fileError = result.errors?.file || 'Ошибка удаления файла'
          return
        }
      }
      
      editTabRef.value.removeDeletedFiles()
    }
    
    const formData = editTabRef.value.getFormData()
    const taskData = {
      ...formData,
      id: props.card?.id
    }
    
    // Вызываем callback и ждём завершения
    if (props.onSave) {
      await props.onSave(taskData)
    } else {
      emit('save', taskData)
    }
    
    toast.success(props.card?.id ? 'Задача сохранена' : 'Задача создана')
  } catch (error) {
    toast.error('Ошибка сохранения задачи')
    console.error('Error saving task:', error)
  } finally {
    isSaving.value = false
  }
}

// Delete
const handleDelete = () => {
  showDeleteDialog.value = true
}

const confirmDelete = async () => {
  if (!props.card?.id) {
    throw new Error('Задача не выбрана')
  }
  
  if (props.onDelete) {
    await props.onDelete(props.card.id)
  } else {
    emit('delete', props.card.id)
  }
  
  toast.success('Задача удалена')
}

// Archive
const handleArchive = () => {
  showArchiveDialog.value = true
}

const confirmArchive = async () => {
  if (!props.card?.id) {
    throw new Error('Задача не выбрана')
  }
  
  if (props.onArchive) {
    await props.onArchive(props.card.id)
  } else {
    emit('archive', props.card.id)
  }
  
  toast.success('Задача в архиве')
}

// Restore
const handleRestore = () => {
  showRestoreDialog.value = true
}

const confirmRestore = async () => {
  if (!props.card?.id) {
    throw new Error('Задача не выбрана')
  }
  
  if (props.onRestore) {
    await props.onRestore(props.card.id)
  } else {
    emit('restore', props.card.id)
  }
  
  toast.success('Задача восстановлена')
}

// Image preview
const openImagePreview = (file) => {
  previewImage.value = file
  nextTick(refreshIcons)
}

const closeImagePreview = () => {
  previewImage.value = null
}

const deleteFromPreview = async () => {
  if (!previewImage.value) return
  
  // Удаление файла из комментария
  if (previewImage.value.source === 'comment') {
    const { commentId, name } = previewImage.value
    try {
      const result = await commentImageApi.delete(commentId, name)
      if (result.success) {
        closeImagePreview()
        // Перезагружаем комментарии
        commentsTabRef.value?.loadComments()
      }
    } catch (e) {
      console.error('Ошибка удаления файла:', e)
    }
    return
  }
  
  // Удаление файла из задачи (старая логика)
  const files = editTabRef.value?.attachedFiles || []
  const index = files.findIndex(
    f => f.name === previewImage.value.name && f.size === previewImage.value.size
  )
  if (index !== -1) {
    closeImagePreview()
    // Trigger file remove in edit tab
    editTabRef.value?.handleFileRemove?.(index)
  }
}

// Watch show
watch(() => props.show, async (newVal) => {
  if (newVal) {
    isNew.value = !props.card
    activeTab.value = 'edit'
    commentsCount.value = props.card?.comments_count || 0
    previewImage.value = null
    isSaving.value = false // Сброс состояния кнопки сохранения
    
    // Обновляем права пользователя (могли измениться администратором)
    await store.fetchUsers()
    
    // Reset comments tab
    commentsTabRef.value?.reset()
    
    // Load form data
    await nextTick()
    editTabRef.value?.loadFromCard(props.card)
    editTabRef.value?.setDetailsContent(props.card?.details || '')
    
    await nextTick()
    editTabRef.value?.saveInitialForm()
    // Не фокусируем поле автоматически, чтобы не открывалась клавиатура
    refreshIcons()
  }
})
</script>

<style scoped>
.header-title-block {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.header-title-block h2 {
  margin: 0;
}

.header-date {
  font-size: 12px;
  color: var(--text-muted);
}

.header-tabs {
  margin-right: 12px;
}

.footer-left {
  display: flex;
  gap: 8px;
}

.btn-close-panel {
  padding: 12px 24px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  color: var(--text-secondary);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s;
}

.btn-close-panel:hover {
  background: rgba(255, 255, 255, 0.12);
  color: var(--text-primary);
}
</style>
