<template>
  <section class="space-y-3 rounded-lg border border-base-200 bg-base-200/40 p-4">
    <header class="flex items-center justify-between gap-3">
      <div>
        <h2 class="font-semibold text-base-content">Versions</h2>
        <p class="text-xs text-base-content/70">
          Historique des versions avec possibilite de restauration.
        </p>
      </div>
      <span v-if="versions.length" class="badge badge-outline">
        {{ versions.length }} version{{ versions.length > 1 ? 's' : '' }}
      </span>
    </header>

    <div v-if="loading" class="flex items-center gap-2 text-sm text-base-content/70">
      <span class="loading loading-spinner loading-sm" aria-hidden="true" />
      Chargement des versions...
    </div>

    <div v-else-if="error" class="alert alert-warning">
      <span>{{ error }}</span>
    </div>

    <p v-else-if="versions.length === 0" class="text-xs text-base-content/70">
      Aucune version enregistree.
    </p>

    <ul v-else class="max-h-96 space-y-2 overflow-y-auto pr-1">
      <li
        v-for="entry in versions"
        :key="entry.version"
        class="flex items-center justify-between rounded-md border border-base-200 bg-base-100 px-3 py-2"
      >
        <div class="min-w-0 flex-1">
          <div class="flex items-center gap-2">
            <span class="font-mono text-sm font-semibold">v{{ entry.version }}</span>
            <span
              v-if="entry.version === currentVersion"
              class="badge badge-primary badge-sm"
            >
              actuelle
            </span>
            <span
              v-if="entry.action === 'restore'"
              class="badge badge-warning badge-sm"
            >
              restauration
            </span>
          </div>
          <div class="mt-0.5 flex flex-wrap items-center gap-2 text-xs text-base-content/60">
            <span>{{ actionLabel(entry.action) }}</span>
            <span>&middot;</span>
            <span>{{ formatDate(entry.createdAt) }}</span>
            <span v-if="entry.actor">&middot; {{ entry.actor.label }}</span>
          </div>
          <div v-if="entry.diff && Object.keys(entry.diff).length" class="mt-1 flex flex-wrap gap-1">
            <span
              v-for="(change, field) in entry.diff"
              :key="field"
              class="badge badge-ghost badge-xs"
            >
              {{ formatDiffEntry(String(field), change) }}
            </span>
          </div>
        </div>
        <button
          v-if="canRestore && entry.version !== currentVersion"
          class="btn btn-ghost btn-xs"
          :disabled="restoring"
          @click="handleRestore(entry.version)"
        >
          Restaurer
        </button>
      </li>
    </ul>

    <VersionRestoreModal
      :visible="modalVisible"
      :preview="previewData"
      :restoring="restoring"
      :field-labels="fieldLabels"
      :entity-type="entityType"
      @close="modalVisible = false"
      @confirm="confirmRestore"
    />
  </section>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch, toRef } from 'vue'
import { useEntityVersions, type RestorePreview } from '~/composables/useEntityVersions'
import { usePermissions } from '~/composables/usePermissions'
import { formatHistoryDate, historyActionLabel } from '~/shared/utils/historyDisplayUtils'
import VersionRestoreModal from './VersionRestoreModal.vue'

const props = defineProps<{
  entityType: 'machine' | 'composant' | 'piece' | 'product'
  entityId: string
  fieldLabels: Record<string, string>
  /** Increment this value to force a refresh of the versions list */
  refreshKey?: number
}>()

const emit = defineEmits<{
  restored: []
}>()

const { canEdit } = usePermissions()
const canRestore = computed(() => canEdit.value)

const { versions, loading, error, fetchVersions, fetchPreview, restore } = useEntityVersions({
  entityType: props.entityType,
  entityId: props.entityId,
})

const currentVersion = computed(() => {
  if (versions.value.length === 0) return null
  return versions.value[0]?.version ?? null
})

const modalVisible = ref(false)
const previewData = ref<RestorePreview | null>(null)
const restoring = ref(false)
const targetVersion = ref<number | null>(null)

const actionLabel = (action: string) => historyActionLabel(action)
const formatDate = (date: string) => formatHistoryDate(date)

const formatDiffEntry = (field: string, change: { from: unknown; to: unknown }): string => {
  const label = props.fieldLabels[field] || field
  // Link changes (addedComponent, removedPiece, etc.) have {id, name} as value
  const val = change.to ?? change.from
  if (val && typeof val === 'object' && 'name' in (val as Record<string, unknown>)) {
    return `${label}: ${(val as Record<string, unknown>).name}`
  }
  return label
}

const handleRestore = async (version: number) => {
  targetVersion.value = version
  previewData.value = null
  modalVisible.value = true
  previewData.value = await fetchPreview(version)
}

const confirmRestore = async () => {
  if (!targetVersion.value) return
  restoring.value = true
  const result = await restore(targetVersion.value)
  restoring.value = false
  if (result?.success) {
    modalVisible.value = false
    await fetchVersions()
    emit('restored')
  }
  else {
    error.value = 'La restauration a echoue.'
    modalVisible.value = false
  }
}

onMounted(() => {
  fetchVersions()
})

// Auto-refresh when parent signals a data change
watch(toRef(props, 'refreshKey'), () => {
  fetchVersions()
})
</script>
