import React, { Children, ReactChild, ReactElement, Ref, useCallback, useEffect, useState } from 'react';
import { bem } from 'utils/bem';
import { STabs } from '../../s-components/tabs/s-tabs';
import { SSpacer } from '../../s-components/layout/s-spacer';
import { TabProps } from './tab';
import { Tooltip } from '../tooltip';
import { DatePicker, DatePickerMode } from '../form/date-picker';
import { OptionalPeriod } from 'common/types';
import { BgStyle } from 'common/styles/utils';

interface Props<T extends string> {
  onChange(tabUrl: T): void;

  activeTab?: T;
  showPeriod?: boolean;
  periodValue?: OptionalPeriod;

  onPeriodChange?(period: OptionalPeriod): void;

  children: ReactElement<TabProps<T>>[];
  title?: ReactChild;
  shouldHideTabs?: boolean;
  shouldHideDivider?: boolean;
  className?: string;
  datePickerStyle?: BgStyle;
  tabContainerElement?: React.ReactChild;
  innerRef?: Ref<HTMLDivElement>;
}

const classes = bem('tabs');

export const Tabs = <T extends string>({
  onChange,
  activeTab,
  showPeriod,
  periodValue,
  onPeriodChange,
  children,
  className,
  title,
  shouldHideTabs,
  shouldHideDivider,
  datePickerStyle = 'grey',
  innerRef,
  tabContainerElement,
}: Props<T>) => {
  const [tab, setTab] = useState(activeTab);

  useEffect(() => {
    setTab(activeTab);
  }, [activeTab]);

  const onTabClick = useCallback(
    (tabTitle: T, disabled?: boolean) => {
      if (disabled) return;
      setTab(tabTitle);
      onChange(tabTitle);
    },
    [onChange]
  );

  return (
    <STabs ref={innerRef} className={className}>
      <div className={classes('header')}>
        <div className={classes('top-container')}>
          {title && (
            <>
              <div className={classes('widget-title')}>{title}</div>
              <SSpacer />
            </>
          )}
          {!shouldHideTabs && (
            <div className={classes('titles-container')}>
              {Children.map(children, element => {
                if (!element) return null;
                const { title, badge, tooltipContent, disabled, dataSelector } = element.props;
                const isActive = title === tab;
                return (
                  <Tooltip content={tooltipContent} enabled={!!tooltipContent} appendTo={document.body}>
                    <div
                      onClick={() => onTabClick(title, disabled)}
                      className={classes('tab-title', { active: isActive, disabled: !!disabled })}
                      data-selector={dataSelector}
                    >
                      {title}
                      {typeof badge === 'number' ? ` (${badge})` : ''}
                      <div className={classes('tab-highlight', { active: isActive })} />
                    </div>
                  </Tooltip>
                );
              })}
            </div>
          )}
          {showPeriod && onPeriodChange && (
            <>
              <SSpacer />
              <div className={classes('period-container')}>
                <span className={classes('period-label')}>Period</span>
                <div className={classes('period-picker')}>
                  <DatePicker
                    value={periodValue}
                    mode={DatePickerMode.RANGE}
                    onChange={onPeriodChange}
                    bgStyle={datePickerStyle}
                  />
                </div>
              </div>
            </>
          )}
          {tabContainerElement}
        </div>
        {!shouldHideDivider && !shouldHideTabs && <div className={classes('tabs-divider')} />}
      </div>
      {Children.map(children, element => {
        if (!element) return null;
        const { title } = element.props;
        if (tab !== title) return null;

        return React.cloneElement(element);
      })}
    </STabs>
  );
};
