/**
 * csrfMiddleware 401-handling regression tests.
 *
 * Bug: clicking Logout (or landing on /login) flooded GET /api/session with 401s
 * and the page hung instead of returning to the login screen.
 *
 * Root cause: the middleware redirected on EVERY 401, including the session
 * probe's own 401. The redirect invalidated the ['session'] query, which
 * refetched GET /api/session, which 401'd, which redirected again → an infinite
 * refetch loop. These tests pin the fix: the session probe and the login
 * endpoint own their 401s (no redirect); any other endpoint's 401 still
 * redirects (session expired mid-use).
 *
 * We call onResponse() directly (rather than going through apiClient.GET) so the
 * test exercises the exact 401 branch without the singleton's relative baseUrl,
 * which has no absolute origin to resolve against under jsdom.
 */

import { describe, it, expect, vi, beforeEach } from 'vitest'
import type { Middleware } from 'openapi-fetch'
import { csrfMiddleware, registerLoginRedirect } from './client'

type OnResponse = NonNullable<Middleware['onResponse']>
type OnResponseParams = Parameters<OnResponse>[0]

/** Build the minimal onResponse params for the given schema path + response. */
function params(schemaPath: string, response: Response): OnResponseParams {
  return { schemaPath, response, request: new Request('http://test.local' + schemaPath) } as OnResponseParams
}

function response401(): Response {
  return new Response(JSON.stringify({ detail: 'unauthorized' }), {
    status: 401,
    headers: { 'Content-Type': 'application/json' },
  })
}

const onResponse = csrfMiddleware.onResponse as OnResponse

describe('csrfMiddleware 401 redirect (session-flood regression)', () => {
  const redirect = vi.fn()

  beforeEach(() => {
    redirect.mockReset()
    registerLoginRedirect(redirect)
  })

  it('does NOT redirect when GET /api/session returns 401 (probe owns its 401)', async () => {
    await onResponse(params('/api/session', response401()))
    expect(redirect).not.toHaveBeenCalled()
  })

  it('does NOT redirect when POST /api/auth/login returns 401 (bad credentials)', async () => {
    await onResponse(params('/api/auth/login', response401()))
    expect(redirect).not.toHaveBeenCalled()
  })

  it('redirects when a normal endpoint returns 401 (session expired mid-use)', async () => {
    await onResponse(params('/api/locations', response401()))
    expect(redirect).toHaveBeenCalledTimes(1)
  })
})
