import React from 'react';
import { render, screen, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom';
import { IntlProvider } from 'react-intl';
import CommunicationStrategyStep from '../CommunicationStrategyStep';
import { getVisibleDropdown } from '../../../../../utils/test-utils';

const STRATEGY_OPTIONS = [
  { value: 'SINGLE_TEMPLATE', label: 'Single template', isMultiChannel: false, disabled: false },
  { value: 'CHANNEL_PRIORITY', label: 'Channel priority', isMultiChannel: true, disabled: false },
];

function renderWithIntl(ui) {
  return render(
    <IntlProvider locale="en" messages={{}} defaultLocale="en">
      {ui}
    </IntlProvider>,
  );
}

async function openStrategySelect() {
  const combo = screen.getByRole('combobox');
  await userEvent.click(combo);
  await waitFor(() => {
    expect(screen.getByRole('listbox')).toBeInTheDocument();
  });
}

describe('CommunicationStrategyStep', () => {
  it('renders heading, placeholder, and strategy dropdown', () => {
    const onChange = jest.fn();
    renderWithIntl(
      <CommunicationStrategyStep
        value={null}
        onChange={onChange}
        options={STRATEGY_OPTIONS}
        disabled={false}
      />,
    );

    expect(screen.getByText(/communication strategy/i)).toBeInTheDocument();
    expect(screen.getByText('Select strategy')).toBeInTheDocument();
    expect(screen.getByRole('combobox')).toBeInTheDocument();
  });

  it('calls onChange with the strategy value when user picks an option', async () => {
    const onChange = jest.fn();
    renderWithIntl(
      <CommunicationStrategyStep
        value={null}
        onChange={onChange}
        options={STRATEGY_OPTIONS}
      />,
    );

    await openStrategySelect();
    await userEvent.click(within(getVisibleDropdown()).getByText('Single template'));

    expect(onChange).toHaveBeenCalledWith('SINGLE_TEMPLATE');
  });

  it('shows the current value in the select when one is chosen', () => {
    const onChange = jest.fn();
    renderWithIntl(
      <CommunicationStrategyStep
        value="CHANNEL_PRIORITY"
        onChange={onChange}
        options={STRATEGY_OPTIONS}
      />,
    );

    expect(screen.getByRole('combobox')).toBeInTheDocument();
    expect(screen.getByText('Channel priority')).toBeInTheDocument();
  });

  it('treats empty string like no selection so placeholder can show', () => {
    const onChange = jest.fn();
    renderWithIntl(
      <CommunicationStrategyStep
        value=""
        onChange={onChange}
        options={STRATEGY_OPTIONS}
      />,
    );

    expect(screen.getByText('Select strategy')).toBeInTheDocument();
  });

  it('annotates each option with single vs multiple channel copy', async () => {
    const onChange = jest.fn();
    renderWithIntl(
      <CommunicationStrategyStep
        value={null}
        onChange={onChange}
        options={STRATEGY_OPTIONS}
      />,
    );

    await openStrategySelect();
    const dropdown = getVisibleDropdown();
    expect(within(dropdown).getByText('Single channel')).toBeInTheDocument();
    expect(within(dropdown).getByText('Multiple channel')).toBeInTheDocument();
  });

  it('disables the select when the step is read-only', () => {
    const onChange = jest.fn();
    renderWithIntl(
      <CommunicationStrategyStep
        value="SINGLE_TEMPLATE"
        onChange={onChange}
        options={STRATEGY_OPTIONS}
        disabled
      />,
    );

    const combo = screen.getByRole('combobox');
    expect(combo.closest('.ant-select')).toHaveClass('ant-select-disabled');
  });

  it('shows validation error under the select', () => {
    const onChange = jest.fn();
    renderWithIntl(
      <CommunicationStrategyStep
        value={null}
        onChange={onChange}
        options={STRATEGY_OPTIONS}
        error="Strategy is required"
      />,
    );

    expect(screen.getByText('Strategy is required')).toBeInTheDocument();
  });
});
