<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { Loader2, Plus, Save, Trash2, X } from '@lucide/vue'

import Button from '../ui/Button.vue'
import Modal from '../ui/Modal.vue'
import { watchAdminToast } from '../../composables/useAdminToast'
import { useAwardsStore } from '../../stores/awards'

const props = defineProps<{
  open: boolean
}>()

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

const store = useAwardsStore()
const loading = ref(false)
const saving = ref(false)
const entries = ref<string[]>([])
const newUrl = ref('')
const success = ref('')
const error = ref('')

const normalizedEntries = computed(() =>
  entries.value
    .map((entry) => entry.trim())
    .filter(Boolean),
)
const canSave = computed(() => !loading.value && !saving.value && normalizedEntries.value.length > 0)

watchAdminToast(success, error)

watch(
  () => props.open,
  (open) => {
    if (open) {
      void loadBlacklist()
    }
  },
  { immediate: true },
)

async function loadBlacklist() {
  loading.value = true
  error.value = ''
  try {
    const response = await store.loadAdminNominationLinkBlacklist()
    entries.value = response.entries.map((entry) => entry.url)
  } catch (loadError) {
    error.value = loadError instanceof Error ? loadError.message : 'Blacklist konnte nicht geladen werden.'
  } finally {
    loading.value = false
  }
}

function addEntry() {
  const url = newUrl.value.trim()
  if (!url) return
  entries.value = [...entries.value, url]
  newUrl.value = ''
}

function removeEntry(index: number) {
  entries.value = entries.value.filter((_, entryIndex) => entryIndex !== index)
}

async function saveBlacklist() {
  if (!canSave.value) return
  saving.value = true
  success.value = ''
  error.value = ''
  try {
    const response = await store.updateAdminNominationLinkBlacklist({ urls: normalizedEntries.value })
    entries.value = response.entries.map((entry) => entry.url)
    success.value = 'Link-Blacklist wurde gespeichert.'
  } catch (saveError) {
    error.value = saveError instanceof Error ? saveError.message : 'Blacklist konnte nicht gespeichert werden.'
  } finally {
    saving.value = false
  }
}
</script>

<template>
  <Modal
    :open="open"
    title="Link-Blacklist"
    subtitle="Blockiert generische oder unerwünschte Stream-Links direkt bei der öffentlichen Nominierung."
    size="lg"
    @close="emit('close')"
  >
    <div class="space-y-5">
      <div class="rounded-2xl border border-amber-100 bg-amber-50/75 px-4 py-3 text-sm leading-6 text-amber-900">
        Die Standardseiten von Twitch, Kick und YouTube sind bereits hinterlegt. User sollen direkte Kanal- oder Profil-Links einreichen, nicht die Startseite einer Plattform.
      </div>

      <div v-if="loading" class="flex items-center gap-3 rounded-2xl border border-violet-100 bg-violet-50/60 px-4 py-5 text-sm font-semibold text-violet-700">
        <Loader2 class="h-4 w-4 animate-spin" />
        Lade Blacklist ...
      </div>

      <div v-else class="space-y-3">
        <div
          v-for="(entry, index) in entries"
          :key="`${entry}-${index}`"
          class="grid gap-3 rounded-2xl border border-violet-100 bg-white px-4 py-3 md:grid-cols-[minmax(0,1fr)_auto]"
        >
          <label class="block min-w-0">
            <span class="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">Blockierter Link</span>
            <input
              v-model="entries[index]"
              type="url"
              class="mt-2 h-11 w-full rounded-2xl border border-violet-200 bg-white px-4 text-sm font-semibold text-slate-800 outline-none transition focus:border-violet-400 focus:ring-4 focus:ring-violet-100"
              placeholder="https://example.com/"
            />
          </label>
          <Button type="button" variant="ghost" size="sm" class="self-end gap-2 rounded-2xl text-rose-700 hover:text-rose-800" @click="removeEntry(index)">
            <Trash2 class="h-4 w-4" />
            Entfernen
          </Button>
        </div>

        <div class="grid gap-3 rounded-2xl border border-dashed border-violet-200 bg-violet-50/45 p-4 md:grid-cols-[minmax(0,1fr)_auto]">
          <label class="block min-w-0">
            <span class="text-[11px] font-semibold uppercase tracking-[0.18em] text-violet-600">Neuer Link</span>
            <input
              v-model="newUrl"
              type="url"
              class="mt-2 h-11 w-full rounded-2xl border border-violet-200 bg-white px-4 text-sm font-semibold text-slate-800 outline-none transition focus:border-violet-400 focus:ring-4 focus:ring-violet-100"
              placeholder="https://www.twitch.tv/"
              @keydown.enter.prevent="addEntry"
            />
          </label>
          <Button type="button" variant="secondary" class="self-end gap-2 rounded-2xl" :disabled="!newUrl.trim()" @click="addEntry">
            <Plus class="h-4 w-4" />
            Hinzufügen
          </Button>
        </div>
      </div>

      <p v-if="entries.length === 0 && !loading" class="rounded-2xl border border-rose-100 bg-rose-50 px-4 py-3 text-sm font-semibold text-rose-700">
        Die Blacklist darf nicht leer sein, damit die generischen Plattform-Links weiter geblockt bleiben.
      </p>
    </div>

    <template #footer>
      <Button type="button" variant="ghost" class="gap-2" :disabled="saving" @click="emit('close')">
        <X class="h-4 w-4" />
        Schließen
      </Button>
      <Button type="button" class="gap-2" :disabled="!canSave" @click="saveBlacklist">
        <Loader2 v-if="saving" class="h-4 w-4 animate-spin" />
        <Save v-else class="h-4 w-4" />
        {{ saving ? 'Speichert ...' : 'Blacklist speichern' }}
      </Button>
    </template>
  </Modal>
</template>
