import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ThemeProvider } from '../../theme';

jest.mock('next-intl', () => ({ useTranslations: () => (key: string) => key }));

import PatientForm from './PatientForm';

function renderForm(extra: Partial<React.ComponentProps<typeof PatientForm>> = {}) {
  const onSubmit = jest.fn();
  render(
    <ThemeProvider>
      <PatientForm submitLabel="Save" onSubmit={onSubmit} {...extra} />
    </ThemeProvider>,
  );
  return { onSubmit };
}

describe('<PatientForm/> component', () => {
  it('blocks submit and flags gender when it is missing', async () => {
    const user = userEvent.setup();
    const { onSubmit } = renderForm();
    await user.type(screen.getByLabelText('first_name_label'), 'Ali');
    await user.type(screen.getByLabelText('last_name_label'), 'Rezaei');
    await user.type(screen.getByLabelText('age_label'), '40');
    await user.click(screen.getByText('Save'));
    expect(onSubmit).not.toHaveBeenCalled();
    expect(screen.getByText('gender_required')).toBeInTheDocument();
  });

  it('submits the mapped patient input once first/last name, age and gender are set', async () => {
    const user = userEvent.setup();
    const { onSubmit } = renderForm();
    await user.type(screen.getByLabelText('first_name_label'), 'Ali');
    await user.type(screen.getByLabelText('last_name_label'), 'Rezaei');
    await user.type(screen.getByLabelText('age_label'), '40');
    await user.click(screen.getByText('gender_male'));
    await user.click(screen.getByText('Save'));
    expect(onSubmit).toHaveBeenCalledTimes(1);
    expect(onSubmit).toHaveBeenCalledWith(
      expect.objectContaining({
        displayName: 'Ali Rezaei',
        firstName: 'Ali',
        lastName: 'Rezaei',
        gender: 'male',
        relation: null,
        conditions: [],
        birthDate: expect.stringMatching(/^\d{4}-01-01$/),
      }),
    );
  });

  it('falls back the last name to the first name when left blank (the wire requires it)', async () => {
    const user = userEvent.setup();
    const { onSubmit } = renderForm();
    await user.type(screen.getByLabelText('first_name_label'), 'Ali');
    await user.type(screen.getByLabelText('age_label'), '40');
    await user.click(screen.getByText('gender_male'));
    await user.click(screen.getByText('Save'));
    expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ displayName: 'Ali', firstName: 'Ali', lastName: 'Ali' }));
  });

  it('reports dirty state changes via onDirtyChange', async () => {
    const user = userEvent.setup();
    const onDirtyChange = jest.fn();
    renderForm({ onDirtyChange });
    expect(onDirtyChange).toHaveBeenLastCalledWith(false);
    await user.type(screen.getByLabelText('first_name_label'), 'A');
    expect(onDirtyChange).toHaveBeenLastCalledWith(true);
  });
});
