import { mockMatchMedia, render, screen, within } from '../../test-utils';
import { PrimitivePrompt, PrimitivePromptProps } from './PrimitivePrompt';
import { userEvent } from '@testing-library/user-event';

mockMatchMedia();

describe('PrimitivePrompt', () => {
  const defaultProps: PrimitivePromptProps = {
    media: <span data-testid="test-media">Media</span>,
    children: <div>Test content</div>,
  };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('Basic rendering', () => {
    it('renders children content', () => {
      render(<PrimitivePrompt {...defaultProps} />);
      expect(screen.getByText('Test content')).toBeInTheDocument();
    });

    it('renders media', () => {
      render(<PrimitivePrompt {...defaultProps} />);
      expect(screen.getByTestId('test-media')).toBeInTheDocument();
    });

    it('renders actions when provided', () => {
      render(
        <PrimitivePrompt
          {...defaultProps}
          actions={<button type="button">Action Button</button>}
        />,
      );

      expect(screen.getByText('Action Button')).toBeInTheDocument();
    });

    it('does not render actions wrapper when actions not provided', () => {
      render(<PrimitivePrompt {...defaultProps} data-testid="prompt" />);
      const prompt = screen.getByTestId('prompt');
      expect(within(prompt).queryByRole('button')).not.toBeInTheDocument();
    });
  });

  describe('Sentiments', () => {
    [
      { sentiment: 'negative' as const, label: 'negative' },
      { sentiment: 'warning' as const, label: 'warning' },
      { sentiment: 'neutral' as const, label: 'neutral' },
      { sentiment: 'success' as const, label: 'success' },
    ].forEach(({ sentiment, label }) => {
      it(`applies correct CSS class for ${label} sentiment`, () => {
        render(<PrimitivePrompt {...defaultProps} sentiment={sentiment} data-testid="prompt" />);
        const promptElement = screen.getByTestId('prompt');

        expect(promptElement).toHaveClass(`wds-prompt--${label}`);
      });
    });

    it('defaults to success sentiment', () => {
      render(<PrimitivePrompt {...defaultProps} data-testid="prompt" />);
      expect(screen.getByTestId('prompt')).toHaveClass('wds-prompt--success');
    });

    it('applies base wds-prompt class', () => {
      render(<PrimitivePrompt {...defaultProps} data-testid="prompt" />);
      expect(screen.getByTestId('prompt')).toHaveClass('wds-prompt');
    });
  });

  describe('Dismiss functionality', () => {
    it('renders dismiss button when onDismiss is provided', () => {
      const onDismiss = jest.fn();
      render(<PrimitivePrompt {...defaultProps} onDismiss={onDismiss} />);

      expect(screen.getByLabelText('Close')).toBeInTheDocument();
    });

    it('calls onDismiss when dismiss button is clicked', async () => {
      const onDismiss = jest.fn();
      const user = userEvent.setup();
      render(<PrimitivePrompt {...defaultProps} onDismiss={onDismiss} />);

      const dismissButton = screen.getByLabelText('Close');
      await user.click(dismissButton);

      expect(onDismiss).toHaveBeenCalledTimes(1);
    });

    it('does not render dismiss button when onDismiss is not provided', () => {
      render(<PrimitivePrompt {...defaultProps} />);
      expect(screen.queryByLabelText('Close')).not.toBeInTheDocument();
    });

    it('applies with-dismiss class when onDismiss is provided', () => {
      render(<PrimitivePrompt {...defaultProps} data-testid="prompt" onDismiss={() => {}} />);

      const prompt = screen.getByTestId('prompt');

      expect(screen.getByLabelText('Close')).toBeInTheDocument();
      expect(prompt).toBeInTheDocument();
    });

    it('does not apply with-dismiss class when onDismiss is not provided', () => {
      render(<PrimitivePrompt {...defaultProps} data-testid="prompt" />);

      expect(screen.queryByLabelText('Close')).not.toBeInTheDocument();
    });
  });

  describe('Custom attributes', () => {
    it('applies custom className', () => {
      render(<PrimitivePrompt {...defaultProps} className="custom-class" data-testid="prompt" />);
      expect(screen.getByTestId('prompt')).toHaveClass('custom-class');
    });

    it('applies custom id', () => {
      render(<PrimitivePrompt {...defaultProps} id="custom-id" data-testid="prompt" />);
      expect(screen.getByTestId('prompt')).toHaveAttribute('id', 'custom-id');
    });

    it('applies custom data-testid', () => {
      render(<PrimitivePrompt {...defaultProps} data-testid="custom-test-id" />);
      expect(screen.getByTestId('custom-test-id')).toBeInTheDocument();
    });

    it('combines custom className with base classes', () => {
      render(
        <PrimitivePrompt
          {...defaultProps}
          className="custom-class"
          sentiment="warning"
          data-testid="prompt"
        />,
      );

      const prompt = screen.getByTestId('prompt');

      expect(prompt).toHaveClass('wds-prompt');
      expect(prompt).toHaveClass('wds-prompt--warning');
      expect(prompt).toHaveClass('custom-class');
    });
  });

  describe('SentimentSurface integration', () => {
    it('uses SentimentSurface for sentiment styling', () => {
      render(<PrimitivePrompt {...defaultProps} sentiment="negative" data-testid="prompt" />);
      const prompt = screen.getByTestId('prompt');

      expect(prompt).toHaveClass('wds-sentiment-surface');
    });

    it('passes sentiment to SentimentSurface', () => {
      render(<PrimitivePrompt {...defaultProps} sentiment="warning" data-testid="prompt" />);
      const prompt = screen.getByTestId('prompt');

      expect(prompt).toHaveClass('wds-prompt--warning');
    });
  });
});
