// @vitest-environment jsdom
//
// The billing page. We mock `@voltro/client` (the live subscription + the three
// billing actions) and assert: the current plan renders, and the plan-change
// flow quotes the provider's proration BEFORE it can be confirmed (preview →
// confirm), not a locally-estimated figure.

import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
import { act, createElement, type ReactNode } from 'react'
import { createRoot, type Root } from 'react-dom/client'
import { I18nProvider } from '@voltro/i18n'
import enCatalog from '../../../locales/en'

const subData = vi.fn<() => { data: unknown }>()
const previewRun = vi.fn<(input: unknown) => Promise<unknown>>()

vi.mock('@voltro/client', () => ({
  useSubscription: () => subData(),
  useAction: (_api: string, tag: string) => ({
    run: tag === 'billing.previewChange' ? previewRun : vi.fn().mockResolvedValue({ url: 'https://provider/portal' }),
    pending: false,
  }),
}))

const { default: Billing, meta, renderMode } = await import('./page')

;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true

let container: HTMLDivElement
let root: Root

const render = (node: ReactNode): void => {
  container = document.createElement('div')
  document.body.appendChild(container)
  act(() => {
    root = createRoot(container)
    root.render(
      createElement(I18nProvider, { locale: 'en', messages: enCatalog, defaultLocale: 'en', children: node }),
    )
  })
}

beforeEach(() => {
  subData.mockReset()
  subData.mockReturnValue({ data: { subscription: { plan: 'free', status: 'active', quantity: 1, currentPeriodEnd: null, cancelAt: null } } })
  previewRun.mockReset()
  previewRun.mockResolvedValue({ plan: 'pro', quantity: 1, prorationMinor: 900, currency: 'usd' })
})

afterEach(() => {
  if (root) act(() => root.unmount())
  container?.remove()
  document.body.innerHTML = ''
})

describe('billing — config', () => {
  test('is an SSR page titled Billing (so the parent gate runs per request)', () => {
    expect(renderMode).toBe('ssr')
    expect(meta({ locale: 'en' }).title).toBe('Billing')
  })
})

describe('billing — render + change flow', () => {
  test('shows the current plan', () => {
    render(createElement(Billing))
    expect(container.textContent).toContain('free')
    expect(container.textContent).toContain('Current plan')
  })

  test('previewing the upgrade quotes the provider proration before confirm appears', async () => {
    render(createElement(Billing))
    // Before preview: the button is "Preview upgrade", not "Confirm".
    expect(container.textContent).toContain('Preview upgrade')
    expect(container.textContent).not.toContain('Confirm upgrade')

    const previewBtn = Array.from(container.querySelectorAll('button')).find((b) => b.textContent === 'Preview upgrade')!
    await act(async () => {
      previewBtn.dispatchEvent(new MouseEvent('click', { bubbles: true }))
      await Promise.resolve(); await Promise.resolve()
    })
    expect(previewRun).toHaveBeenCalledWith({ plan: 'pro' })
    // The quote is shown and now the confirm button is available.
    expect(container.textContent).toContain('settles at about')
    expect(container.textContent).toContain('Confirm upgrade')
  })
})
