// creation.ts tests (QVS-P2, KAR-971): title validation, previewToken
// staleness check, deselection + connection relinking, RPC error mapping,
// and idempotent-hit passthrough. loadQafSourceRows is mocked (controlled
// source rows); mapAndFingerprint/computePreviewToken run for REAL so the
// staleness check is exercised against the actual mapper output, not a stub.

import { describe, it, expect, vi, beforeEach } from 'vitest'
import type { QAFRow } from '@/lib/qaf-parser'
import type { QafSourceRows } from '../qaf-source'

const { loadQafSourceRowsMock } = vi.hoisted(() => ({ loadQafSourceRowsMock: vi.fn() }))

vi.mock('../qaf-source', async (importOriginal) => {
  const actual = await importOriginal<typeof import('../qaf-source')>()
  return { ...actual, loadQafSourceRows: loadQafSourceRowsMock }
})

import { createValueStreamFromQaf, createValueStreamsForVariants, severityForQvsWarningCode } from '../creation'
import { mapAndFingerprint } from '../qaf-source'

function makeRow(overrides: Partial<QAFRow> = {}): QAFRow {
  return {
    positionsnummer: '',
    teilebenennung: '',
    prozessbezeichnung: '',
    bezeichnungAnlage: '',
    standort: '',
    beschaffungswaehrung: '',
    zykluszeit: null,
    teileProZyklus: null,
    anzahlMA: null,
    lohnkosten: null,
    lohnzuschlagssaetze: null,
    mss: null,
    ruestkosten: null,
    fek: null,
    rfgk: null,
    fk: null,
    angebotswaehrung: '',
    wechselkurs: null,
    anzahlProAngebotsteil: null,
    fkAW: null,
    ausschuss: null,
    ausschusskosten: null,
    ...overrides,
  }
}

const SOURCE: QafSourceRows = {
  qafFile: {
    id: 'file-1',
    projectId: 'project-1',
    fileHash: 'hash-1',
    originalFileName: 'x.xlsx',
    parserVersion: 'p1',
    fileLevelContext: { plannedCapacityPartsPerYear: null, lotSizeParts: null },
  },
  rows: [
    makeRow({ prozessbezeichnung: 'Schweißen' }),
    makeRow({ prozessbezeichnung: 'Montage' }),
    makeRow({ prozessbezeichnung: 'Prüfen' }),
  ],
  stepIds: ['step-0', 'step-1', 'step-2'],
}

function validPreviewToken(): string {
  return mapAndFingerprint(SOURCE).previewToken
}

function makeSupabase(rpcImpl: (...args: unknown[]) => unknown) {
  return { rpc: vi.fn(rpcImpl) }
}

beforeEach(() => {
  loadQafSourceRowsMock.mockReset()
  loadQafSourceRowsMock.mockResolvedValue(SOURCE)
})

