import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useApi } from '../composables/useApi.js'
import { useAsyncAction } from '../composables/useAsyncAction.js'
import { useInflightToken } from '../composables/useInflightToken.js'

const PAGE = 60

export const useTagDirectoryStore = defineStore('tagDirectory', () => {
  const api = useApi()
  const cards = ref([])
  const nextCursor = ref(null)
  const { loading, error, run } = useAsyncAction({ errorAs: 'message' })
  const kind = ref(null)
  const q = ref('')
  let started = false
  // Same shape as artistDirectory — rapid setQuery/setKind dropped
  // the second fetch because loading was still true from the first.
  // Audit 2026-06-02.
  const inflight = useInflightToken()

  async function loadMore() {
    if (started && nextCursor.value === null) return
    const t = inflight.claim()
    await run(async () => {
      const params = { limit: PAGE }
      if (kind.value) params.kind = kind.value
      if (q.value) params.q = q.value
      if (nextCursor.value) params.cursor = nextCursor.value
      const body = await api.get('/api/tags/directory', { params })
      if (!t.isCurrent()) return
      cards.value.push(...body.cards)
      nextCursor.value = body.next_cursor
      started = true
    })
  }

  async function reset() {
    inflight.cancel()
    cards.value = []
    nextCursor.value = null
    started = false
    await loadMore()
  }

  function setKind(k) { kind.value = k; reset() }
  function setQuery(text) { q.value = text; reset() }

  async function rename(id, name) {
    try {
      const body = await api.patch(`/api/tags/${id}`, { body: { name } })
      const card = cards.value.find((c) => c.id === id)
      if (card) card.name = body.name
      return { tag: body }
    } catch (e) {
      if (e.status === 409 && e.body && e.body.target) {
        const card = cards.value.find((c) => c.id === id)
        return {
          collision: {
            sourceId: id,
            sourceName: card ? card.name : '',
            target: e.body.target,
            sourceImageCount: e.body.source_image_count,
            willAlias: e.body.will_alias
          }
        }
      }
      throw e
    }
  }

  async function merge(sourceId, targetId) {
    const result = await api.post(`/api/tags/${sourceId}/merge`, {
      body: { target_id: targetId }
    })
    const idx = cards.value.findIndex((c) => c.id === sourceId)
    if (idx !== -1) cards.value.splice(idx, 1)
    return result
  }

  const hasMore = computed(() => !started || nextCursor.value !== null)
  const isEmpty = computed(
    () => !loading.value && cards.value.length === 0 && error.value === null
  )

  return {
    cards, loading, error, kind, q, hasMore, isEmpty,
    loadMore, reset, setKind, setQuery, rename, merge
  }
})
