import 'server-only'

import { liveSynchronPayments } from './live'
import { createMockSynchronPayments, isMockScenario, type MockScenario } from './mock'
import type { SynchronPaymentsAdapter } from './types'

export * from './types'
export { MOCK_SCENARIOS, isMockScenario, mockChooseCheckoutOutcome, mockChooseCardSetupOutcome, type MockScenario } from './mock'

/**
 * Adapter selection (task §11, §27).
 *
 *   SYNCHRON_PAYMENTS_MODE=mock  AND  NODE_ENV !== 'production'  → mock
 *   anything else                                                → live (unconnected stub)
 *
 * Production can never resolve to the mock, whatever the env says, so a mock
 * confirmation can never mark a real transaction as paid.
 */
export function synchronPaymentsMode(): 'live' | 'mock' {
  if (process.env.NODE_ENV === 'production') return 'live'
  return process.env.SYNCHRON_PAYMENTS_MODE === 'mock' ? 'mock' : 'live'
}

export function isMockPaymentsActive(): boolean {
  return synchronPaymentsMode() === 'mock'
}

/** Default scenario when the request does not pick one. */
export const DEFAULT_MOCK_SCENARIO: MockScenario = 'card_on_file'

/**
 * Read the scenario a dev request asked for: header `x-hha-mock-scenario`
 * or query `?mock=`. Ignored outside mock mode.
 */
export function mockScenario(req?: { headers?: { get(name: string): string | null }; nextUrl?: { searchParams: URLSearchParams } }): MockScenario {
  const fromHeader = req?.headers?.get('x-hha-mock-scenario')
  const fromQuery = req?.nextUrl?.searchParams.get('mock')
  const env = process.env.SYNCHRON_PAYMENTS_MOCK_SCENARIO
  const candidate = fromHeader || fromQuery || env
  return isMockScenario(candidate) ? candidate : DEFAULT_MOCK_SCENARIO
}

export function getSynchronPayments(opts: { scenario?: MockScenario; appOrigin: string }): SynchronPaymentsAdapter {
  if (synchronPaymentsMode() === 'mock') return createMockSynchronPayments(opts.scenario ?? DEFAULT_MOCK_SCENARIO, opts.appOrigin)
  return liveSynchronPayments
}

/** Is a status/confirmation from this source allowed to change a purchase right now? */
export function isTrustedPaymentSource(source: 'synchron' | 'mock'): boolean {
  if (source === 'synchron') return true
  return isMockPaymentsActive()
}
