// updateSession — unauth-Redirect-Vertrag (Kais-Befund 22.07.2026): Der
// Middleware-Guard feuert VOR jedem Page-Level-Guard und muss dem Login das
// ursprüngliche Ziel als ?next= mitgeben, sonst strandet jeder Deep-Link ohne
// Session auf dem /projektanlage-Fallback. PR #358 fixte nur die Page-Ebene —
// live blieb der Middleware-Redirect ohne next (empirisch: curl 307 auf
// /login mit durchgereichter Original-Query). Diese Datei testet exakt den
// Redirect-Zweig; Supabase ist gemockt, die NextRequest-Objekte sind echt.

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { NextRequest } from 'next/server'

let currentClaims: { sub: string } | null = null

vi.mock('@supabase/ssr', () => ({
  createServerClient: vi.fn(() => ({
    auth: { getClaims: vi.fn(() => Promise.resolve({ data: { claims: currentClaims }, error: null })) },
    from: vi.fn(() => {
      const chain: Record<string, unknown> = {}
      chain.select = vi.fn(() => chain)
      chain.eq = vi.fn(() => chain)
      chain.maybeSingle = vi.fn(() => Promise.resolve({ data: null, error: null }))
      return chain
    }),
  })),
}))

beforeEach(() => {
  currentClaims = null
  vi.clearAllMocks()
})

async function runUpdateSession(url: string) {
  const { updateSession } = await import('../proxy')
  return updateSession(new NextRequest(url))
}

describe('updateSession — unauth redirect carries ?next=', () => {
  it('deep link with query: /login?next=<pathname+search>, original query NOT leaked onto /login', async () => {
    const res = await runUpdateSession('https://app.example.test/wertstrom/abc-123?compare=def-456')
    expect(res.status).toBe(307)
    const loc = new URL(res.headers.get('location')!)
    expect(loc.pathname).toBe('/login')
    expect(loc.searchParams.get('next')).toBe('/wertstrom/abc-123?compare=def-456')
    expect(loc.searchParams.get('compare')).toBeNull()
  })

  it('root path: plain /login without next (login fallback /projektanlage is the right landing)', async () => {
    const res = await runUpdateSession('https://app.example.test/')
    expect(res.status).toBe(307)
    const loc = new URL(res.headers.get('location')!)
    expect(loc.pathname).toBe('/login')
    expect(loc.searchParams.get('next')).toBeNull()
  })

  it('API path: redirect without next — landing on a JSON route after login helps no one', async () => {
    const res = await runUpdateSession('https://app.example.test/api/wertstrom/abc')
    expect(res.status).toBe(307)
    const loc = new URL(res.headers.get('location')!)
    expect(loc.pathname).toBe('/login')
    expect(loc.searchParams.get('next')).toBeNull()
  })

  it('authenticated: no redirect at all', async () => {
    currentClaims = { sub: 'user-1' }
    const res = await runUpdateSession('https://app.example.test/wertstrom')
    expect(res.headers.get('location')).toBeNull()
    expect(res.status).toBe(200)
  })
})
