import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useCredentialsStore } from '../src/stores/credentials.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('credentials store', () => {
  beforeEach(() => setActivePinia(createPinia()))
  afterEach(() => vi.restoreAllMocks())

  it('loadAll populates byPlatform map', async () => {
    const s = useCredentialsStore()
    stubFetch(() => ({
      status: 200,
      body: [{ platform: 'patreon', credential_type: 'cookies', captured_at: '2026-05-20T00:00:00+00:00', expires_at: null, last_verified: null }],
    }))
    await s.loadAll()
    expect(s.byPlatform.get('patreon').credential_type).toBe('cookies')
  })

  it('upload reflects the returned record into the cache', async () => {
    // The previous behavior was to delete the cache entry on upload, which
    // briefly showed "no credential" until a follow-up loadAll() resolved.
    // Audit 2026-06-02 corrected this: upload now stores the returned
    // record directly so the card updates immediately.
    const s = useCredentialsStore()
    s.byPlatform.set('patreon', { platform: 'patreon', credential_type: 'token' })
    const fresh = { platform: 'patreon', credential_type: 'cookies' }
    stubFetch(() => ({ status: 201, body: fresh }))
    await s.upload('patreon', 'cookies', 'NETSCAPE_CONTENT')
    expect(s.byPlatform.get('patreon')).toEqual(fresh)
  })

  it('remove deletes and invalidates the cache', async () => {
    const s = useCredentialsStore()
    s.byPlatform.set('patreon', { platform: 'patreon' })
    stubFetch(() => ({ status: 204, body: null }))
    await s.remove('patreon')
    expect(s.byPlatform.has('patreon')).toBe(false)
  })

  it('loadKey + rotateKey', async () => {
    const s = useCredentialsStore()
    const seen = []
    stubFetch((url) => {
      seen.push(url)
      if (url.endsWith('/rotate')) return { status: 200, body: { key: 'NEW' } }
      return { status: 200, body: { key: 'OLD' } }
    })
    await s.loadKey()
    expect(s.extensionKey).toBe('OLD')
    await s.rotateKey()
    expect(s.extensionKey).toBe('NEW')
  })
})
