<template>
  <!-- #874 follow-up: purge blurred locked-preview images grabbed from
       tier-gated Patreon posts before the ingester fix. Re-walks each feed and
       matches by content hash, so real content downloaded when access existed is
       provably spared. Preview first, then apply (destructive: deletes the
       matched blurred-preview files). -->
  <v-card>
    <v-card-title>Clean up gated-post previews</v-card-title>
    <v-card-text>
      <p class="text-body-2 mb-3">
        Removes the blurred locked-preview images that were grabbed from
        tier-gated Patreon posts before they were filtered out. It re-walks every
        enabled Patreon source and matches by exact content hash, so anything you
        downloaded while you <em>had</em> access is left untouched —
        only the blurred previews are removed. <strong>Preview</strong> first to
        see the count; <strong>Apply</strong> deletes the matched files and clears
        their download ledger so the real media can re-download if you regain
        access. The re-walk can take a while across many sources.
      </p>

      <div class="d-flex align-center flex-wrap" style="gap: 12px;">
        <v-btn
          color="primary" variant="tonal" rounded="pill"
          :loading="previewing" :disabled="applying" @click="preview"
        >
          <v-icon start>mdi-magnify</v-icon> Preview
        </v-btn>
        <v-btn
          color="error" rounded="pill"
          :loading="applying"
          :disabled="previewing || !canApply"
          @click="confirmOpen = true"
        >
          <v-icon start>mdi-image-off</v-icon> Apply
        </v-btn>
      </div>

      <v-alert
        v-if="summary" :type="summaryType" variant="tonal" class="mt-4"
        density="comfortable"
      >
        <span v-if="applied">
          Removed {{ summary.deleted }} blurred preview image(s) across
          {{ summary.gated_posts }} gated post(s); reclaimed
          {{ humanBytes(summary.reclaim_bytes) }};
          removed {{ summary.posts_deleted }} now-empty post(s).
          <template v-if="summary.unverifiable > 0">
            {{ summary.unverifiable }} image(s) couldn't be verified (no stored
            source hash) and were kept.
          </template>
        </span>
        <span v-else-if="summary.matched > 0">
          {{ summary.matched }} blurred preview image(s) across
          {{ summary.gated_posts }} gated post(s) —
          {{ humanBytes(summary.reclaim_bytes) }} reclaimable. Click
          <strong>Apply</strong> to delete them.
          <template v-if="summary.unverifiable > 0">
            ({{ summary.unverifiable }} image(s) on gated posts have no stored
            source hash, so they can't be verified and will be kept.)
          </template>
        </span>
        <span v-else>
          No blurred gated-post previews found
          <template v-if="summary.gated_posts > 0">
            across {{ summary.gated_posts }} gated post(s)</template>.
        </span>
        <template v-if="summary.partial">
          <br>
          <small>
            Scanned {{ summary.sources_scanned }}/{{ summary.sources_total }}
            sources before the time budget — run again to finish the rest.
          </small>
        </template>
      </v-alert>

      <QueueStatusBar queue="maintenance_long" queue-label="Maintenance" />
    </v-card-text>

    <v-dialog v-model="confirmOpen" max-width="460">
      <v-card>
        <v-card-title>Delete gated-post previews?</v-card-title>
        <v-card-text class="text-body-2">
          This permanently deletes
          <strong>{{ summary?.matched ?? 0 }}</strong> blurred preview file(s)
          matched by exact content hash. Real content you downloaded with access
          has a different hash and is not affected.
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn variant="text" @click="confirmOpen = false">Cancel</v-btn>
          <v-btn color="error" @click="apply">Delete previews</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </v-card>
</template>

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

import { useMaintenanceTask } from '../../composables/useMaintenanceTask.js'
import QueueStatusBar from './QueueStatusBar.vue'

const confirmOpen = ref(false)

// The re-walk hits every enabled Patreon feed and can run long — the lifecycle +
// resurface-after-navigation live in the shared composable. 300 polls × 2s ≈ 10m.
const { previewing, applying, summary, applied, preview, apply: applyTask } = useMaintenanceTask({
  endpoint: '/api/admin/maintenance/purge-gated-previews',
  storageKey: 'fc.maint.gatedPurge',
  appliedToast: 'Gated-post previews removed',
  maxPolls: 300,
})

const canApply = computed(() => !!summary.value && !applied.value && summary.value.matched > 0)
const summaryType = computed(() => {
  if (applied.value) return 'success'
  return summary.value && summary.value.matched > 0 ? 'info' : 'success'
})

function humanBytes (n) {
  const b = Number(n || 0)
  if (b >= 1 << 30) return (b / (1 << 30)).toFixed(1) + ' GB'
  if (b >= 1 << 20) return (b / (1 << 20)).toFixed(1) + ' MB'
  if (b >= 1 << 10) return (b / (1 << 10)).toFixed(1) + ' KB'
  return b + ' B'
}

// The confirm dialog gates the destructive apply; close it, then run.
function apply () {
  confirmOpen.value = false
  applyTask()
}
</script>
