<template>
  <div
    class="group bg-white border border-gray-200 rounded-xl p-4 hover:border-indigo-300 hover:shadow-sm transition-all cursor-pointer relative"
    @click="$router.push(`/document/${doc.id}`)"
  >
    <div class="flex items-start gap-3">
      <!-- Icon -->
      <div class="w-9 h-9 rounded-lg bg-indigo-50 flex items-center justify-center shrink-0 mt-0.5">
        <AppIcon name="document" class="w-5 h-5 text-indigo-500" />
      </div>

      <div class="flex-1 min-w-0">
        <p class="font-medium text-gray-900 text-sm truncate">{{ doc.original_name }}</p>
        <p class="text-xs text-gray-400 mt-0.5">{{ formatDate(doc.created_at) }} · {{ formatSize(doc.size_bytes) }}</p>

        <!-- Topics (only when classified) -->
        <div v-if="doc.status === 'ready'" class="flex flex-wrap gap-1 mt-2">
          <TopicBadge
            v-for="topicName in doc.topics"
            :key="topicName"
            :name="topicName"
            :color="topicColor(topicName)"
          />
          <span v-if="!doc.topics?.length" class="text-xs text-gray-300 italic">unclassified</span>
        </div>

        <!-- Processing indicator -->
        <div v-else-if="doc.status === 'processing'" class="flex items-center gap-1.5 mt-2">
          <span class="animate-spin rounded-full border-2 border-indigo-400 border-t-transparent w-3 h-3 shrink-0"></span>
          <span class="text-xs text-indigo-500 font-medium">Classifying…</span>
        </div>

        <!-- Pending / queued indicator -->
        <div v-else-if="doc.status === 'pending'" class="mt-2">
          <span class="bg-gray-100 text-gray-500 text-xs font-medium px-2 py-1 rounded-full">Queued</span>
        </div>

        <!-- Shared indicator pill -->
        <div v-if="isShared" class="mt-2">
          <span class="bg-indigo-50 text-indigo-600 text-xs font-medium px-2 py-1 rounded-full">Shared</span>
        </div>

        <!-- Classification failed badge + Re-analyze button -->
        <div v-if="doc.status === 'classification_failed'" class="mt-2 flex items-center gap-2">
          <span class="bg-red-50 text-red-600 text-xs font-medium px-2 py-1 rounded-full">Classification failed</span>
          <button
            @click.stop="reanalyze"
            :disabled="reanalyzing"
            class="text-xs text-indigo-600 hover:text-indigo-700 font-semibold disabled:opacity-50"
          >
            <span v-if="reanalyzing">Re-analyzing…</span>
            <span v-else>Re-analyze</span>
          </button>
        </div>
      </div>

      <!-- Action buttons (hover-reveal) -->
      <div class="opacity-0 group-hover:opacity-100 transition-opacity flex items-center gap-1 shrink-0">
        <!-- Move to folder -->
        <div class="relative">
          <button
            ref="pickerTriggerEl"
            @click.stop="toggleFolderPicker"
            aria-label="Move to folder"
            class="min-h-[44px] min-w-[44px] flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-indigo-600 hover:bg-indigo-50 active:bg-indigo-100 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1"
          >
            <AppIcon name="folderMove" class="w-4 h-4" />
          </button>
        </div>
        <!-- Share -->
        <button
          @click.stop="openShareModal"
          aria-label="Share document"
          class="min-h-[44px] min-w-[44px] flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-indigo-600 hover:bg-indigo-50 active:bg-indigo-100 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1"
        >
          <AppIcon name="share" class="w-4 h-4" />
        </button>
      </div>
    </div>

    <!-- ShareModal -->
    <ShareModal
      v-if="showShareModal"
      :doc="doc"
      @close="showShareModal = false"
      @unshared="isShared = false"
    />
  </div>

  <!-- Teleported folder picker — avoids overflow:hidden clipping -->
  <Teleport to="body">
    <div
      v-if="showFolderPicker"
      :style="pickerStyle"
      data-test="folder-picker"
      class="fixed z-[9999] bg-white border border-gray-200 rounded-xl shadow-lg overflow-y-auto py-1"
      style="max-height: 240px;"
      @click.stop
    >
      <button
        class="w-full text-left px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 active:bg-gray-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-indigo-500"
        @click.stop="moveToFolder(null)"
      >Root (no folder)</button>
      <button
        v-for="folder in allFolders"
        :key="folder.id"
        class="w-full text-left px-3 py-2 text-sm text-gray-700 hover:bg-indigo-50 hover:text-indigo-600 active:bg-indigo-100 truncate focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-indigo-500"
        @click.stop="moveToFolder(folder.id)"
      >{{ folder.name }}</button>
      <p v-if="!allFolders.length" class="px-3 py-2 text-xs text-gray-400">No folders yet</p>
    </div>
  </Teleport>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import AppIcon from '../ui/AppIcon.vue'
