<script setup lang="ts">
import { computed } from 'vue'
import { storeToRefs } from 'pinia'
import { useImportStore } from '@PeopleManager/stores/importStore'
import { CollectionObject } from '@PeopleManager/models/collection'

// Props
const props = defineProps<{
  modelValue: boolean
  collections: CollectionObject[]
}>()

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  // refresh = true once contacts were created/updated, so the caller can reload lists
  'close': [refresh: boolean]
}>()

// Store
const importStore = useImportStore()
const { files, sessions, order, stage, running, totals } = storeToRefs(importStore)

// Collection picker options
const collectionOptions = computed(() =>
  props.collections.map((collection: CollectionObject) => ({
    title: collection.properties.label || 'Unnamed',
    value: collection.identifier,
  })),
)

const isSelecting = computed(() => stage.value === 'selecting')
const isComplete = computed(() => stage.value === 'completed' || stage.value === 'error')

// Every queued file must have a destination before import can start.
const canImport = computed(() =>
  files.value.length > 0 && files.value.every((entry) => entry.collectionId !== null),
)

const progress = computed(() => {
  const { discovered, processed } = totals.value
  return discovered > 0 ? Math.min(100, Math.round((processed / discovered) * 100)) : 0
})

const counters = computed(() => {
  const t = totals.value
  return [
    { key: 'discovered', label: 'Discovered', value: t.discovered, color: 'info' },
    { key: 'created', label: 'Created', value: t.created, color: 'success' },
    { key: 'updated', label: 'Updated', value: t.updated, color: 'info' },
    { key: 'exists', label: 'Skipped', value: t.exists, color: 'warning' },
    { key: 'error', label: 'Errors', value: t.error, color: 'error' },
  ]
})

function setCollection(fileId: number, collectionId: CollectionObject['identifier'] | null) {
  importStore.setCollectionForFile(fileId, collectionId)
}

function setSupersede(fileId: number, value: boolean) {
  importStore.setOptionsForFile(fileId, { supersede: value })
}

async function startImport() {
  try {
    await importStore.startImport()
  } catch (error) {
    console.error('[People] - Import failed:', error)
  }
}

function cancel() {
  emit('update:modelValue', false)
  emit('close', false)
}

function done() {
  const refresh = totals.value.created > 0 || totals.value.updated > 0
  emit('update:modelValue', false)
  emit('close', refresh)
}
</script>

<template>
  <v-dialog
    :model-value="modelValue"
    max-width="640"
    persistent
    scrollable
  >
    <v-card>
      <v-card-title class="d-flex align-center">
        <v-icon icon="mdi-database-import" class="mr-2" />
        Import Contacts
      </v-card-title>

      <v-divider />

      <!-- Selecting stage: choose a destination per file -->
      <v-card-text v-if="isSelecting" class="pt-4">
        <p class="text-body-2 text-medium-emphasis mb-4">
          Choose a destination address book for each file. Existing contacts are kept
          unless "Overwrite existing" is enabled.
        </p>

        <v-card
          v-for="entry in files"
          :key="entry.file.id"
          variant="tonal"
          class="mb-3 pa-3"
        >
          <div class="d-flex align-center mb-2">
            <v-icon icon="mdi-file-account-outline" size="small" class="mr-2" />
            <span class="text-subtitle-2 font-weight-medium text-truncate">{{ entry.file.name }}</span>
          </div>

          <v-select
            :model-value="entry.collectionId"
            :items="collectionOptions"
            label="Address book"
            density="compact"
            variant="outlined"
            hide-details
            class="mb-2"
            @update:model-value="setCollection(entry.file.id, $event)"
          />

          <v-switch
            :model-value="entry.options.supersede"
            label="Overwrite existing contacts"
            color="primary"
            density="compact"
            hide-details
            @update:model-value="setSupersede(entry.file.id, $event ?? false)"
          />
        </v-card>
      </v-card-text>

      <!-- Importing / completed stage: progress + counters -->
      <v-card-text v-else class="pt-4">
        <div class="d-flex align-center justify-space-between mb-1">
          <span class="text-body-2">
            {{ isComplete ? 'Import complete' : 'Importing…' }}
          </span>
          <span class="text-body-2 text-medium-emphasis">
            {{ totals.processed }} / {{ totals.discovered }}
          </span>
        </div>

        <v-progress-linear
          :model-value="progress"
          :indeterminate="running && totals.discovered === 0"
          color="primary"
          height="8"
          rounded
          class="mb-4"
        />

        <div class="d-flex flex-wrap ga-2">
          <v-chip
            v-for="counter in counters"
            :key="counter.key"
            :color="counter.color"
            size="small"
            variant="tonal"
          >
            {{ counter.label }}: {{ counter.value }}
          </v-chip>
        </div>

        <v-list v-if="order.length > 1" density="compact" class="mt-3 bg-transparent">
          <v-list-item
            v-for="id in order"
            :key="id"
            :title="sessions[id]?.fileName"
            :subtitle="sessions[id]?.lastError ?? undefined"
          >
            <template #prepend>
              <v-icon
                :icon="sessions[id]?.status === 'error' ? 'mdi-alert-circle' : sessions[id]?.status === 'completed' ? 'mdi-check-circle' : 'mdi-progress-clock'"
                :color="sessions[id]?.status === 'error' ? 'error' : sessions[id]?.status === 'completed' ? 'success' : 'info'"
                size="small"
              />
            </template>
            <template #append>
              <span class="text-caption text-medium-emphasis">
                {{ sessions[id]?.counters.processed }} / {{ sessions[id]?.counters.discovered }}
              </span>
            </template>
          </v-list-item>
        </v-list>
      </v-card-text>

      <v-divider />

      <v-card-actions>
        <v-spacer />
        <template v-if="isSelecting">
          <v-btn variant="text" @click="cancel">Cancel</v-btn>
          <v-btn color="primary" variant="flat" :disabled="!canImport" @click="startImport">
            Import
          </v-btn>
        </template>
        <template v-else>
          <v-btn color="primary" variant="flat" :disabled="running" @click="done">
            Close
          </v-btn>
        </template>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>
