// @flow
import React from 'react';
import { mountWrappedComponent, currentTheme } from '../../../../utils/tests';

import {
  getBgColor,
  getColor,
  getTabButtonFontSize,
  getAnimation,
} from './tab-set.css-rules';
import type { TabSetProps } from './tab-set.proptypes';
import { TabSet, TabButton } from './tab-set.component';

const DEFAULT_PROPS: TabSetProps = {
  tabs: [
    {
      id: 'plan',
      label: 'Plan',
      content: <div>Plan Content</div>,
    },
    {
      id: 'history',
      label: 'History',
      content: <div>History Content</div>,
    },
  ],
};

describe('TabSet', () => {
  it('renders tabs', () => {
    const tabSet = mountWrappedComponent(<TabSet {...DEFAULT_PROPS} />);

    const buttons = tabSet.find(TabButton);
    buttons.forEach((button, index) => {
      expect(button.props()).toEqual({
        children: DEFAULT_PROPS.tabs[index].label,
        onClick: expect.any(Function),
        role: 'tab',
        insetFocus: true,
        selected: expect.any(Boolean),
        totalTabs: DEFAULT_PROPS.tabs.length,
      });
    });
  });

  it('sets the tab index to match selectedTabIndex when selectedTabIndex has changed', () => {
    const TabSetWithResetButton = () => {
      const [selectedTabIndex, setSelectedTabIndex] = React.useState(1);
      const resetTabIndex = () => setSelectedTabIndex(0);

      return (
        <>
          <TabSet {...{ ...DEFAULT_PROPS, selectedTabIndex }} />
          <button id="reset-btn" type="button" onClick={resetTabIndex}>
            Reset selected tab index
          </button>
        </>
      );
    };

    const component = mountWrappedComponent(<TabSetWithResetButton />);

    expect(component.find(TabButton).at(0).prop('selected')).toBe(false);
    expect(component.find(TabButton).at(1).prop('selected')).toBe(true);

    component.find('button#reset-btn').simulate('click');
    component.update();

    expect(component.find(TabButton).at(0).prop('selected')).toBe(true);
    expect(component.find(TabButton).at(1).prop('selected')).toBe(false);
  });

  describe('tab selection', () => {
    it('is set to thee first tab by default', () => {
      const tabSet = mountWrappedComponent(<TabSet {...DEFAULT_PROPS} />);
      const firstTab = tabSet.find(TabButton).at(0);
      const secondTab = tabSet.find(TabButton).at(1);

      expect(tabSet.contains(DEFAULT_PROPS.tabs[0].content));
      expect(firstTab.prop('selected')).toBe(true);
      expect(secondTab.prop('selected')).toBe(false);
    });

    it('is set by the `selectedTabIndex` prop', () => {
      const tabSet = mountWrappedComponent(
        <TabSet selectedTabIndex={1} {...DEFAULT_PROPS} />,
      );

      const firstTab = tabSet.find(TabButton).at(0);
      const secondTab = tabSet.find(TabButton).at(1);

      expect(tabSet.contains(DEFAULT_PROPS.tabs[1].content));
      expect(firstTab.prop('selected')).toBe(false);
      expect(secondTab.prop('selected')).toBe(true);
    });
  });

  it('calls onSelect with the tab index', () => {
    const onSelect = jest.fn();
    const tabSet = mountWrappedComponent(
      <TabSet selectedTabIndex={1} onSelect={onSelect} {...DEFAULT_PROPS} />,
    );

    const secondTab = tabSet.find(TabButton).at(1);
    secondTab.simulate('click');
    expect(onSelect).toHaveBeenCalledWith(1);
  });

  describe('css-rules', () => {
    describe('getBgColor', () => {
      it('returns different colors based on if it was selected or not', () => {
        const selectedColor = getBgColor({
          theme: currentTheme,
          selected: true,
        });
        const notSelectedColor = getBgColor({
          theme: currentTheme,
          selected: false,
        });

        expect(selectedColor).toBeHexCode();
        expect(notSelectedColor).toBeHexCode();

        expect(selectedColor).not.toBe(notSelectedColor);
      });
    });

    describe('getColor', () => {
      it('returns different colors based on if it was selected or not', () => {
        const selectedColor = getColor({
          theme: currentTheme,
          selected: true,
        });
        const notSelectedColor = getColor({
          theme: currentTheme,
          selected: false,
        });

        expect(selectedColor).toBeHexCode();
        expect(notSelectedColor).toBeHexCode();

        expect(selectedColor).not.toBe(notSelectedColor);
      });
    });

    describe('getTabButtonFontSize', () => {
      it('returns a valid font size', () => {
        const fontSize = getTabButtonFontSize({ theme: currentTheme });

        expect(fontSize).toBeFontSize();
      });
    });

    describe('getAnimation', () => {
      it('returns an empty string if a previous index does not exist', () => {
        const animation = getAnimation({
          selected: true,
          currentIndex: 0,
        });

        expect(animation).toBe('');
      });

      it('returns an empty string if the current index and previous index are the same', () => {
        const animation = getAnimation({
          selected: true,
          currentIndex: 1,
          prevTabIndex: 1,
        });

        expect(animation).toBe('');
      });

      it('returns an empty string if not selected', () => {
        const animation = getAnimation({
          selected: false,
          currentIndex: 1,
          prevTabIndex: 0,
        });

        expect(animation).toBe('');
      });
    });
  });
});