import { useTopicsStore } from '../../stores/topics.js'
import { useFoldersStore } from '../../stores/folders.js'
import { moveDocument, classifyDocument } from '../../api/client.js'
import TopicBadge from '../topics/TopicBadge.vue'
import ShareModal from '../sharing/ShareModal.vue'
import { formatDate, formatSize } from '../../utils/formatters.js'

const props = defineProps({
  doc: Object,
})

const emit = defineEmits(['reclassified'])

const isShared = ref(props.doc?.is_shared ?? false)
watch(() => props.doc?.is_shared, v => { isShared.value = v ?? false })

const topicsStore = useTopicsStore()
const foldersStore = useFoldersStore()
const showShareModal = ref(false)
const showFolderPicker = ref(false)
const reanalyzing = ref(false)
const pickerTriggerEl = ref(null)
const pickerStyle = ref({})

const allFolders = computed(() => foldersStore.rootFolders)

function openShareModal() {
  showShareModal.value = true
}

function updatePickerPosition() {
  if (!pickerTriggerEl.value) return
  const rect = pickerTriggerEl.value.getBoundingClientRect()
  const spaceBelow = window.innerHeight - rect.bottom
  const dropH = 240
  if (spaceBelow >= dropH || spaceBelow > 120) {
    pickerStyle.value = {
      top: `${rect.bottom + 4}px`,
      left: `${rect.left}px`,
      width: '192px',
    }
  } else {
    pickerStyle.value = {
      bottom: `${window.innerHeight - rect.top + 4}px`,
      left: `${rect.left}px`,
      width: '192px',
    }
  }
}

function toggleFolderPicker() {
  if (showFolderPicker.value) {
    showFolderPicker.value = false
  } else {
    updatePickerPosition()
    showFolderPicker.value = true
  }
}

function onScroll() {
  if (showFolderPicker.value) updatePickerPosition()
}

function closeFolderPicker(e) {
  if (
    !e.target.closest('[data-test="folder-picker"]') &&
    !e.target.closest('.relative')
  ) {
    showFolderPicker.value = false
  }
}

onMounted(() => {
  document.addEventListener('click', closeFolderPicker)
  window.addEventListener('scroll', onScroll, true)
  window.addEventListener('resize', onScroll)
})
onUnmounted(() => {
  document.removeEventListener('click', closeFolderPicker)
  window.removeEventListener('scroll', onScroll, true)
  window.removeEventListener('resize', onScroll)
})

async function moveToFolder(folderId) {
  showFolderPicker.value = false
  try {
    await moveDocument(props.doc.id, folderId)
  } catch (e) {
    console.error('Move failed:', e.message)
  }
}

function topicColor(name) {
  return topicsStore.topics.find(t => t.name === name)?.color ?? '#6366f1'
}

async function reanalyze() {
  reanalyzing.value = true
  try {
    await classifyDocument(props.doc.id)
    emit('reclassified', props.doc.id)
  } catch (e) {
    console.error('Re-analyze failed:', e.message)
  } finally {
    setTimeout(() => { reanalyzing.value = false }, 500)
  }
}

</script>
