<template>
  <v-dialog
    :model-value="modelValue"
    max-width="520" persistent
    @update:model-value="$emit('update:modelValue', $event)"
  >
    <v-card>
      <v-card-title>
        {{ titleVerb }}
        {{ kindLabel }}<span v-if="runId"> #{{ runId }}</span>
      </v-card-title>
      <v-card-text>
        <v-alert
          :type="alertType"
          variant="tonal" density="compact" class="mb-3"
        >
          <strong>{{ warningText }}</strong>
          <div v-if="description" class="mt-1">{{ description }}</div>
        </v-alert>

        <div v-if="projectedCounts" class="fc-counts mb-3">
          <div v-for="(v, k) in projectedCounts" :key="k">
            <span class="fc-counts-key">{{ k }}:</span>
            <span class="fc-counts-val">{{ v }}</span>
          </div>
        </div>

        <template v-if="tier === 'C'">
          <div class="text-body-2 mb-2">Type the following to confirm:</div>
          <div class="fc-token mb-3">{{ expectedToken }}</div>
          <v-text-field
            v-model="typed"
            variant="outlined" density="compact" hide-details
            autofocus
            placeholder="paste the token above"
          />
        </template>
      </v-card-text>
      <v-card-actions>
        <v-spacer />
        <v-btn variant="text" @click="onCancel">Cancel</v-btn>
        <v-btn
          :color="confirmColor"
          variant="flat" rounded="pill"
          :disabled="!canConfirm"
          @click="onConfirm"
        >
          {{ titleVerb }}
        </v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script setup>
import { computed, ref, watch } from 'vue'

const props = defineProps({
  modelValue: { type: Boolean, required: true },
  action: { type: String, required: true },          // 'restore' | 'delete'
  kind: { type: String, required: true },            // 'db' | 'images' | 'artist' | 'tag' | 'images-selection' | 'audit' | 'min-dim'
  runId: { type: [Number, String], default: '' },    // numeric id or sha8 string
  description: { type: String, default: '' },
  tier: { type: String, default: 'C' },              // 'B' | 'C'
  projectedCounts: { type: Object, default: null },
  // Override the `${action}-${kind}-${runId}` token formula. Use when
  // the backend computes the canonical confirm token (e.g. bulk-delete
  // and min-dim cleanup both return `confirm_token` from their dry-run
  // endpoints) and the UI's kind/runId would otherwise produce a
  // mismatched string. Operator-flagged 2026-05-27 after the
  // BulkEditor's kind="images-selection" produced
  // `delete-images-selection-<sha8>` while the backend expected
  // `delete-images-<sha8>`.
  expectedTokenOverride: { type: String, default: '' },
})
const emit = defineEmits(['update:modelValue', 'confirm'])

const typed = ref('')
const expectedToken = computed(
  () => props.expectedTokenOverride
    || `${props.action}-${props.kind}-${props.runId}`,
)
const titleVerb = computed(
  () => props.action === 'restore' ? 'Restore' : 'Delete',
)
const kindLabel = computed(() => ({
  db: 'database backup',
  images: 'images backup',
  artist: 'artist',
  tag: 'tag',
  'images-selection': 'image selection',
}[props.kind] || props.kind))
const alertType = computed(
  () => props.action === 'restore' ? 'warning' : 'error',
)
const confirmColor = computed(
  () => props.action === 'restore' ? 'warning' : 'error',
)
const warningText = computed(() => (
  props.action === 'restore'
    ? 'This replaces current state with the backup. There is no undo.'
    : 'This permanently deletes the listed items. Cannot be recovered.'
))
const canConfirm = computed(
  () => props.tier === 'B'
    ? true
    : typed.value === expectedToken.value,
)

watch(() => props.modelValue, (open) => {
  if (open) typed.value = ''
})

function onCancel() {
  emit('update:modelValue', false)
}
function onConfirm() {
  emit('confirm', expectedToken.value)
  emit('update:modelValue', false)
}
</script>

<style scoped>
.fc-token {
  font-family: 'JetBrains Mono', monospace;
  background: rgb(var(--v-theme-surface-light));
  padding: 6px 10px; border-radius: 4px;
  font-size: 14px; word-break: break-all;
}
.fc-counts {
  display: grid; grid-template-columns: max-content auto;
  gap: 4px 12px;
  font-size: 13px;
  color: rgb(var(--v-theme-on-surface-variant));
}
.fc-counts-key { font-weight: 500; text-transform: capitalize; }
.fc-counts-val { font-variant-numeric: tabular-nums; }
</style>