describe('createValueStreamFromQaf', () => {
  it('rejects a blank title without touching the DB', async () => {
    const supabase = makeSupabase(() => Promise.resolve({ data: null, error: null }))
    const result = await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: 'irrelevant',
      title: '   ',
    })
    expect(result).toEqual({ ok: false, error: { code: 'title_required' } })
    expect(loadQafSourceRowsMock).not.toHaveBeenCalled()
  })

  it('returns not_found when the qaf_file cannot be loaded (missing or not RLS-visible)', async () => {
    loadQafSourceRowsMock.mockResolvedValueOnce(null)
    const supabase = makeSupabase(() => Promise.resolve({ data: null, error: null }))
    const result = await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: 'irrelevant',
      title: 'My Wertstrom',
    })
    expect(result).toEqual({ ok: false, error: { code: 'not_found' } })
  })

  it('returns stale_preview when the confirmed token does not match a freshly recomputed one', async () => {
    const supabase = makeSupabase(() => Promise.resolve({ data: null, error: null }))
    const result = await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: 'stale-token-from-before-the-file-was-replaced',
      title: 'My Wertstrom',
    })
    expect(result).toEqual({ ok: false, error: { code: 'stale_preview' } })
    expect(supabase.rpc).not.toHaveBeenCalled()
  })

  it('returns no_steps_selected when every included step is deselected', async () => {
    const supabase = makeSupabase(() => Promise.resolve({ data: null, error: null }))
    const result = await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: validPreviewToken(),
      title: 'My Wertstrom',
      deselectedRowIndexes: [0, 1, 2],
    })
    expect(result).toEqual({ ok: false, error: { code: 'no_steps_selected' } })
    expect(supabase.rpc).not.toHaveBeenCalled()
  })

  it('calls the RPC with all 3 steps and the original linear connections when nothing is deselected', async () => {
    const supabase = makeSupabase(() =>
      Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null }),
    )
    const result = await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: validPreviewToken(),
      title: '  My Wertstrom  ',
    })

    expect(result).toEqual({ ok: true, result: { valueStreamId: 'vsm-1', importId: 'import-1', idempotentHit: false } })
    expect(supabase.rpc).toHaveBeenCalledTimes(1)
    const [, payload] = supabase.rpc.mock.calls[0] as [string, Record<string, unknown>]
    expect(payload.p_title).toBe('My Wertstrom')
    expect((payload.p_nodes as unknown[]).length).toBe(3)
    expect((payload.p_connections as unknown[]).length).toBe(2)
    expect(payload.p_imported_step_count).toBe(3)
    expect(payload.p_excluded_step_count).toBe(0)
  })

  it('deselecting the middle step drops it from p_nodes and relinks the remaining two directly', async () => {
    const supabase = makeSupabase(() =>
      Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null }),
    )
    await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: validPreviewToken(),
      title: 'My Wertstrom',
      deselectedRowIndexes: [1],
    })

    const [, payload] = supabase.rpc.mock.calls[0] as [string, Record<string, unknown>]
    const nodes = payload.p_nodes as Array<{ qafSource?: { rowIndex: number } }>
    const connections = payload.p_connections as Array<{ fromNodeId: string; toNodeId: string }>
    expect(nodes.map((n) => n.qafSource?.rowIndex)).toEqual([0, 2])
    expect(connections).toHaveLength(1)
    expect(connections[0].fromNodeId).toBe((nodes[0] as unknown as { id: string }).id)
    expect(connections[0].toNodeId).toBe((nodes[1] as unknown as { id: string }).id)
    expect(payload.p_imported_step_count).toBe(2)
    expect(payload.p_excluded_step_count).toBe(1)
  })

  // Review-Fix 5: a client-supplied out-of-range rowIndex (500 does not
  // exist in the 3-row SOURCE fixture) must not produce a phantom
  // `step_deselected` audit entry — manual_preview_corrections must only
  // ever reference rowIndexes that actually exist in the mapped nodes.
  it('ignores an out-of-range deselectedRowIndex when building manual_preview_corrections (phantom stepRef guard)', async () => {
    const supabase = makeSupabase(() =>
      Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null }),
    )
    await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: validPreviewToken(),
      title: 'My Wertstrom',
      deselectedRowIndexes: [1, 500],
    })

    const [, payload] = supabase.rpc.mock.calls[0] as [string, Record<string, unknown>]
    const nodes = payload.p_nodes as Array<{ qafSource?: { rowIndex: number } }>
    expect(nodes.map((n) => n.qafSource?.rowIndex)).toEqual([0, 2]) // rowIndex 500 never matched anything — already tolerant
    expect(payload.p_excluded_step_count).toBe(1) // only the real exclusion (rowIndex 1) counts, not the bogus 500

    const p_payload = payload.p_payload as { manualPreviewCorrections: Array<{ kind: string; stepRef: string }> | null }
    expect(p_payload.manualPreviewCorrections).toEqual([{ kind: 'step_deselected', stepRef: '1' }])
  })

  it('maps a qaf_file_not_found RPC error to the not_found code', async () => {
    const supabase = makeSupabase(() => Promise.resolve({ data: null, error: { message: 'qaf_file_not_found' } }))
    const result = await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: validPreviewToken(),
      title: 'My Wertstrom',
    })
    expect(result).toEqual({ ok: false, error: { code: 'not_found' } })
  })

  // Review-Fix 5 (PR #337): both are only reachable via a direct, tampered
  // .rpc() call (never via this module's own app-sanctioned path — see the
  // migration's own comments), but must still map to their own specific,
  // non-transient error codes rather than falling into the generic db_error
  // bucket.
  it('maps an invalid_step_count RPC error to its own code', async () => {
    const supabase = makeSupabase(() => Promise.resolve({ data: null, error: { message: 'invalid_step_count' } }))
    const result = await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: validPreviewToken(),
      title: 'My Wertstrom',
    })
    expect(result).toEqual({ ok: false, error: { code: 'invalid_step_count' } })
  })

  it('maps an import_id_conflict RPC error to its own code', async () => {
    const supabase = makeSupabase(() => Promise.resolve({ data: null, error: { message: 'import_id_conflict' } }))
    const result = await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: validPreviewToken(),
      title: 'My Wertstrom',
    })
    expect(result).toEqual({ ok: false, error: { code: 'import_id_conflict' } })
  })

  it('passes through an unrecognized RPC error as db_error with the original message', async () => {
    const supabase = makeSupabase(() => Promise.resolve({ data: null, error: { message: 'connection reset' } }))
    const result = await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: validPreviewToken(),
      title: 'My Wertstrom',
    })
    expect(result).toEqual({ ok: false, error: { code: 'db_error', message: 'connection reset' } })
  })

  it('passes through idempotent_hit: true from the RPC unchanged', async () => {
    const supabase = makeSupabase(() =>
      Promise.resolve({ data: { value_stream_id: 'vsm-existing', import_id: 'import-existing', idempotent_hit: true }, error: null }),
    )
    const result = await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: validPreviewToken(),
      title: 'My Wertstrom',
    })
    expect(result).toEqual({
      ok: true,
      result: { valueStreamId: 'vsm-existing', importId: 'import-existing', idempotentHit: true },
    })
  })
})

