<template>
  <div class="upload-view">
    <h1 class="page-title">Book Library</h1>
    <p v-if="uploadEnabled" class="page-subtitle">Upload medical textbooks (PDF) to build the knowledge base.</p>

    <!-- Upload Section -->
    <div v-if="uploadEnabled" class="upload-section card">
      <h2 class="section-title">Upload a Book</h2>

      <div
        class="drop-zone"
        :class="{ 'drop-zone--active': isDragging, 'drop-zone--has-file': selectedFile }"
        @dragover.prevent="isDragging = true"
        @dragleave="isDragging = false"
        @drop.prevent="onDrop"
        @click="fileInput?.click()"
      >
        <input
          ref="fileInput"
          type="file"
          accept=".pdf,application/pdf"
          class="file-input-hidden"
          @change="onFileChange"
        />
        <div v-if="!selectedFile" class="drop-zone-content">
          <span class="drop-zone-icon">📄</span>
          <p class="drop-zone-text">Drop a PDF here or click to browse</p>
          <p class="drop-zone-hint">Maximum size: 100 MB</p>
        </div>
        <div v-else class="drop-zone-selected">
          <span class="drop-zone-icon">✅</span>
          <p class="drop-zone-text">{{ selectedFile.name }}</p>
          <p class="drop-zone-hint">{{ formatFileSize(selectedFile.size) }}</p>
        </div>
      </div>

      <div class="upload-controls">
        <button
          class="btn btn-secondary"
          :disabled="!selectedFile || bookStore.uploading"
          @click="clearFile"
        >
          Clear
        </button>
        <button
          class="btn btn-primary"
          :disabled="!selectedFile || bookStore.uploading"
          @click="handleUpload"
        >
          <span v-if="bookStore.uploading" class="spinner"></span>
          {{ bookStore.uploading ? 'Uploading...' : 'Upload' }}
        </button>
      </div>

      <div v-if="uploadSuccess" class="upload-feedback upload-feedback--success">
        Book uploaded successfully — embedding will start shortly.
      </div>
      <div v-if="uploadError" class="upload-feedback upload-feedback--error">
        {{ uploadError }}
      </div>
    </div>

    <!-- Book List -->
    <div class="book-list-section">
      <div class="book-list-header">
        <h2 class="section-title">Uploaded Books</h2>
        <button class="btn btn-secondary" :disabled="bookStore.loading" @click="bookStore.fetchBooks()">
          <span v-if="bookStore.loading" class="spinner spinner-dark"></span>
          {{ bookStore.loading ? 'Refreshing...' : 'Refresh' }}
        </button>
      </div>

      <div v-if="bookStore.loading && bookStore.books.length === 0" class="empty-state">
        <div class="spinner spinner-dark" style="width:32px;height:32px;margin:0 auto 1rem;"></div>
        <p class="empty-state-text">Loading library...</p>
      </div>

      <div v-else-if="bookStore.books.length === 0" class="empty-state">
        <div class="empty-state-icon">📚</div>
        <p class="empty-state-text">No books uploaded yet</p>
        <p class="empty-state-hint">Upload a medical textbook PDF to get started.</p>
      </div>

      <div v-else class="book-grid">
        <BookCard
          v-for="book in bookStore.books"
          :key="book.id"
          :book="book"
          :deleting="deletingId === book.id"
          :delete-enabled="deleteEnabled"
          @delete="handleDelete"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, inject } from 'vue'
import { useBookStore } from '@/stores/bookStore'
import BookCard from '@/components/BookCard.vue'
import { env } from '@/env'

const uploadEnabled = env('VITE_UPLOAD_ENABLED') !== 'false'
const deleteEnabled = env('VITE_DELETE_ENABLED') !== 'false'

const bookStore = useBookStore()
const showToast = inject<(msg: string, type?: 'error' | 'success') => void>('showToast')

