import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { FormProvider, useForm } from 'react-hook-form';
import { ThemeProvider } from '../../../theme';
import RhfTextField from './RhfTextField';

interface Values {
  years: string;
}

function Harness({ onSubmit }: { onSubmit: (values: Values) => void }) {
  const form = useForm<Values>({ mode: 'onTouched', defaultValues: { years: '' } });
  return (
    <FormProvider {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        <RhfTextField<Values>
          name="years"
          label="Years"
          helperText="How long you have practised"
          transform={(raw) => raw.replace(/\D/g, '').slice(0, 2)}
          rules={{ validate: (value) => String(value ?? '').length > 0 || 'Years is required' }}
        />
        <button type="submit">Save</button>
      </form>
    </FormProvider>
  );
}

function renderField() {
  const onSubmit = jest.fn();
  render(
    <ThemeProvider>
      <Harness onSubmit={onSubmit} />
    </ThemeProvider>,
  );
  return { onSubmit };
}

describe('<RhfTextField/> component', () => {
  it('reads its control off the enclosing FormProvider and shows the helper text', () => {
    renderField();
    expect(screen.getByLabelText('Years')).toBeInTheDocument();
    expect(screen.getByText('How long you have practised')).toBeInTheDocument();
  });

  it('normalizes keystrokes through `transform` before they reach form state', async () => {
    const user = userEvent.setup();
    const { onSubmit } = renderField();
    await user.type(screen.getByLabelText('Years'), 'a1b2c3');
    await user.click(screen.getByText('Save'));
    // Non-digits stripped and capped at two — the stored value, not just the displayed one.
    await waitFor(() => expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ years: '12' }), expect.anything()));
  });

  it('replaces the helper text with the field rule message on a failed submit', async () => {
    const user = userEvent.setup();
    const { onSubmit } = renderField();
    await user.click(screen.getByText('Save'));
    expect(await screen.findByText('Years is required')).toBeInTheDocument();
    expect(screen.queryByText('How long you have practised')).not.toBeInTheDocument();
    expect(onSubmit).not.toHaveBeenCalled();
  });
});