// QVS-P4 (KAR-973, gap-analysis G5, ux-flow.md §4): variant tagging on a
// single createValueStreamFromQaf call ("geteilter Fluss") + the
// createValueStreamsForVariants N-create orchestrator ("je Variante ein
// Wertstrom").
describe('createValueStreamFromQaf — variantTagging (QVS-P4)', () => {
  it('tags every remaining node with ALL variantTags and persists the variantSelector verbatim', async () => {
    const supabase = makeSupabase(() =>
      Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null }),
    )
    await createValueStreamFromQaf(
      supabase as never,
      { qafFileId: 'file-1', previewToken: validPreviewToken(), title: 'My Wertstrom' },
      { variantTags: ['region=eu', 'region=us'], variantSelector: { strategy: 'shared_flow', variantKeys: ['region=eu', 'region=us'] } },
    )

    const [, payload] = supabase.rpc.mock.calls[0] as [string, Record<string, unknown>]
    const nodes = payload.p_nodes as Array<{ variantTags?: string[] }>
    expect(nodes.every((n) => n.variantTags?.length === 2)).toBe(true)
    expect(nodes[0].variantTags).toEqual(['region=eu', 'region=us'])

    const p_payload = payload.p_payload as { variantSelector: unknown }
    expect(p_payload.variantSelector).toEqual({ strategy: 'shared_flow', variantKeys: ['region=eu', 'region=us'] })
  })

  it('omitting variantTagging keeps variant_selector null and never sets variantTags — byte-compatible with P2/P3', async () => {
    const supabase = makeSupabase(() =>
      Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null }),
    )
    await createValueStreamFromQaf(supabase as never, { qafFileId: 'file-1', previewToken: validPreviewToken(), title: 'My Wertstrom' })

    const [, payload] = supabase.rpc.mock.calls[0] as [string, Record<string, unknown>]
    const nodes = payload.p_nodes as Array<{ variantTags?: string[] }>
    expect(nodes.every((n) => n.variantTags === undefined)).toBe(true)
    const p_payload = payload.p_payload as { variantSelector: unknown }
    expect(p_payload.variantSelector).toBeNull()
  })

  it('persists sum_planned_capacity/sum_lot_size on engine_context from the source file-level context', async () => {
    const supabase = makeSupabase(() =>
      Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null }),
    )
    const sourceWithCapacity = {
      ...SOURCE,
      qafFile: { ...SOURCE.qafFile, fileLevelContext: { plannedCapacityPartsPerYear: 221500, lotSizeParts: 250 } },
    }
    loadQafSourceRowsMock.mockResolvedValueOnce(sourceWithCapacity)
    await createValueStreamFromQaf(supabase as never, {
      qafFileId: 'file-1',
      previewToken: mapAndFingerprint(sourceWithCapacity).previewToken,
      title: 'My Wertstrom',
    })

    const [, payload] = supabase.rpc.mock.calls[0] as [string, Record<string, unknown>]
    const p_payload = payload.p_payload as { engineContext: { plannedCapacityPartsPerYear: number | null; lotSizeParts: number | null } }
    expect(p_payload.engineContext.plannedCapacityPartsPerYear).toBe(221500)
    expect(p_payload.engineContext.lotSizeParts).toBe(250)
  })

  it('appends persistedTokenSuffix ONLY to the persisted engine_context.previewToken, not the staleness check', async () => {
    const supabase = makeSupabase(() =>
      Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null }),
    )
    const trueToken = validPreviewToken()
    const result = await createValueStreamFromQaf(
      supabase as never,
      // The CLIENT-supplied previewToken is still the true, unmodified one —
      // the suffix is a persistence-only concern the caller never sees.
      { qafFileId: 'file-1', previewToken: trueToken, title: 'My Wertstrom' },
      { variantTags: ['v1'], variantSelector: { strategy: 'per_variant', variantKeys: ['v1'] }, persistedTokenSuffix: 'variant:v1' },
    )
    expect(result.ok).toBe(true)

    const [, payload] = supabase.rpc.mock.calls[0] as [string, Record<string, unknown>]
    const p_payload = payload.p_payload as { engineContext: { previewToken: string } }
    expect(p_payload.engineContext.previewToken).toBe(`${trueToken}:variant:v1`)
  })

  // Review-Fix (critical, KAR-974 adversarial review — reimport.ts's
  // createComparisonValueStreamFromSync): a non-variant caller needs the SAME
  // suffix mechanism without any variant-tagging side effects.
  it('a bare options.persistedTokenSuffix (no variantTagging) also reaches the persisted previewToken, with no variant semantics leaking in', async () => {
    const supabase = makeSupabase(() =>
      Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null }),
    )
    const trueToken = validPreviewToken()
    const result = await createValueStreamFromQaf(
      supabase as never,
      { qafFileId: 'file-1', previewToken: trueToken, title: 'My Wertstrom' },
      undefined,
      { persistedTokenSuffix: 'reimport-comparison:vsm-1:2026-07-17' },
    )
    expect(result.ok).toBe(true)

    const [, payload] = supabase.rpc.mock.calls[0] as [string, Record<string, unknown>]
    const p_payload = payload.p_payload as { engineContext: { previewToken: string }; variantSelector: unknown }
    expect(p_payload.engineContext.previewToken).toBe(`${trueToken}:reimport-comparison:vsm-1:2026-07-17`)
    expect(p_payload.variantSelector).toBeNull()
    const nodes = payload.p_nodes as Array<{ variantTags?: string[] }>
    expect(nodes.every((n) => n.variantTags === undefined)).toBe(true)
  })

  it('two variantTagging calls against the SAME source produce two DIFFERENT persisted previewTokens (no idempotent collapse)', async () => {
    const supabase = makeSupabase(() =>
      Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null }),
    )
    const token = validPreviewToken()
    await createValueStreamFromQaf(
      supabase as never,
      { qafFileId: 'file-1', previewToken: token, title: 'My Wertstrom' },
      { variantTags: ['v1'], variantSelector: { strategy: 'per_variant', variantKeys: ['v1'] }, persistedTokenSuffix: 'variant:v1' },
    )
    await createValueStreamFromQaf(
      supabase as never,
      { qafFileId: 'file-1', previewToken: token, title: 'My Wertstrom' },
      { variantTags: ['v2'], variantSelector: { strategy: 'per_variant', variantKeys: ['v2'] }, persistedTokenSuffix: 'variant:v2' },
    )

    const [, payload1] = supabase.rpc.mock.calls[0] as [string, Record<string, unknown>]
    const [, payload2] = supabase.rpc.mock.calls[1] as [string, Record<string, unknown>]
    const token1 = (payload1.p_payload as { engineContext: { previewToken: string } }).engineContext.previewToken
    const token2 = (payload2.p_payload as { engineContext: { previewToken: string } }).engineContext.previewToken
    expect(token1).not.toBe(token2)
  })
})

