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

const PAGE = 60

export const useArtistStore = defineStore('artist', () => {
  const api = useApi()
  const overview = ref(null)
  const images = ref([])
  const nextCursor = ref(null)
  const loading = ref(false)
  const imagesLoading = ref(false)
  const error = ref(null)
  const notFound = ref(false)
  let started = false
  // Rapid artist-to-artist navigation used to render the previous
  // artist's overview/images briefly when the second load resolved
  // after the third. Audit 2026-06-02.
  const inflight = useInflightToken()

  async function load (slug) {
    // Cross-artist reset: clear this store AND the posts store so the new
    // artist doesn't briefly render with the previous artist's content
    // when the user is on the Posts tab. (Gallery tab uses this artist
    // store's own images list — cleared above.)
    inflight.cancel()
    overview.value = null
    images.value = []
    nextCursor.value = null
    notFound.value = false
    started = false
    error.value = null
    loading.value = true
    usePostsStore().$reset?.()
    const t = inflight.claim()
    try {
      const body = await api.get(`/api/artist/${encodeURIComponent(slug)}`)
      if (!t.isCurrent()) return
      overview.value = body
      await loadMoreImages(slug)
    } catch (e) {
      if (!t.isCurrent()) return
      if (e.status === 404) notFound.value = true
      else error.value = e.message
    } finally {
      if (t.isCurrent()) loading.value = false
    }
  }

  async function loadMoreImages (slug) {
    if (imagesLoading.value) return
    if (started && nextCursor.value === null) return
    imagesLoading.value = true
    const t = inflight.claim()
    try {
      const params = { limit: PAGE }
      if (nextCursor.value) params.cursor = nextCursor.value
      const body = await api.get(
        `/api/artist/${encodeURIComponent(slug)}/images`, { params }
      )
      if (!t.isCurrent()) return
      images.value.push(...body.images)
      nextCursor.value = body.next_cursor
      started = true
    } catch (e) {
      if (!t.isCurrent()) return
      error.value = e.message
    } finally {
      if (t.isCurrent()) imagesLoading.value = false
    }
  }

  // Rename the DISPLAY name only (#130). The slug is immutable, so the route
  // (slug-based) and on-disk paths are unaffected — just patch the shown name.
  async function rename (name) {
    if (!overview.value) return
    const id = overview.value.id
    const body = await api.patch(`/api/artists/${id}`, { body: { name } })
    if (overview.value && overview.value.id === id) overview.value.name = body.name
    return body
  }

  const hasMoreImages = computed(() => !started || nextCursor.value !== null)
  const postCount = computed(() => overview.value?.post_count ?? null)
  const imageCount = computed(() => overview.value?.image_count ?? null)
  const lastAdded = computed(() => overview.value?.date_range?.max ?? null)

  return {
    overview, images, loading, imagesLoading, error, notFound,
    hasMoreImages, postCount, imageCount, lastAdded,
    load, loadMoreImages, rename,
  }
})
