<script setup lang="ts">
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useDialog } from '../composables/useDialog'
import { ApiError, apiRequest } from '../lib/api'
import { useCardsStore } from '../stores/cards'
import { useInboxStore } from '../stores/inbox'

// The "Manage" dropdown + its delete-card confirmation modal, shared by the
// card view and its configuration view -- each links to the other, and
// either can delete the card. Mirrors ProjectManageMenu.
const props = defineProps<{
  cardId: number
  cardText: string
  /** null for an inbox card -- there's no project to return to, so a delete
   * (or the "Back to project" link on the pages using this menu) goes to
   * the dashboard instead. */
  projectId: number | null
}>()

const route = useRoute()
const router = useRouter()
const cards = useCardsStore()
const inbox = useInboxStore()

const menuOpen = ref(false)
const confirmingDelete = ref(false)
const deleting = ref(false)
const deleteError = ref<string | null>(null)
const cancelButton = ref<HTMLButtonElement>()

function askDelete() {
  menuOpen.value = false
  deleteError.value = null
  confirmingDelete.value = true
}

async function confirmDelete() {
  deleting.value = true
  deleteError.value = null
  try {
    await apiRequest(`/cards/${props.cardId}`, { method: 'DELETE', auth: true })
    // Refresh whichever store holds this card -- a project's board, or the
    // sidebar inbox -- so it no longer shows the card we just deleted.
    await (props.projectId !== null ? cards.load(props.projectId) : inbox.load())
    await router.push(
      props.projectId !== null ? { name: 'project', params: { id: props.projectId } } : { name: 'dashboard' },
    )
  } catch (e) {
    deleteError.value = e instanceof ApiError ? e.message : 'Could not delete the card.'
    deleting.value = false
  }
}

// The modal takes priority: while it's open, Escape closes it, not the menu
// underneath (askDelete() already closes the menu when the modal opens, so
// the two are never both open at once).
useDialog(confirmingDelete, () => (confirmingDelete.value = false), cancelButton)
useDialog(menuOpen, () => (menuOpen.value = false))
</script>

<template>
  <div class="menu">
    <button
      type="button"
      class="menu__toggle"
      aria-haspopup="true"
      :aria-expanded="menuOpen"
      @click="menuOpen = !menuOpen"
    >
      Manage &#9662;
    </button>

    <template v-if="menuOpen">
      <div class="menu__backdrop" @click="menuOpen = false" />
      <ul class="menu__list" role="menu">
        <li v-if="route.name !== 'card-configure'" role="none">
          <RouterLink
            :to="{ name: 'card-configure', params: { id: cardId } }"
            role="menuitem"
            class="menu__item"
            @click="menuOpen = false"
          >
            Configure
          </RouterLink>
        </li>
        <li role="none">
          <button type="button" role="menuitem" class="menu__item menu__item--danger" @click="askDelete">
            Delete card
          </button>
        </li>
      </ul>
    </template>
  </div>

  <div
    v-if="confirmingDelete"
    class="modal"
    role="dialog"
    aria-modal="true"
    aria-labelledby="confirm-delete-title"
  >
    <div class="modal__backdrop" @click="confirmingDelete = false" />
    <div class="modal__dialog">
      <h2 id="confirm-delete-title">Delete this card?</h2>
      <p class="muted">&ldquo;{{ cardText }}&rdquo; will be permanently deleted.</p>
      <p v-if="deleteError" class="form-error">{{ deleteError }}</p>
      <div class="modal__actions">
        <button
          ref="cancelButton"
          type="button"
          class="btn-secondary"
          :disabled="deleting"
          @click="confirmingDelete = false"
        >
          Cancel
        </button>
        <button type="button" class="btn-danger" :disabled="deleting" @click="confirmDelete">
          {{ deleting ? 'Deleting…' : 'Delete card' }}
        </button>
      </div>
    </div>
  </div>
</template>
