import { CSSProperties, css } from 'glamor';
import { observer } from 'mobx-react';
import { Button } from './Button';
import {
  BoxSizeStyles,
  ButtonStyleVariant
} from '../styles/defaults/themes.interface';
import { TabViewModel } from '../app/tabs/TabViewModel';
import { useApphouse } from '../context/useApphouse';
import { ApphouseComponent } from './component.interfaces';
import { useLocalStyles } from '../styles/defaults/useLocalStyles';
import { getGutterStyles } from '../styles/getGutterStyles';
import React from 'react';
import { View } from './View';

/**
 * Interface for styles to be applied to the tab view component
 */
export interface TabViewStyles {
  container?: CSSProperties;
  tabsContainer?: CSSProperties;
  tabButton?: CSSProperties;
  tabContent?: CSSProperties;
}
/**
 * Interface for the TabView component
 */
export interface TabViewProps extends ApphouseComponent<TabViewStyles> {
  /**
   * The tab view Model
   * @example new TabView()
   */
  tabView: TabViewModel;
  /**
   * The content of the tab view.
   * @optional the tab will render the content of the tab view by default,
   * this will be rendered in addition to the content provided by the tab
   */
  children?: React.ReactNode;
  /**
   * The variant for the styles to be applied on the tab button
   * @default "clear"
   */
  variant?: keyof ButtonStyleVariant;
  /**
   * The variant for the styles to be applied on the tab button when the tab is selected
   * @default "tab"
   */
  variantSelected?: keyof ButtonStyleVariant;
  /**
   * The size for the tab buttons
   * @default "m"
   */
  size?: keyof BoxSizeStyles;
}

/**
 * A tab view component.
 * It displays content in tabs.
 * The tabs are displayed based on a TabViewModel passed in the props.
 */
export const TabView: React.FC<TabViewProps> = observer((props) => {
  const {
    tabView,
    children,
    styleOverwrites,
    variant = 'clear',
    variantSelected = 'tab',
    size = 'm',
    gutters
  } = props;
  const { theme } = useApphouse();
  const { styles, colors } = theme;
  const { tabs, content } = tabView;

  const componentStyles: TabViewStyles = {
    container: {
      ...styles.layout?.vertical,
      gridGap: 0,
      ...getGutterStyles(gutters)
    },
    tabsContainer: {
      ...styles.layout?.horizontal,
      justifyContent: 'flex-start',
      width: '100%',
      gridGap: 0,
      borderBottom: `1px solid ${colors.onPrimary_10}`
    },
    tabButton: {
      border: 0
    }
  };

  const localStyles: TabViewStyles = useLocalStyles(
    componentStyles,
    styleOverwrites
  );

  return (
    <div
      {...css(localStyles.container)}
      data-xray="TabView"
      data-style="TabViewStyles.container"
    >
      <div
        {...css(localStyles.tabsContainer)}
        data-style="TabViewStyles.tabsContainer"
      >
        {tabs?.map((option) => {
          const isSelected = option.id === tabView.selectedId;
          return (
            <Button
              variant={isSelected ? variantSelected : variant}
              size={size}
              key={`${option.id}-tab-${option.label}`}
              styleOverwrites={localStyles.tabButton}
              data-style="TabViewStyles.tabButton"
              onClick={() => {
                option.action && option.action();
                // use default action if not defined
                // which is to just select the tab
                if (!option.action) {
                  tabView.onSelected(option.id);
                }
              }}
            >
              {option.label}
            </Button>
          );
        })}
      </div>

      <View
        orientation="vertical"
        styleOverwrites={localStyles.tabContent}
        data-style="TabView.tabContent"
      >
        {content && content}
        {children && children}
      </View>
    </div>
  );
});
