<script setup>
import { ref, nextTick, onMounted, watch, computed } from 'vue'
import { useTranslation } from 'i18next-vue'
import { useRouter } from 'vue-router'
import { useCollections } from '../composables/useCollections.js'
import { useJsonExport } from '../composables/useJsonExport.js'
import { useJsonImport } from '../composables/useJsonImport.js'
import { useSettings } from '../composables/useSettings.js'
import { useKeyboardShortcut } from '../composables/useKeyboardShortcut.js'
import { useListNavigation } from '../composables/useListNavigation.js'
import ImportDialog from '../components/ImportDialog.vue'

const { t } = useTranslation()
const router = useRouter()
const { collections, loading, fetchAll, search } = useCollections()
const { exportAllCollections } = useJsonExport()
const { loadFile } = useJsonImport()
const { settings, fetchAll: fetchSettings } = useSettings()
const localUuid = ref('')

// Import dialog state
const showImportDialog = ref(false)
const importEnvelope = ref(null)
const importAsMine = ref(false)

const searchQuery = ref('')
const searching = ref(false)
const searchInput = ref(null)

onMounted(async () => {
  fetchAll()
  await fetchSettings()
  localUuid.value = settings.value.user_uuid || ''
})

let searchTimeout = null
watch(searchQuery, (query) => {
  clearTimeout(searchTimeout)
  const trimmed = query.trim()
  if (!trimmed) {
    fetchAll()
    return
  }
  searchTimeout = setTimeout(() => {
    search(trimmed)
  }, 250)
})

function goToNew() {
  router.push({ name: 'collection-new' })
}

useKeyboardShortcut('n', goToNew)

const collectionCount = computed(() => collections.value.length)
const { focusedIndex: focusedCollectionIndex } = useListNavigation(collectionCount, (index) => {
  goToDetail(collections.value[index].id)
})

function goToDetail(id) {
  router.push({ name: 'collection-detail', params: { id } })
}

function toggleSearch() {
  searching.value = !searching.value
  if (searching.value) {
    nextTick(() => {
      searchInput.value?.focus()
    })
  } else {
    searchQuery.value = ''
    fetchAll()
  }
}

function onSearchBlur() {
  if (!searchQuery.value.trim()) {
    searching.value = false
  }
}

function clearSearch() {
  searchQuery.value = ''
  searchInput.value?.focus()
}

async function onExport() {
  await exportAllCollections(searchQuery.value.trim())
}

async function onImport(asMine = false) {
  const result = await loadFile()
  if (result.cancelled) return
  if (result.error) {
    window.alert(t(result.error))
    return
  }
  importEnvelope.value = result.envelope
  importAsMine.value = asMine
  showImportDialog.value = true
}

function onImportDone() {
  showImportDialog.value = false
  importEnvelope.value = null
  importAsMine.value = false
  fetchAll()
}

function onImportClose() {
  showImportDialog.value = false
  importEnvelope.value = null
  importAsMine.value = false
}
</script>

<template>
  <Teleport to="#actionbar-actions" defer>
    <button
      data-testid="collection-search-toggle"
      :title="$t('collections.searchPlaceholder')"
      :aria-label="$t('collections.searchPlaceholder')"
      @click="toggleSearch"
    >
      <i class="bi bi-search"></i>
    </button>
    <button
      data-testid="collection-export-btn"
      :title="$t('export.collections')"
      :aria-label="$t('export.collections')"
      @click="onExport"
    >
      <i class="bi bi-download"></i>
    </button>
    <button
      data-testid="collection-import-btn"
      :title="$t('import.exercises')"
      :aria-label="$t('import.exercises')"
      @click="onImport(false)"
    >
      <i class="bi bi-upload"></i>
    </button>
    <button
      data-testid="collection-import-as-mine-btn"
      :title="$t('import.importAsMine')"
      :aria-label="$t('import.importAsMine')"
      @click="onImport(true)"
    >
      <i class="bi bi-person-check"></i>
    </button>
    <button
      data-testid="collection-new-btn"
      :title="$t('collections.new') + ' ' + $t('shortcuts.new')"
      :aria-label="$t('collections.new')"
      @click="goToNew"
    >
      <i class="bi bi-plus-lg"></i>
    </button>
  </Teleport>

  <div class="collection-list-view">
    <div v-if="searching" class="search-bar" data-testid="collection-search-bar">
      <input
        ref="searchInput"
        v-model="searchQuery"
        type="text"
        :placeholder="$t('collections.searchPlaceholder')"
        data-testid="collection-search-input"
        @blur="onSearchBlur"
      />
      <button
        v-if="searchQuery"
        type="button"
        class="search-clear-btn"
        data-testid="collection-search-clear"
        :title="$t('common.clearSearch')"
        :aria-label="$t('common.clearSearch')"
        @mousedown.prevent="clearSearch"
      >
        <i class="bi bi-x-lg"></i>
      </button>
    </div>

    <p v-if="loading" class="text-muted">{{ $t('app.loading') }}</p>

    <p
      v-else-if="collections.length === 0 && !searchQuery.trim()"
      class="text-muted"
      data-testid="collection-empty"
    >
      {{ $t('collections.empty') }}
    </p>

    <p
      v-else-if="collections.length === 0 && searchQuery.trim()"
      class="text-muted"
      data-testid="collection-no-results"
    >
      {{ $t('collections.noResults') }}
    </p>

    <div
      v-for="(collection, index) in collections"
      :key="collection.id"
      class="card collection-card"
      :class="{ 'card-focused': focusedCollectionIndex === index }"
      :data-testid="'collection-card-' + collection.id"
      :data-list-index="index"
      tabindex="0"
      @click="goToDetail(collection.id)"
    >
      <div class="collection-card-header">
        <h3 data-testid="collection-card-title">{{ collection.label }}</h3>
        <span
          v-if="collection.sessionCount"
          class="badge badge-info"
          data-testid="collection-card-session-count"
        >
          {{ collection.sessionCount }} {{ $t('collections.sessions') }}
        </span>
      </div>
    </div>
  </div>

  <ImportDialog
    v-if="showImportDialog && importEnvelope"
    :envelope="importEnvelope"
    :local-uuid="localUuid"
    :as-mine="importAsMine"
    @done="onImportDone"
    @close="onImportClose"
  />
</template>

<style scoped>
.collection-list-view {
  max-width: 800px;
}

.search-bar {
  position: relative;
  margin-bottom: 16px;
}

.search-bar input {
  padding-right: 36px;
}

.search-clear-btn {
  position: absolute;
  top: 50%;
  right: 8px;
  transform: translateY(-50%);
  background: none;
  border: none;
  padding: 4px;
  line-height: 1;
  color: var(--front-color2);
  cursor: pointer;
}

.collection-card {
  cursor: pointer;
  transition: border-color 0.15s;
}

.collection-card:hover {
  border-color: var(--btn-primary-bg);
}

.collection-card:focus-visible {
  border-color: var(--btn-primary-bg);
  box-shadow: 0 0 0 2px var(--btn-primary-bg);
  outline: none;
}

.collection-card.card-focused {
  border-color: var(--btn-primary-bg);
  box-shadow: 0 0 0 2px var(--btn-primary-bg);
}

.collection-card-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

.collection-card-header h3 {
  flex: 1;
  font-size: 16px;
  font-weight: 600;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 12px;
  background-color: var(--btn-primary-bg);
  color: var(--btn-primary-color);
  white-space: nowrap;
}

.badge-info {
  background-color: var(--front-color2);
}
</style>
