import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useTagStore } from '../src/stores/tags.js'

function stubFetch(handler) {
  globalThis.fetch = vi.fn(async (url, init) => {
    const { status, body } = handler(url, init)
    return {
      ok: status >= 200 && status < 300,
      status,
      statusText: String(status),
      text: async () => (body == null ? '' : JSON.stringify(body)),
    }
  })
}

describe('tags store: setFandom', () => {
  beforeEach(() => setActivePinia(createPinia()))
  afterEach(() => vi.restoreAllMocks())

  it('PATCHes fandom_id, and null to clear', async () => {
    const s = useTagStore()
    const calls = []
    stubFetch((url, init) => {
      calls.push({ url, init })
      return { status: 200, body: { id: 5, name: 'Ichigo', kind: 'character', fandom_id: 9 } }
    })
    const body = await s.setFandom(5, 9)
    expect(body.fandom_id).toBe(9)
    const last = calls.at(-1)
    expect(last.url).toContain('/api/tags/5')
    expect(last.init.method).toBe('PATCH')
    expect(JSON.parse(last.init.body)).toEqual({ fandom_id: 9 })

    await s.setFandom(5, null)
    expect(JSON.parse(calls.at(-1).init.body)).toEqual({ fandom_id: null })
  })

  it('sends merge: true when requested', async () => {
    const s = useTagStore()
    const calls = []
    stubFetch((url, init) => {
      calls.push({ url, init })
      return { status: 200, body: { id: 2 } }
    })
    await s.setFandom(7, 3, { merge: true })
    expect(JSON.parse(calls.at(-1).init.body)).toEqual({ fandom_id: 3, merge: true })
  })

  it('throws ApiError carrying the 409 collision body', async () => {
    const s = useTagStore()
    stubFetch(() => ({
      status: 409,
      body: { error: 'exists', target: { id: 42, name: 'Renji' } },
    }))
    await expect(s.setFandom(1, 2)).rejects.toMatchObject({
      status: 409,
      body: { target: { id: 42 } },
    })
  })
})