const fileInput = ref<HTMLInputElement | null>(null)
const selectedFile = ref<File | null>(null)
const isDragging = ref(false)
const uploadSuccess = ref(false)
const uploadError = ref<string | null>(null)
const deletingId = ref<string | null>(null)

let pollInterval: ReturnType<typeof setInterval> | null = null

onMounted(async () => {
  await bookStore.fetchBooks()
  startPolling()
})

onUnmounted(() => {
  stopPolling()
})

function startPolling() {
  pollInterval = setInterval(async () => {
    const hasActive = bookStore.books.some(
      (b) => b.status === 'PENDING' || b.status === 'PROCESSING'
    )
    if (hasActive) {
      await bookStore.fetchBooks()
    }
  }, 5000)
}

function stopPolling() {
  if (pollInterval != null) {
    clearInterval(pollInterval)
    pollInterval = null
  }
}

function onFileChange(event: Event) {
  const input = event.target as HTMLInputElement
  if (input.files && input.files.length > 0) {
    setFile(input.files[0])
  }
}

function onDrop(event: DragEvent) {
  isDragging.value = false
  const file = event.dataTransfer?.files[0]
  if (file) setFile(file)
}

function setFile(file: File) {
  if (!file.name.toLowerCase().endsWith('.pdf')) {
    uploadError.value = 'Only PDF files are accepted.'
    return
  }
  selectedFile.value = file
  uploadError.value = null
  uploadSuccess.value = false
}

function clearFile() {
  selectedFile.value = null
  uploadError.value = null
  uploadSuccess.value = false
  if (fileInput.value) fileInput.value.value = ''
}

async function handleUpload() {
  if (!selectedFile.value) return
  uploadError.value = null
  uploadSuccess.value = false

  const result = await bookStore.uploadBook(selectedFile.value)
  if (result) {
    uploadSuccess.value = true
    clearFile()
    showToast?.('Book uploaded — embedding started.', 'success')
  } else {
    uploadError.value = bookStore.error ?? 'Upload failed.'
    showToast?.(uploadError.value, 'error')
  }
}

async function handleDelete(id: string) {
  deletingId.value = id
  const ok = await bookStore.deleteBook(id)
  deletingId.value = null
  if (!ok) {
    showToast?.(bookStore.error ?? 'Delete failed.', 'error')
  }
}

function formatFileSize(bytes: number): string {
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
}
</script>

<style scoped>
.upload-section {
  margin-bottom: 2rem;
}

.section-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: #2d3748;
  margin-bottom: 1rem;
}

.drop-zone {
  border: 2px dashed #cbd5e0;
  border-radius: 8px;
  padding: 2rem;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  margin-bottom: 1rem;
}

.drop-zone:hover,
.drop-zone--active {
  border-color: #3182ce;
  background: #ebf8ff;
}

.drop-zone--has-file {
  border-color: #48bb78;
  background: #f0fff4;
}

.file-input-hidden {
  display: none;
}

.drop-zone-icon {
  font-size: 2rem;
  display: block;
  margin-bottom: 0.5rem;
}

.drop-zone-content,
.drop-zone-selected {
  pointer-events: none;
}

.drop-zone-text {
  font-size: 1rem;
  font-weight: 500;
  color: #4a5568;
  margin-bottom: 0.25rem;
}

.drop-zone-hint {
  font-size: 0.85rem;
  color: #a0aec0;
}

.upload-controls {
  display: flex;
  gap: 0.75rem;
  justify-content: flex-end;
}

.upload-feedback {
  margin-top: 0.75rem;
  padding: 0.6rem 1rem;
  border-radius: 6px;
  font-size: 0.9rem;
}

.upload-feedback--success {
  background: #c6f6d5;
  color: #22543d;
  border: 1px solid #68d391;
}

.upload-feedback--error {
  background: #fed7d7;
  color: #742a2a;
  border: 1px solid #fc8181;
}

.book-list-section {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.book-list-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.book-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 1rem;
}
</style>
