import { Clock } from '@transferwise/icons';
import { mockMatchMedia, render, screen } from '../../test-utils';
import { Sentiment } from '../../common';
import { ListItem } from '../ListItem';
import type { ListItemPromptProps } from './ListItemPrompt';

mockMatchMedia();

describe('ListItem.Prompt', () => {
  it('renders children content', () => {
    render(
      <ListItem
        title="Test Title"
        prompt={<ListItem.Prompt>This is a prompt message</ListItem.Prompt>}
      />,
    );

    expect(screen.getByText('This is a prompt message')).toBeInTheDocument();
  });

  describe('render icon', () => {
    const customLabel = 'Custom icon label';

    it.each([
      [Sentiment.NEUTRAL, 'info-icon'],
      [Sentiment.POSITIVE, 'check-icon'],
      [Sentiment.NEGATIVE, 'cross-icon'],
      [Sentiment.WARNING, 'alert-icon'],
    ] as [ListItemPromptProps['sentiment'], string][])('renders %s icon', (sentiment, iconId) => {
      render(
        <ListItem
          title="Test Title"
          prompt={<ListItem.Prompt sentiment={sentiment}>Message</ListItem.Prompt>}
        />,
      );
      expect(screen.getByTestId(iconId)).toBeInTheDocument();
    });

    it('should accept accessible name override for a status icon', () => {
      render(
        <ListItem
          title="Test Title"
          prompt={
            <ListItem.Prompt sentiment={Sentiment.NEGATIVE} mediaLabel={customLabel}>
              Message
            </ListItem.Prompt>
          }
        />,
      );
      expect(screen.getByLabelText(customLabel)).toBeInTheDocument();
    });

    it('should accept icon accessible name override', () => {
      render(
        <ListItem
          title="Test Title"
          prompt={
            <ListItem.Prompt sentiment={Sentiment.NEGATIVE} media={<Clock title={customLabel} />}>
              Message
            </ListItem.Prompt>
          }
        />,
      );
      expect(screen.getByLabelText(customLabel)).toBeInTheDocument();
    });
  });

  describe('muted state', () => {
    it('does not render backslash-cross icon when parent ListItem is disabled and disabledPromptMessage is not', () => {
      render(
        <ListItem
          title="Test Title"
          disabled
          prompt={<ListItem.Prompt>Message</ListItem.Prompt>}
        />,
      );
      expect(screen.queryByTestId('InlinePrompt_Muted')).not.toBeInTheDocument();
    });

    it('does not renders backslash-cross icon when parent ListItem is not disabled but disabledPromptMessage is set', () => {
      render(
        <ListItem
          title="Test Title"
          disabledPromptMessage="Test reason"
          prompt={<ListItem.Prompt>Message</ListItem.Prompt>}
        />,
      );
      expect(screen.queryByTestId('InlinePrompt_Muted')).not.toBeInTheDocument();
    });

    it('renders backslash-cross icon when parent ListItem is disabled and disabledPromptMessage is provided', () => {
      render(
        <ListItem
          title="Test Title"
          disabled
          disabledPromptMessage="Test reason"
          prompt={<ListItem.Prompt>Message</ListItem.Prompt>}
        />,
      );
      expect(screen.getByTestId('InlinePrompt_Muted')).toBeInTheDocument();
    });
  });

  [
    { sentiment: Sentiment.NEGATIVE as const, mediaLabel: 'Error:' },
    { sentiment: Sentiment.WARNING as const, mediaLabel: 'Warning:' },
    { sentiment: Sentiment.NEUTRAL as const, mediaLabel: 'Information:' },
    { sentiment: Sentiment.POSITIVE as const, mediaLabel: 'Success:' },
    { sentiment: 'proposition' as const, mediaLabel: '' },
  ].forEach(({ sentiment, mediaLabel }) => {
    describe(sentiment, () => {
      const customLabel = 'Custom icon label';

      if (!mediaLabel) {
        it('should not have accessible name for the icon', () => {
          const { container } = render(
            <ListItem
              title="Test Title"
              prompt={<ListItem.Prompt sentiment={sentiment}>Message</ListItem.Prompt>}
            />,
          );
          expect(container.querySelector('svg')).not.toHaveAccessibleName();
        });
      } else {
        it('should use default aria label', () => {
          render(
            <ListItem
              title="Test Title"
              prompt={<ListItem.Prompt sentiment={sentiment}>Message</ListItem.Prompt>}
            />,
          );
          expect(screen.getByLabelText(mediaLabel)).toBeInTheDocument();
        });
      }

      it('should allow for customisation of aria label', () => {
        render(
          <ListItem
            title="Test Title"
            prompt={
              <ListItem.Prompt sentiment={sentiment} mediaLabel={customLabel}>
                Message
              </ListItem.Prompt>
            }
          />,
        );
        expect(screen.getByLabelText(customLabel)).toBeInTheDocument();
      });
    });
  });
});
