import { render, screen, waitFor, cleanup, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import OnboardingForm from '../OnboardingForm';
import { useRouter } from 'next/navigation';

/**
 * Helper to fill form fields instantly using fireEvent.
 * Use this when testing data persistence/flow, not typing behavior.
 */
function fillField(element: HTMLElement, value: string) {
  fireEvent.change(element, { target: { value } });
}

// Mock Next.js router
jest.mock('next/navigation', () => ({
  useRouter: jest.fn(),
}));

// Mock fetch for API calls
global.fetch = jest.fn();

// Clean up after each test to prevent state leakage
afterEach(() => {
  cleanup();
  jest.resetAllMocks();
});

describe('OnboardingForm - Business Logic', () => {
  const mockRouterPush = jest.fn();
  const defaultProps = {
    dealerId: 'dealer123',
    sessionId: 'session456',
    subscriptionTier: 'starter',
    defaultDomain: 'com',
    hasSubdomain: false,
    initialData: {
      subdomain: '',
      customDomain: '',
      dealerNumber: '',
      name: 'Test Dealer',
      email: 'test@example.com',
      phone: '',
      address: '',
      city: '',
      state: '',
      zip: '',
    },
  };

  beforeEach(() => {
    jest.clearAllMocks();
    (useRouter as jest.Mock).mockReturnValue({
      push: mockRouterPush,
    });
    (global.fetch as jest.Mock).mockResolvedValue({
      json: async () => ({ available: true }),
    });
  });

  describe('Subdomain Validation', () => {
    // Helper to navigate to subdomain step with filled profile
    // Note: hasSubdomain: false starts on profile, we fill fields and click continue
    const filledProfileProps = {
      ...defaultProps,
      initialData: {
        ...defaultProps.initialData,
        dealerNumber: '123456',
        email: 'test@example.com',
        phone: '555-1234',
        address: '123 Main St',
        city: 'Springfield',
        state: 'IL',
        zip: '62701',
      },
    };

    async function navigateToSubdomainStep() {
      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      await userEvent.click(continueButton);
      await waitFor(() => {
        expect(screen.getByPlaceholderText('yourname')).toBeInTheDocument();
      });
    }

    test('accepts valid subdomain (lowercase, 3+ chars)', async () => {
      render(<OnboardingForm {...filledProfileProps} />);
      await navigateToSubdomainStep();

      const input = screen.getByPlaceholderText('yourname');
      await userEvent.type(input, 'validname');

      await waitFor(() => {
        expect(screen.getByText(/is available/i)).toBeInTheDocument();
      });
    });

    test('rejects subdomain with < 3 characters', async () => {
      render(<OnboardingForm {...filledProfileProps} />);
      await navigateToSubdomainStep();

      const input = screen.getByPlaceholderText('yourname');
      await userEvent.type(input, 'ab');

      // Should NOT show availability check for < 3 chars
      await waitFor(() => {
        expect(screen.queryByText(/checking availability/i)).not.toBeInTheDocument();
        expect(screen.queryByText(/is available/i)).not.toBeInTheDocument();
      });
    });

    test('rejects subdomain with > 63 characters', async () => {
      render(<OnboardingForm {...filledProfileProps} />);
      await navigateToSubdomainStep();

      const input = screen.getByPlaceholderText('yourname') as HTMLInputElement;

      // Test behavior: input has maxLength constraint for browser enforcement
      // Note: jsdom doesn't enforce maxLength like browsers do, so we verify the attribute
      expect(input.maxLength).toBe(63);
    });

    test('converts uppercase letters to lowercase', async () => {
      render(<OnboardingForm {...filledProfileProps} />);
      await navigateToSubdomainStep();

      const input = screen.getByPlaceholderText('yourname') as HTMLInputElement;

      // Test behavior: onChange handler lowercases input
      fillField(input, 'MixedCase');
      expect(input.value).toBe('mixedcase');
    });

    test('accepts hyphens in the middle of subdomain', async () => {
      render(<OnboardingForm {...filledProfileProps} />);
      await navigateToSubdomainStep();

      const input = screen.getByPlaceholderText('yourname');
      await userEvent.type(input, 'valid-name');

      await waitFor(() => {
        expect(screen.getByText(/is available/i)).toBeInTheDocument();
      });
    });

    test('shows availability check while typing (debounced)', async () => {
      // Mock with a slight delay to catch the checking state
      (global.fetch as jest.Mock).mockImplementationOnce(
        () =>
          new Promise((resolve) =>
            setTimeout(() => resolve({ json: async () => ({ available: true }) }), 100)
          )
      );

      render(<OnboardingForm {...filledProfileProps} />);
      await navigateToSubdomainStep();

      const input = screen.getByPlaceholderText('yourname');
      await userEvent.type(input, 'testing');

      // Should show "checking" state briefly (after debounce triggers)
      await waitFor(
        () => {
          expect(screen.getByText(/checking availability/i)).toBeInTheDocument();
        },
        { timeout: 1000 }
      );

      // Then should resolve to available
      await waitFor(() => {
        expect(screen.getByText(/is available/i)).toBeInTheDocument();
      });
    });

    test('shows "available" when API returns true', async () => {
      (global.fetch as jest.Mock).mockResolvedValueOnce({
        json: async () => ({ available: true }),
      });

      render(<OnboardingForm {...filledProfileProps} />);
      await navigateToSubdomainStep();

      const input = screen.getByPlaceholderText('yourname');
      await userEvent.type(input, 'available');

      await waitFor(() => {
        expect(screen.getByText(/available.myamsoil.com is available/i)).toBeInTheDocument();
      });
    });

    test('shows "not available" when API returns false', async () => {
      (global.fetch as jest.Mock).mockResolvedValueOnce({
        json: async () => ({
          available: false,
          reason: 'Subdomain already taken',
        }),
      });

      render(<OnboardingForm {...filledProfileProps} />);
      await navigateToSubdomainStep();

      const input = screen.getByPlaceholderText('yourname');
      await userEvent.type(input, 'taken');

      await waitFor(() => {
        expect(screen.getByText(/subdomain already taken/i)).toBeInTheDocument();
      });
    });

    test('displays correct domain extension for Canadian dealers', async () => {
      render(<OnboardingForm {...filledProfileProps} defaultDomain="ca" />);
      await navigateToSubdomainStep();

      // Domain extension is split across option text nodes: "myamsoil" + ".ca"
      expect(
        screen.getByText((content, element) => {
          return (
            element?.tagName === 'OPTION' && content.includes('myamsoil') && content.includes('.ca')
          );
        })
      ).toBeInTheDocument();
    });
  });

  describe('Step Progression Logic', () => {
    // With new step order: Step 1 = Profile, Step 2 = Domain, Step 3 = Review
    test('cannot proceed to step 2 without required profile fields', async () => {
      render(<OnboardingForm {...defaultProps} />);

      // Should start on profile step (Step 1) when hasSubdomain is false
      expect(screen.getByText(/business profile/i)).toBeInTheDocument();

      const continueButton = screen.getByRole('button', { name: /continue to domain/i });

      // Button should be disabled without required fields
      expect(continueButton).toBeDisabled();
    });

    test('can proceed to step 2 with all required profile fields', async () => {
      render(<OnboardingForm {...defaultProps} />);

      // Fill in required fields (dealer number and email are now required too)
      fillField(screen.getByLabelText(/zo account number/i), '123456');
      fillField(screen.getByLabelText(/contact email/i), 'test@example.com');
      fillField(screen.getByLabelText(/phone/i), '555-1234');
      fillField(screen.getByLabelText(/street address/i), '123 Main St');
      fillField(screen.getByLabelText(/city/i), 'Springfield');
      fillField(screen.getByLabelText(/state/i), 'IL');
      fillField(screen.getByLabelText(/zip/i), '62701');

      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      expect(continueButton).not.toBeDisabled();
    });

    test('cannot proceed to step 3 without valid subdomain', async () => {
      render(
        <OnboardingForm
          {...defaultProps}
          hasSubdomain={true}
          initialData={{
            ...defaultProps.initialData,
            subdomain: '',
          }}
        />
      );

      // Should be on subdomain step (Step 2) when hasSubdomain is true
      expect(screen.getByText(/choose your domain/i)).toBeInTheDocument();

      const continueButton = screen.getByRole('button', { name: /continue to review/i });

      // Button should be disabled without valid subdomain
      expect(continueButton).toBeDisabled();
    });

    test('can proceed to step 3 with valid available subdomain', async () => {
      (global.fetch as jest.Mock).mockResolvedValueOnce({
        json: async () => ({ available: true }),
      });

      render(
        <OnboardingForm
          {...defaultProps}
          hasSubdomain={true}
          initialData={{
            ...defaultProps.initialData,
            subdomain: '',
          }}
        />
      );

      const input = screen.getByPlaceholderText('yourname');
      await userEvent.type(input, 'validname');

      await waitFor(() => {
        const continueButton = screen.getByRole('button', { name: /continue to review/i });
        expect(continueButton).not.toBeDisabled();
      });
    });

    test('can navigate back to previous steps', async () => {
      render(
        <OnboardingForm
          {...defaultProps}
          hasSubdomain={true}
          initialData={{
            ...defaultProps.initialData,
            subdomain: 'existing',
          }}
        />
      );

      // Should be on subdomain step (Step 2) when hasSubdomain is true
      expect(screen.getByText(/choose your domain/i)).toBeInTheDocument();

      const backButton = screen.getByRole('button', { name: /back/i });
      await userEvent.click(backButton);

      // Should return to profile step (Step 1)
      expect(screen.getByText(/business profile/i)).toBeInTheDocument();
    });

    test('displays progress indicator for current step', async () => {
      render(<OnboardingForm {...defaultProps} />);

      // Step 1: Profile (new order)
      expect(screen.getByText('Step 1 of 3:')).toBeInTheDocument();
      expect(screen.getByText('Business Profile')).toBeInTheDocument();
    });
  });

  describe('Form Data Persistence', () => {
    // Pre-filled profile for navigation tests
    const filledProfileProps = {
      ...defaultProps,
      initialData: {
        ...defaultProps.initialData,
        dealerNumber: '123456',
        email: 'test@example.com',
        phone: '555-1234',
        address: '123 Main St',
        city: 'Springfield',
        state: 'IL',
        zip: '62701',
      },
    };

    test('subdomain persists when navigating between steps', async () => {
      (global.fetch as jest.Mock).mockResolvedValue({
        json: async () => ({ available: true }),
      });

      // Start on profile step with pre-filled data
      render(<OnboardingForm {...filledProfileProps} />);

      // Go to subdomain step
      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      await userEvent.click(continueButton);

      await waitFor(() => {
        expect(screen.getByPlaceholderText('yourname')).toBeInTheDocument();
      });

      // Enter subdomain
      const input = screen.getByPlaceholderText('yourname');
      await userEvent.type(input, 'persistent');

      await waitFor(() => {
        expect(screen.getByText(/is available/i)).toBeInTheDocument();
      });

      // Go back to profile step
      const backButton = screen.getByRole('button', { name: /back/i });
      await userEvent.click(backButton);

      // Go forward to subdomain step again
      const continueAgain = screen.getByRole('button', { name: /continue to domain/i });
      await userEvent.click(continueAgain);

      // Verify subdomain input still has the value
      await waitFor(() => {
        const subdomainInput = screen.getByPlaceholderText('yourname') as HTMLInputElement;
        expect(subdomainInput.value).toBe('persistent');
      });
    });

    test('profile data persists when navigating between steps', async () => {
      (global.fetch as jest.Mock).mockResolvedValue({
        json: async () => ({ available: true }),
      });

      // Start on subdomain step with existing subdomain
      render(
        <OnboardingForm
          {...defaultProps}
          hasSubdomain={true}
          initialData={{
            ...defaultProps.initialData,
            subdomain: 'existing',
          }}
        />
      );

      // Go back to profile step
      const backButton = screen.getByRole('button', { name: /back/i });
      await userEvent.click(backButton);

      // Fill in profile fields
      fillField(screen.getByLabelText(/zo account number/i), '123456');
      fillField(screen.getByLabelText(/contact email/i), 'test@example.com');
      fillField(screen.getByLabelText(/phone/i), '555-1234');
      fillField(screen.getByLabelText(/street address/i), '123 Main St');
      fillField(screen.getByLabelText(/city/i), 'Springfield');
      fillField(screen.getByLabelText(/state/i), 'IL');
      fillField(screen.getByLabelText(/zip/i), '62701');

      // Go to subdomain step
      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      await userEvent.click(continueButton);

      // Go to review step
      await waitFor(() => {
        expect(screen.getByText(/choose your domain/i)).toBeInTheDocument();
      });
      const reviewButton = screen.getByRole('button', { name: /continue to review/i });
      await userEvent.click(reviewButton);

      await waitFor(() => {
        expect(screen.getByText(/review & continue/i)).toBeInTheDocument();
      });

      // Go back to subdomain
      const backToEditButton = screen.getByRole('button', { name: /back to edit/i });
      await userEvent.click(backToEditButton);

      // Go back to profile
      const backToProfileButton = screen.getByRole('button', { name: /back/i });
      await userEvent.click(backToProfileButton);

      // Verify data persists
      expect((screen.getByLabelText(/phone/i) as HTMLInputElement).value).toBe('555-1234');
      expect((screen.getByLabelText(/street address/i) as HTMLInputElement).value).toBe(
        '123 Main St'
      );
    });

    test('all data available in review step', async () => {
      (global.fetch as jest.Mock).mockResolvedValue({
        json: async () => ({ available: true }),
      });

      // Start on subdomain step
      render(
        <OnboardingForm
          {...defaultProps}
          hasSubdomain={true}
          initialData={{
            ...defaultProps.initialData,
            subdomain: 'review',
            name: 'Test Business',
            email: 'test@example.com',
          }}
        />
      );

      // Go to review
      const continueButton = screen.getByRole('button', { name: /continue to review/i });
      await userEvent.click(continueButton);

      await waitFor(() => {
        // Verify all data is shown
        expect(screen.getByText(/review.myamsoil.com/i)).toBeInTheDocument();
        expect(screen.getByText('Test Business')).toBeInTheDocument();
        expect(screen.getByText('test@example.com')).toBeInTheDocument();
      });
    });
  });

  describe('Form Submission', () => {
    // Pre-filled profile data for submission tests
    const filledProfileData = {
      ...defaultProps.initialData,
      subdomain: 'test',
      dealerNumber: '123456',
      email: 'test@example.com',
      phone: '555-1234',
      address: '123 Main St',
      city: 'Springfield',
      state: 'IL',
      zip: '62701',
    };

    test('handles API errors gracefully on registration save', async () => {
      (global.fetch as jest.Mock).mockResolvedValueOnce({
        json: async () => ({
          success: false,
          error: 'Profile save failed',
        }),
      });

      render(
        <OnboardingForm {...defaultProps} hasSubdomain={true} initialData={filledProfileData} />
      );

      // Start on subdomain step, go to review
      const continueButton = screen.getByRole('button', { name: /continue to review/i });
      await userEvent.click(continueButton);

      // Should advance to review step
      await waitFor(() => {
        expect(screen.getByText(/review & continue/i)).toBeInTheDocument();
      });

      // Now click continue to dashboard to trigger the API call
      const continueToDbButton = screen.getByRole('button', { name: /continue to dashboard/i });
      await userEvent.click(continueToDbButton);

      // Should show error from API
      await waitFor(() => {
        expect(screen.getByText(/profile save failed/i)).toBeInTheDocument();
      });
    });

    test('calls register/complete API with registration data (no publish API)', async () => {
      (global.fetch as jest.Mock).mockResolvedValueOnce({
        json: async () => ({ success: true }),
      });

      render(
        <OnboardingForm
          {...defaultProps}
          hasSubdomain={true}
          initialData={{ ...filledProfileData, subdomain: 'testdealer' }}
        />
      );

      // Start on subdomain step, go to review
      const continueButton = screen.getByRole('button', { name: /continue to review/i });
      await userEvent.click(continueButton);

      await waitFor(() => {
        expect(screen.getByText(/review & continue/i)).toBeInTheDocument();
      });

      // Click continue to dashboard
      const continueToDbButton = screen.getByRole('button', { name: /continue to dashboard/i });
      await userEvent.click(continueToDbButton);

      await waitFor(() => {
        // Should call register/complete API
        expect(global.fetch).toHaveBeenCalledWith(
          '/api/register/complete',
          expect.objectContaining({
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
          })
        );
        // Should NOT call publish API (publishing moved to post-onboarding)
        expect(global.fetch).not.toHaveBeenCalledWith(
          '/api/dealers/dealer123/publish',
          expect.anything()
        );
      });
    });

    test('redirects to dashboard with setup=complete on successful save', async () => {
      (global.fetch as jest.Mock).mockResolvedValueOnce({
        json: async () => ({ success: true }),
      });

      render(
        <OnboardingForm
          {...defaultProps}
          hasSubdomain={true}
          initialData={{ ...filledProfileData, subdomain: 'success' }}
        />
      );

      // Start on subdomain step, go to review
      const continueButton = screen.getByRole('button', { name: /continue to review/i });
      await userEvent.click(continueButton);

      await waitFor(() => {
        expect(screen.getByText(/review & continue/i)).toBeInTheDocument();
      });

      // Click continue to dashboard
      const continueToDbButton = screen.getByRole('button', { name: /continue to dashboard/i });
      await userEvent.click(continueToDbButton);

      await waitFor(() => {
        expect(mockRouterPush).toHaveBeenCalledWith('/dashboard?setup=complete');
      });
    });

    test('handles registration save API errors gracefully', async () => {
      (global.fetch as jest.Mock).mockResolvedValueOnce({
        json: async () => ({
          success: false,
          error: 'Registration save failed',
        }),
      });

      render(
        <OnboardingForm
          {...defaultProps}
          hasSubdomain={true}
          initialData={{ ...filledProfileData, subdomain: 'error' }}
        />
      );

      // Start on subdomain step, go to review
      const continueButton = screen.getByRole('button', { name: /continue to review/i });
      await userEvent.click(continueButton);

      await waitFor(() => {
        expect(screen.getByText(/review & continue/i)).toBeInTheDocument();
      });

      // Click continue to dashboard
      const continueToDbButton = screen.getByRole('button', { name: /continue to dashboard/i });
      await userEvent.click(continueToDbButton);

      await waitFor(() => {
        expect(screen.getByText(/registration save failed/i)).toBeInTheDocument();
      });
    });
  });

  describe('Required Fields Validation', () => {
    // These tests validate profile fields, so we start on profile step (hasSubdomain: false)
    test('phone is required', async () => {
      render(<OnboardingForm {...defaultProps} />);

      // Fill all except phone
      fillField(screen.getByLabelText(/zo account number/i), '123456');
      fillField(screen.getByLabelText(/contact email/i), 'test@example.com');
      fillField(screen.getByLabelText(/street address/i), '123 Main St');
      fillField(screen.getByLabelText(/city/i), 'Springfield');
      fillField(screen.getByLabelText(/state/i), 'IL');
      fillField(screen.getByLabelText(/zip/i), '62701');

      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      expect(continueButton).toBeDisabled();
    });

    test('address is required', async () => {
      render(<OnboardingForm {...defaultProps} />);

      // Fill all except address
      fillField(screen.getByLabelText(/zo account number/i), '123456');
      fillField(screen.getByLabelText(/contact email/i), 'test@example.com');
      fillField(screen.getByLabelText(/phone/i), '555-1234');
      fillField(screen.getByLabelText(/city/i), 'Springfield');
      fillField(screen.getByLabelText(/state/i), 'IL');
      fillField(screen.getByLabelText(/zip/i), '62701');

      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      expect(continueButton).toBeDisabled();
    });

    test('city is required', async () => {
      render(<OnboardingForm {...defaultProps} />);

      // Fill all except city
      fillField(screen.getByLabelText(/zo account number/i), '123456');
      fillField(screen.getByLabelText(/contact email/i), 'test@example.com');
      fillField(screen.getByLabelText(/phone/i), '555-1234');
      fillField(screen.getByLabelText(/street address/i), '123 Main St');
      fillField(screen.getByLabelText(/state/i), 'IL');
      fillField(screen.getByLabelText(/zip/i), '62701');

      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      expect(continueButton).toBeDisabled();
    });

    test('state is required', async () => {
      render(<OnboardingForm {...defaultProps} />);

      // Fill all except state
      fillField(screen.getByLabelText(/zo account number/i), '123456');
      fillField(screen.getByLabelText(/contact email/i), 'test@example.com');
      fillField(screen.getByLabelText(/phone/i), '555-1234');
      fillField(screen.getByLabelText(/street address/i), '123 Main St');
      fillField(screen.getByLabelText(/city/i), 'Springfield');
      fillField(screen.getByLabelText(/zip/i), '62701');

      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      expect(continueButton).toBeDisabled();
    });

    test('ZIP is required', async () => {
      render(<OnboardingForm {...defaultProps} />);

      // Fill all except ZIP
      fillField(screen.getByLabelText(/zo account number/i), '123456');
      fillField(screen.getByLabelText(/contact email/i), 'test@example.com');
      fillField(screen.getByLabelText(/phone/i), '555-1234');
      fillField(screen.getByLabelText(/street address/i), '123 Main St');
      fillField(screen.getByLabelText(/city/i), 'Springfield');
      fillField(screen.getByLabelText(/state/i), 'IL');

      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      expect(continueButton).toBeDisabled();
    });

    test('dealer number is required', async () => {
      render(<OnboardingForm {...defaultProps} />);

      // Fill all except dealer number
      fillField(screen.getByLabelText(/contact email/i), 'test@example.com');
      fillField(screen.getByLabelText(/phone/i), '555-1234');
      fillField(screen.getByLabelText(/street address/i), '123 Main St');
      fillField(screen.getByLabelText(/city/i), 'Springfield');
      fillField(screen.getByLabelText(/state/i), 'IL');
      fillField(screen.getByLabelText(/zip/i), '62701');

      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      expect(continueButton).toBeDisabled();
    });

    test('contact email is required', async () => {
      render(<OnboardingForm {...defaultProps} />);

      // Fill all except email (clear the pre-filled value)
      fillField(screen.getByLabelText(/zo account number/i), '123456');
      fillField(screen.getByLabelText(/contact email/i), '');
      fillField(screen.getByLabelText(/phone/i), '555-1234');
      fillField(screen.getByLabelText(/street address/i), '123 Main St');
      fillField(screen.getByLabelText(/city/i), 'Springfield');
      fillField(screen.getByLabelText(/state/i), 'IL');
      fillField(screen.getByLabelText(/zip/i), '62701');

      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      expect(continueButton).toBeDisabled();
    });

    test('email is pre-filled and editable', async () => {
      render(
        <OnboardingForm
          {...defaultProps}
          initialData={{
            ...defaultProps.initialData,
            email: 'prefilled@example.com',
          }}
        />
      );

      const emailInput = screen.getByDisplayValue('prefilled@example.com') as HTMLInputElement;
      // Email should now be editable (not disabled)
      expect(emailInput).not.toBeDisabled();

      // Test that we can change it
      fillField(emailInput, 'changed@example.com');
      expect(emailInput.value).toBe('changed@example.com');
    });
  });

  describe('Network Failure Handling', () => {
    // Pre-filled profile data for network tests
    const filledProfileData = {
      ...defaultProps.initialData,
      subdomain: 'test',
      dealerNumber: '123456',
      email: 'test@example.com',
      phone: '555-1234',
      address: '123 Main St',
      city: 'Springfield',
      state: 'IL',
      zip: '62701',
    };

    test('shows error message when registration API network fails', async () => {
      (global.fetch as jest.Mock).mockRejectedValueOnce(new Error('Network error'));

      render(
        <OnboardingForm {...defaultProps} hasSubdomain={true} initialData={filledProfileData} />
      );

      // Proceed to review step (start on subdomain step with pre-filled data)
      await userEvent.click(screen.getByRole('button', { name: /continue to review/i }));
      await waitFor(() => {
        expect(screen.getByText(/review & continue/i)).toBeInTheDocument();
      });

      // Trigger final submission
      await userEvent.click(screen.getByRole('button', { name: /continue to dashboard/i }));

      // Should show user-friendly error message
      await waitFor(() => {
        expect(screen.getByText(/failed to complete registration/i)).toBeInTheDocument();
      });

      // Should not redirect
      expect(mockRouterPush).not.toHaveBeenCalled();
    });

    test('shows error message when subdomain check network fails', async () => {
      (global.fetch as jest.Mock).mockRejectedValueOnce(new Error('Network error'));

      // Pre-filled profile to enable navigation
      const filledProps = {
        ...defaultProps,
        initialData: {
          ...defaultProps.initialData,
          dealerNumber: '123456',
          email: 'test@example.com',
          phone: '555-1234',
          address: '123 Main St',
          city: 'Springfield',
          state: 'IL',
          zip: '62701',
        },
      };

      render(<OnboardingForm {...filledProps} />);

      // Navigate to subdomain step
      const continueButton = screen.getByRole('button', { name: /continue to domain/i });
      await userEvent.click(continueButton);

      await waitFor(() => {
        expect(screen.getByPlaceholderText('yourname')).toBeInTheDocument();
      });

      const input = screen.getByPlaceholderText('yourname');
      await userEvent.type(input, 'testname');

      await waitFor(() => {
        expect(screen.getByText(/error checking availability/i)).toBeInTheDocument();
      });
    });
  });
});
