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 RhfChipSelect from './RhfChipSelect';

const OPTIONS = [
  { code: 'icu', label: 'ICU' },
  { code: 'elderly', label: 'Elderly' },
];

interface MultiValues {
  specialties: string[];
}
interface SingleValues {
  relation: string | null;
}

function MultiHarness({ onSubmit, initial = [] }: { onSubmit: (values: MultiValues) => void; initial?: string[] }) {
  const form = useForm<MultiValues>({ defaultValues: { specialties: initial } });
  return (
    <FormProvider {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        <RhfChipSelect<MultiValues> name="specialties" label="Specialties" options={OPTIONS} allowCustomValues />
        <button type="submit">Save</button>
      </form>
    </FormProvider>
  );
}

function SingleHarness({ onSubmit }: { onSubmit: (values: SingleValues) => void }) {
  const form = useForm<SingleValues>({ defaultValues: { relation: null } });
  return (
    <FormProvider {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        <RhfChipSelect<SingleValues> name="relation" options={OPTIONS} multiple={false} />
        <button type="submit">Save</button>
      </form>
    </FormProvider>
  );
}

describe('<RhfChipSelect/> component', () => {
  it('toggles codes in and out of a multi-select field', async () => {
    const user = userEvent.setup();
    const onSubmit = jest.fn();
    render(
      <ThemeProvider>
        <MultiHarness onSubmit={onSubmit} />
      </ThemeProvider>,
    );
    await user.click(screen.getByText('ICU'));
    await user.click(screen.getByText('Elderly'));
    await user.click(screen.getByText('ICU'));
    await user.click(screen.getByText('Save'));
    await waitFor(() => expect(onSubmit).toHaveBeenCalledWith({ specialties: ['elderly'] }, expect.anything()));
  });

  it('behaves like a radio group when single-select, clearing on a re-tap', async () => {
    const user = userEvent.setup();
    const onSubmit = jest.fn();
    render(
      <ThemeProvider>
        <SingleHarness onSubmit={onSubmit} />
      </ThemeProvider>,
    );
    await user.click(screen.getByText('ICU'));
    await user.click(screen.getByText('Elderly'));
    await user.click(screen.getByText('Save'));
    await waitFor(() => expect(onSubmit).toHaveBeenCalledWith({ relation: 'elderly' }, expect.anything()));

    await user.click(screen.getByText('Elderly'));
    await user.click(screen.getByText('Save'));
    await waitFor(() => expect(onSubmit).toHaveBeenLastCalledWith({ relation: null }, expect.anything()));
  });

  it('renders a stored value that is not in the option list, so it can never silently vanish', () => {
    render(
      <ThemeProvider>
        <MultiHarness onSubmit={jest.fn()} initial={['wound care']} />
      </ThemeProvider>,
    );
    expect(screen.getByText('wound care')).toBeInTheDocument();
  });
});
