import { render } from '@testing-library/react';
import React from 'react';
import { act } from 'react-dom/test-utils';
import { describe, expect, it, vi } from 'vitest';
import { DynamicListColumn } from '../../DynamicDataList/DynamicDataList.model';
import { DynamicDataListControl } from './DynamicDataListControl';

const setFieldTouchedSpy = vi.fn();
const setFieldValueSpy = vi.fn();

vi.mock('formik', () => ({
  useFormikContext: () => ({
    error: undefined,
    setFieldTouched: setFieldTouchedSpy,
    setFieldValue: setFieldValueSpy,
  }),
}));

interface DynamicListTestData {
  id: number;
  title: string;
  position?: number;
}

const defaultData: DynamicListTestData[] = [
  {
    id: 1,
    title: 'fses',
    position: 1,
  },
];

const defaultColumns: DynamicListColumn<DynamicListTestData>[] = [
  {
    propertyName: 'id',
    label: 'Id',
  },
  {
    propertyName: 'title',
    label: 'Title',
  },
];

const defaultProps = {
  name: 'storyData',
  value: defaultData,
  columns: defaultColumns,
  onChange: () => null,
};

describe('DynamicDataListControl', () => {
  it('renders the component without crashing', () => {
    const { container } = render(<DynamicDataListControl {...defaultProps} />);

    expect(container).toBeTruthy();
  });

  it(`renders a label using the 'label' prop`, () => {
    const mockLabel = 'test-label';
    const { container } = render(
      <DynamicDataListControl {...defaultProps} label={mockLabel} />,
    );

    const label = container.querySelector('label');

    expect(label?.textContent).toBe(mockLabel);
  });

  it(`renders an empty string if the 'label' prop is not set`, () => {
    const { container } = render(<DynamicDataListControl {...defaultProps} />);

    const label = container.querySelector('label');

    expect(label?.textContent).toBe('');
  });

  it(`renders the 'DynamicDataList' component`, () => {
    const { container } = render(<DynamicDataListControl {...defaultProps} />);

    const ddl = container.querySelector('[data-test-id="dynamic-data-list"]');

    expect(ddl).toBeInTheDocument();
  });

  it(`emits 'onChange'`, () => {
    const onChangeSpy = vi.fn();
    const mockList = [{ prop: 1 }];

    render(<DynamicDataListControl {...defaultProps} onChange={onChangeSpy} />);

    act(() => {
      onChangeSpy(mockList);
    });

    expect(onChangeSpy).toHaveBeenCalledTimes(1);
    expect(onChangeSpy).toHaveBeenCalledWith(mockList);
  });
});
