<template>
  <div class="p-8 max-w-4xl mx-auto">
    <!-- Back -->
    <button @click="$router.back()" class="text-sm text-indigo-600 hover:underline mb-6 flex items-center gap-1 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1 rounded">
      ← Back
    </button>

    <div v-if="loading" class="text-gray-400 text-sm">Loading…</div>
    <div v-else-if="!doc" class="text-gray-400 text-sm">Document not found.</div>

    <template v-else>
      <!-- Header -->
      <div class="flex items-start justify-between gap-4 mb-6">
        <div>
          <h2 class="text-2xl font-semibold text-gray-900 break-all">{{ doc.original_name }}</h2>
          <p class="text-sm text-gray-400 mt-1">
            Uploaded {{ formatDate(doc.created_at) }} · {{ formatSize(doc.size_bytes) }} · {{ doc.mime_type }}
          </p>
        </div>
        <div class="flex items-center gap-2 shrink-0">
          <!-- Open/Preview button for PDFs -->
          <button
            v-if="isPdf"
            @click="openPdf"
            class="text-sm px-3 py-1.5 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 active:bg-indigo-800 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1"
          >
            {{ pdfOpenMode === 'in_app' ? 'Preview' : 'Open' }}
          </button>
          <button
            @click="confirmDelete"
            class="text-sm text-red-500 hover:text-red-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500 focus-visible:ring-offset-1 rounded"
          >Delete</button>
        </div>
      </div>

      <!-- Topics -->
      <div class="bg-white border border-gray-200 rounded-xl p-5 mb-5">
        <div class="flex items-center justify-between mb-3">
          <h3 class="text-sm font-semibold text-gray-800">Topics</h3>
          <div class="flex gap-2">
            <button
              @click="reclassify"
              :disabled="classifying"
              class="text-xs px-3 py-1.5 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 active:bg-indigo-800 transition-colors disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1"
            >
              {{ classifying ? 'Classifying…' : 'Re-classify' }}
            </button>
            <button
              @click="suggestTopics"
              :disabled="suggesting"
              class="text-xs px-3 py-1.5 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 active:bg-gray-100 transition-colors disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1"
            >
              {{ suggesting ? 'Suggesting…' : 'Suggest Topics' }}
            </button>
          </div>
        </div>

        <div class="flex flex-wrap gap-2">
          <TopicBadge
            v-for="name in doc.topics"
            :key="name"
            :name="name"
            :color="topicColor(name)"
          />
          <span v-if="!doc.topics?.length" class="text-sm text-gray-400 italic">No topics assigned yet.</span>
        </div>

        <p v-if="classifyError" class="text-red-500 text-xs mt-2">{{ classifyError }}</p>

        <!-- Suggestions modal inline -->
        <div v-if="suggestions.length" class="mt-4 border-t border-gray-100 pt-4">
          <p class="text-sm font-medium text-gray-700 mb-2">AI Suggestions — select to create:</p>
          <div class="flex flex-wrap gap-2 mb-3">
            <label
              v-for="s in suggestions"
              :key="s"
              class="flex items-center gap-1.5 cursor-pointer text-sm"
            >
              <input type="checkbox" v-model="selectedSuggestions" :value="s" class="rounded border-gray-300 text-indigo-600" />
              {{ s }}
            </label>
          </div>
          <div class="flex gap-2">
            <button
              @click="createSelectedTopics"
              :disabled="!selectedSuggestions.length"
              class="text-xs px-3 py-1.5 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 disabled:opacity-50"
            >
              Create Selected
            </button>
            <button @click="suggestions = []; selectedSuggestions = []" class="text-xs text-gray-500 hover:text-gray-700">
              Dismiss
            </button>
          </div>
        </div>
      </div>

      <!-- Extracted text -->
      <div class="bg-white border border-gray-200 rounded-xl p-5">
        <h3 class="text-sm font-semibold text-gray-800 mb-3">Extracted Text</h3>
        <pre class="text-xs text-gray-600 whitespace-pre-wrap font-mono bg-gray-50 rounded-lg p-4 max-h-96 overflow-y-auto">{{ doc.extracted_text || '(no text extracted)' }}</pre>
      </div>
    </template>

    <!-- PDF in-app preview modal -->
    <DocumentPreviewModal
      v-if="showPreviewModal && doc"
      :doc="doc"
      @close="showPreviewModal = false"
    />

    <!-- Cloud delete warning modal -->
    <div
      v-if="showCloudDeleteWarning"
      class="fixed inset-0 bg-black/40 flex items-center justify-center z-50"
      @click.self="cancelCloudDeleteWarning"
    >
      <div
        role="dialog"
        aria-modal="true"
        aria-labelledby="cloud-delete-modal-title"
        data-test="cloud-delete-modal-panel"
        class="bg-white rounded-2xl shadow-xl p-6 max-w-sm w-full mx-4 max-h-[90vh] overflow-y-auto"
      >
        <div class="flex items-center gap-2 mb-2">
          <AppIcon name="warning" class="w-5 h-5 text-amber-500 shrink-0" />
          <h2 id="cloud-delete-modal-title" class="text-lg font-semibold text-gray-900">Cloud delete failed</h2>
        </div>
        <p class="text-sm text-gray-600 mb-4">
          The file could not be deleted from {{ cloudProviderName }}. Remove it from DocuVault anyway? The file will remain on {{ cloudProviderName }}.
        </p>
        <div class="flex gap-2 justify-end">
          <button
            @click="cancelCloudDeleteWarning"
            class="border border-gray-300 text-gray-700 text-sm px-4 py-2 rounded-lg hover:bg-gray-50 active:bg-gray-100 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1"
          >Cancel</button>
          <button
            @click="confirmRemoveOnly"
            class="bg-red-600 hover:bg-red-700 active:bg-red-800 text-white text-sm px-4 py-2 rounded-lg transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500 focus-visible:ring-offset-1"
          >Remove from app</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { formatDate, formatSize } from '../utils/formatters.js'
