// @vitest-environment jsdom
import { cleanup, render, screen } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import InvitePage from './InvitePage';

vi.mock('react-i18next', async (importOriginal) => ({
  ...(await importOriginal<typeof import('react-i18next')>()),
  useTranslation: () => ({ t: (key: string) => key, i18n: { language: 'en' } }),
}));

function mockFetch(invite: { ok: boolean; status: number; body?: unknown }) {
  return vi.fn((input: RequestInfo | URL) => {
    const url = String(input);
    if (url.includes('/api/invite/')) {
      return Promise.resolve({
        ok: invite.ok,
        status: invite.status,
        json: () => Promise.resolve(invite.body ?? {}),
      } as Response);
    }
    return Promise.resolve({
      ok: true,
      status: 200,
      json: () => Promise.resolve({ current_price_pence: 4999 }),
    } as Response);
  });
}

const baseProps = {
  user: null,
  theme: 'light' as const,
  onLoginClick: vi.fn(),
  onRegisterClick: vi.fn(),
  onLicenseGranted: vi.fn(),
};

afterEach(() => {
  cleanup();
  vi.unstubAllGlobals();
  vi.restoreAllMocks();
});

describe('InvitePage invalid-invite messaging', () => {
  it('shows the unified copy for an unknown code (200 valid:false)', async () => {
    vi.stubGlobal(
      'fetch',
      mockFetch({
        ok: true,
        status: 200,
        body: { valid: false, invite_type: '', used: false, invited_by: null },
      })
    );
    render(<InvitePage code="BOGUS" {...baseProps} />);
    expect(await screen.findByText('invitePage.invalidInviteLink')).toBeTruthy();
  });

  it('shows the SAME copy for a malformed code rejected with 400', async () => {
    vi.stubGlobal('fetch', mockFetch({ ok: false, status: 400 }));
    render(<InvitePage code="%20" {...baseProps} />);
    expect(await screen.findByText('invitePage.invalidInviteLink')).toBeTruthy();
    expect(screen.queryByText('invitePage.invalidInvite')).toBeNull();
  });
});