describe('createValueStreamsForVariants (QVS-P4, "je Variante ein Wertstrom")', () => {
  it('calls the RPC once per variant, sequentially, each tagged with exactly ONE key', async () => {
    const rpcCalls: Array<Record<string, unknown>> = []
    const supabase = makeSupabase((...args: unknown[]) => {
      const [, payload] = args as [string, Record<string, unknown>]
      rpcCalls.push(payload)
      return Promise.resolve({
        data: { value_stream_id: `vsm-${rpcCalls.length}`, import_id: `import-${rpcCalls.length}`, idempotent_hit: false },
        error: null,
      })
    })

    const results = await createValueStreamsForVariants(
      supabase as never,
      { qafFileId: 'file-1', previewToken: validPreviewToken(), title: 'My Wertstrom' },
      [
        { variantKey: 'region=eu', label: 'EU' },
        { variantKey: 'region=us', label: 'US' },
        { variantKey: 'region=cn', label: 'CN' },
      ],
    )

    expect(supabase.rpc).toHaveBeenCalledTimes(3)
    expect(results).toHaveLength(3)
    expect(results.map((r) => r.variantKey)).toEqual(['region=eu', 'region=us', 'region=cn'])
    expect(results.every((r) => r.outcome.ok)).toBe(true)
    expect(results.map((r) => (r.outcome.ok ? r.outcome.result.valueStreamId : null))).toEqual(['vsm-1', 'vsm-2', 'vsm-3'])

    for (const payload of rpcCalls) {
      const nodes = payload.p_nodes as Array<{ variantTags?: string[] }>
      expect(nodes.every((n) => n.variantTags?.length === 1)).toBe(true)
    }
    expect((rpcCalls[0].p_nodes as Array<{ variantTags?: string[] }>)[0].variantTags).toEqual(['region=eu'])
    expect((rpcCalls[1].p_nodes as Array<{ variantTags?: string[] }>)[0].variantTags).toEqual(['region=us'])
  })

  // Review-Fix 3 (KAR-973 adversarial review, MAJOR — N byte-identical
  // titles): every RPC call used to receive the exact same p_title, making
  // the N resulting value_stream_maps rows indistinguishable in the
  // /wertstrom list. Each call must now carry its own variant-label suffix.
  describe('per-variant title suffix (Review-Fix 3)', () => {
    it('suffixes each RPC call\'s p_title with "· <variant label>", producing N DISTINCT titles', async () => {
      const rpcCalls: Array<Record<string, unknown>> = []
      const supabase = makeSupabase((...args: unknown[]) => {
        const [, payload] = args as [string, Record<string, unknown>]
        rpcCalls.push(payload)
        return Promise.resolve({
          data: { value_stream_id: `vsm-${rpcCalls.length}`, import_id: `import-${rpcCalls.length}`, idempotent_hit: false },
          error: null,
        })
      })

      await createValueStreamsForVariants(
        supabase as never,
        { qafFileId: 'file-1', previewToken: validPreviewToken(), title: 'My Wertstrom' },
        [
          { variantKey: 'region=eu', label: 'EU' },
          { variantKey: 'region=us', label: 'US' },
        ],
      )

      const titles = rpcCalls.map((p) => p.p_title)
      expect(titles).toEqual(['My Wertstrom · EU', 'My Wertstrom · US'])
      expect(new Set(titles).size).toBe(2)
    })

    it('falls back to the variantKey as the title suffix when label is blank (collision-safe defensive guard)', async () => {
      const rpcCalls: Array<Record<string, unknown>> = []
      const supabase = makeSupabase((...args: unknown[]) => {
        const [, payload] = args as [string, Record<string, unknown>]
        rpcCalls.push(payload)
        return Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null })
      })

      await createValueStreamsForVariants(
        supabase as never,
        { qafFileId: 'file-1', previewToken: validPreviewToken(), title: 'My Wertstrom' },
        [{ variantKey: 'slot-9', label: '   ' }],
      )

      expect(rpcCalls[0].p_title).toBe('My Wertstrom · slot-9')
    })

    it('does not mutate the original confirmation across variants (each RPC call gets its own title, not an accumulating one)', async () => {
      const rpcCalls: Array<Record<string, unknown>> = []
      const supabase = makeSupabase((...args: unknown[]) => {
        const [, payload] = args as [string, Record<string, unknown>]
        rpcCalls.push(payload)
        return Promise.resolve({ data: { value_stream_id: 'vsm-1', import_id: 'import-1', idempotent_hit: false }, error: null })
      })
      const confirmation = { qafFileId: 'file-1', previewToken: validPreviewToken(), title: 'My Wertstrom' }

      await createValueStreamsForVariants(supabase as never, confirmation, [
        { variantKey: 'region=eu', label: 'EU' },
        { variantKey: 'region=us', label: 'US' },
      ])

      expect(confirmation.title).toBe('My Wertstrom') // untouched
      expect(rpcCalls[0].p_title).toBe('My Wertstrom · EU')
      expect(rpcCalls[1].p_title).toBe('My Wertstrom · US') // not "My Wertstrom · EU · US"
    })
  })

  it('every call gets a distinct persisted previewToken (each variant is its own import, never an idempotent resubmit of another)', async () => {
    const persistedTokens: string[] = []
    const supabase = makeSupabase((...args: unknown[]) => {
      const [, payload] = args as [string, Record<string, unknown>]
      const p_payload = payload.p_payload as { engineContext: { previewToken: string } }
      persistedTokens.push(p_payload.engineContext.previewToken)
      return Promise.resolve({ data: { value_stream_id: 'vsm-x', import_id: 'import-x', idempotent_hit: false }, error: null })
    })

    await createValueStreamsForVariants(
      supabase as never,
      { qafFileId: 'file-1', previewToken: validPreviewToken(), title: 'My Wertstrom' },
      [
        { variantKey: 'region=eu', label: 'EU' },
        { variantKey: 'region=us', label: 'US' },
      ],
    )

    expect(new Set(persistedTokens).size).toBe(2)
  })

  it('reports a mid-sequence failure honestly — does not abort remaining variants, does not hide the failure', async () => {
    let call = 0
    const supabase = makeSupabase(() => {
      call++
      if (call === 2) return Promise.resolve({ data: null, error: { message: 'connection reset' } })
      return Promise.resolve({ data: { value_stream_id: `vsm-${call}`, import_id: `import-${call}`, idempotent_hit: false }, error: null })
    })

    const results = await createValueStreamsForVariants(
      supabase as never,
      { qafFileId: 'file-1', previewToken: validPreviewToken(), title: 'My Wertstrom' },
      [
        { variantKey: 'region=eu', label: 'EU' },
        { variantKey: 'region=us', label: 'US' },
        { variantKey: 'region=cn', label: 'CN' },
      ],
    )

    expect(supabase.rpc).toHaveBeenCalledTimes(3) // continues past the failure, does not abort
    expect(results[0].outcome).toEqual({ ok: true, result: { valueStreamId: 'vsm-1', importId: 'import-1', idempotentHit: false } })
    expect(results[1].outcome).toEqual({ ok: false, error: { code: 'db_error', message: 'connection reset' } })
    expect(results[2].outcome).toEqual({ ok: true, result: { valueStreamId: 'vsm-3', importId: 'import-3', idempotentHit: false } })
  })

  it('propagates a shared blocking condition (e.g. stale_preview) identically to every variant', async () => {
    const supabase = makeSupabase(() => Promise.resolve({ data: null, error: null }))
    const results = await createValueStreamsForVariants(
      supabase as never,
      { qafFileId: 'file-1', previewToken: 'stale-token', title: 'My Wertstrom' },
      [
        { variantKey: 'region=eu', label: 'EU' },
        { variantKey: 'region=us', label: 'US' },
      ],
    )
    expect(supabase.rpc).not.toHaveBeenCalled()
    expect(results.every((r) => !r.outcome.ok && r.outcome.error.code === 'stale_preview')).toBe(true)
  })
})

// QVS-P3 (KAR-972): severityForQvsWarningCode exposes the exact severity
// table toPersistedWarning uses internally, so the Preview dialog's warning
// badges (still built from the plain QvsWarning[] on QvsImportPreview) can
// never drift from what a confirmed create actually persists.
describe('severityForQvsWarningCode', () => {
  it('returns "warning" for both current QvsWarningCode values', () => {
    expect(severityForQvsWarningCode('sequence_ambiguous')).toBe('warning')
    expect(severityForQvsWarningCode('no_eligible_rows')).toBe('warning')
  })
})