import AppIcon from '../components/ui/AppIcon.vue'
import TopicBadge from '../components/topics/TopicBadge.vue'
import DocumentPreviewModal from '../components/documents/DocumentPreviewModal.vue'
import { useDocumentsStore } from '../stores/documents.js'
import { useTopicsStore } from '../stores/topics.js'
import * as api from '../api/client.js'
import { fetchDocumentContent } from '../api/client.js'

const route = useRoute()
const router = useRouter()
const docsStore = useDocumentsStore()
const topicsStore = useTopicsStore()

const doc = ref(null)
const loading = ref(true)
const classifying = ref(false)
const suggesting = ref(false)
const classifyError = ref(null)
const suggestions = ref([])
const selectedSuggestions = ref([])
const showPreviewModal = ref(false)
const pdfOpenMode = ref('new_tab')
const showCloudDeleteWarning = ref(false)
const cloudProviderName = ref('your cloud storage')

const isPdf = computed(() => {
  if (!doc.value) return false
  const mime = doc.value.mime_type || ''
  const name = doc.value.original_name || ''
  return mime === 'application/pdf' || name.toLowerCase().endsWith('.pdf')
})

onMounted(async () => {
  try {
    doc.value = await api.getDocument(route.params.id)
  } finally {
    loading.value = false
  }
  // Load user preferences for PDF open mode
  try {
    const prefs = await api.getMyPreferences()
    pdfOpenMode.value = prefs.pdf_open_mode || 'new_tab'
  } catch {
    pdfOpenMode.value = 'new_tab'
  }
})

async function openPdf() {
  if (pdfOpenMode.value === 'in_app') {
    showPreviewModal.value = true
  } else {
    // Fetch with Authorization header → blob → object URL → window.open
    // This closes the unauthenticated access gap: window.open(rawUrl) would bypass
    // Bearer auth for cloud documents (plan 05-09 trust boundary).
    try {
      const res = await fetchDocumentContent(doc.value.id)
      if (!res.ok) {
        console.error('Failed to open document:', res.status)
        return
      }
      const blob = await res.blob()
      const objectUrl = URL.createObjectURL(blob)
      const tab = window.open(objectUrl, '_blank')
      // Revoke once the new tab has loaded, or after 120s as a fallback.
      // Also revoke if the user navigates away from this page before the tab loads.
      const revoke = () => URL.revokeObjectURL(objectUrl)
      const timer = setTimeout(revoke, 120000)
      window.addEventListener('pagehide', revoke, { once: true })
      if (tab) {
        tab.addEventListener('load', () => { clearTimeout(timer); revoke() }, { once: true })
      }
    } catch (err) {
      console.error('Failed to open document:', err)
    }
  }
}

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

async function reclassify() {
  classifying.value = true
  classifyError.value = null
  try {
    const result = await api.classifyDocument(doc.value.id)
    doc.value.topics = result.topics
    await topicsStore.fetchTopics()
  } catch (e) {
    classifyError.value = e.message
  } finally {
    classifying.value = false
  }
}

async function suggestTopics() {
  suggesting.value = true
  try {
    const result = await api.suggestTopics(doc.value.id)
    suggestions.value = result.suggested
    selectedSuggestions.value = []
  } catch (e) {
    classifyError.value = e.message
  } finally {
    suggesting.value = false
  }
}

async function createSelectedTopics() {
  for (const name of selectedSuggestions.value) {
    await topicsStore.addTopic({ name })
  }
  suggestions.value = []
  selectedSuggestions.value = []
  // Re-classify now that topics exist
  await reclassify()
}

const _PROVIDER_NAMES = { google_drive: 'Google Drive', onedrive: 'OneDrive', nextcloud: 'Nextcloud', webdav: 'WebDAV' }

async function confirmDelete() {
  if (!confirm(`Delete "${doc.value.original_name}"?`)) return
  const resp = await api.deleteDocument(doc.value.id)
  if (resp && resp.cloud_delete_failed) {
    cloudProviderName.value = _PROVIDER_NAMES[doc.value.storage_backend] || 'your cloud storage'
    showCloudDeleteWarning.value = true
    return
  }
  router.push('/')
}

async function confirmRemoveOnly() {
  try {
    await api.deleteDocumentRemoveOnly(doc.value.id)
    showCloudDeleteWarning.value = false
    router.push('/')
  } catch (e) {
    // error shown inline if needed — modal stays open
  }
}

function cancelCloudDeleteWarning() {
  showCloudDeleteWarning.value = false
}

</script>
