import React from 'react';

import { fireEvent } from '@testing-library/react-native';

import { render } from '@/components/testUtils';
import Button, { ButtonProps } from '@/components/shared/Button';

const renderComponent = ({
  status,
  onPress,
  secondary,
  icon,
  iconLocation,
  label,
  color,
  labelColor
}: ButtonProps = {}) => {
  const base = render(
    <Button
      label={label || "Press me"}
      status={status}
      onPress={onPress}
      secondary={secondary}
      icon={icon}
      iconLocation={iconLocation}
      color={color}
      labelColor={labelColor}
    />
  );

  return base;
};

describe('[Component] Button', () => {
  describe('Ready state', () => {
    test('renders correctly', () => {
      const button = renderComponent();

      expect(button).toMatchSnapshot();
    });

    it('executes an action when pressing it', () => {
      const action = jest.fn();
      const button = renderComponent({ onPress: action });

      fireEvent.press(button.getByText('Press me'));
      expect(action).toHaveBeenCalledWith();
    });
  });

  describe('Disabled state', () => {
    test('renders correctly', () => {
      const button = renderComponent({ status: 'disabled' });

      expect(button).toMatchSnapshot();
    });

    test('does not do anything when pressing it', () => {
      const action = jest.fn();
      const button = renderComponent({ status: 'disabled', onPress: action });

      fireEvent.press(button.getByText('Press me'));
      expect(action).not.toHaveBeenCalled();
    });
  });

  describe('Loading state', () => {
    test('renders correctly', () => {
      const button = renderComponent({ status: 'loading' });

      expect(button).toMatchSnapshot();
    });

    test('does not do anything when pressing it', () => {
      const action = jest.fn();
      const button = renderComponent({ status: 'loading', onPress: action });

      fireEvent.press(button.getByText('Press me'));
      expect(action).not.toHaveBeenCalled();
    });
  });

  describe('Secondary button', () => {
    test('renders correctly', () => {
      const button = renderComponent({ secondary: true });

      expect(button).toMatchSnapshot();
    });

    test('with different colors', () => {
      const button = renderComponent({
        secondary: true,
        color: 'green'
      });

      expect(button).toMatchSnapshot();
    });
  });

  describe('Icon rendering', () => {
    const mockIcon = <div data-testid="mock-icon" />;

    test('renders with icon on the right', () => {
      const button = renderComponent({
        icon: mockIcon,
        iconLocation: 'right'
      });

      expect(button).toMatchSnapshot();
    });

    test('renders with icon on the left', () => {
      const button = renderComponent({
        icon: mockIcon,
        iconLocation: 'left'
      });

      expect(button).toMatchSnapshot();
    });

    test('renders icon only without label', () => {
      const button = renderComponent({
        icon: mockIcon,
        label: undefined
      });

      expect(button).toMatchSnapshot();
    });
  });

  describe('Color variations', () => {
    test('renders with different colors', () => {
      const greenButton = renderComponent({ color: 'green', labelColor: 'white' });
      const redButton = renderComponent({ color: 'red', labelColor: 'white' });
      const greyButton = renderComponent({ color: 'grey' });

      expect(greenButton).toMatchSnapshot();
      expect(redButton).toMatchSnapshot();
      expect(greyButton).toMatchSnapshot();
    });
  });
});
