import React from 'react';
import { CSSProperties, css } from 'glamor';
import { observer } from 'mobx-react';
import { useApphouse } from '../../context/useApphouse';
import { BsChevronRight, BsChevronDown } from 'react-icons/bs';
import { Text } from '../Text';
import { ApphouseComponent } from '../component.interfaces';
import { TextStyles } from '../Text';
import { setAlpha } from '../../utils/color/setAlpha';
import { BoxSizeStyles } from '../../styles/defaults/themes.interface';
import { merge } from '../../utils/obj/merge';

/**
 * Interface for styles to be applied to the panel component
 */
export interface PanelStyles {
  container?: CSSProperties;
  content?: CSSProperties;
  title?: TextStyles;
  titlePanel?: CSSProperties;
  titleWrapper?: CSSProperties;
}

/**
 * Interface for the Panel component
 */
export interface PanelProps extends ApphouseComponent<PanelStyles> {
  /**
   * Controls whether the panel is expanded or collapsed externally
   * If not provided, the panel will be controlled internally
   * @optional
   * @default false
   */
  expanded?: boolean;
  /**
   * A callback function that is called when the panel is expanded
   * @returns void
   */
  onExpand?: (expanded: boolean) => void;
  /**
   * The title of the panel
   */
  title: React.ReactNode | JSX.Element;
  /**
   * If provided, the panel will have a max height and will be scrollable
   * @optional
   * @default auto
   */
  maxContentHeight?: number;
  /**
   * If provided, the panel will have a min height when the panel is collapsed
   * @optional
   * @default auto
   */
  minContentHeight?: number;
  /**
   * The content of the panel
   */
  children?: any;
  /**
   * A complementary component to be displayed on the right side of the title
   * @optional
   * @default null
   */
  complementaryComponent?: React.ReactNode | JSX.Element;
  /**
   * If true, the icon will on the left hidden
   * @optional
   * @default false - the icon will be displayed on the left
   */
  hideIcon?: boolean;
  /**
   * The overall size of the Panel
   * @default 'm'
   */
  size?: keyof BoxSizeStyles;
  /**
   * If true, the panel will have no border
   */
  borderless?: boolean;
}
/**
 * A minimalistic panel component that can be used to display content
 * in a panel that can be expanded and collapsed
 */
export const Panel = observer((props: PanelProps) => {
  const {
    children,
    expanded = false,
    title,
    maxContentHeight = 'auto',
    minContentHeight = 'auto',
    onExpand,
    styleOverwrites,
    complementaryComponent,
    size = 'm',
    hideIcon = false,
    borderless = false
  } = props;

  const store = useApphouse();
  const { colors, styles, tokens } = store.theme;

  const componentStyles: PanelStyles = {
    container: {
      width: '100%',
      display: 'contents',
      flexDirection: 'column',
      position: 'relative',
      overflowY: 'scroll',
      transition: 'all 0.3s ease-in-out'
    },
    titlePanel: {
      alignItems: 'center',
      border: borderless ? 0 : `1px solid ${setAlpha(colors.onPrimary, 0.1)}`,
      color: 'inherit',
      cursor: 'pointer',
      display: 'flex',
      userSelect: 'none',
      width: '100%',
      justifyContent: 'space-between'
    },
    titleWrapper: {
      display: 'flex',
      color: 'inherit',
      alignItems: 'center',
      justifyContent: 'flex-start',
      width: '100%',
      boxSizing: 'border-box'
    },
    content: {
      width: '100%',
      position: 'relative',
      minHeight: `${minContentHeight}px`,
      maxHeight: expanded ? `${maxContentHeight}px` : 0,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'flex-start',
      justifyContent: 'flex-start',
      color: 'inherit',
      fontSize: 'inherit',
      fontFamily: 'inherit',
      transition: 'all 0.3s ease-in-out'
    },
    title: {
      fontWeight: 800,
      transition: 'all 0.3s ease-in-out',
      ':hover': {
        color: colors.brand
      }
    }
  };
  const boxSizeStyles = styles.boxSize[size];

  const sizeStyles: PanelStyles = {
    content: boxSizeStyles,
    title: boxSizeStyles
  };
  const localStyles = merge({}, componentStyles, sizeStyles, styleOverwrites);

  return (
    <div
      {...css(localStyles.container)}
      data-xray="Panel"
      data-style="Panel.container"
    >
      <div
        {...css(localStyles.titlePanel)}
        data-style="Panel.titlePanel"
        onClick={() => {
          const value = !expanded;
          onExpand && onExpand(value);
        }}
      >
        <div {...css(localStyles?.titleWrapper)} data-style="Panel.iconWrapper">
          {expanded && !hideIcon && (
            <span {...css(boxSizeStyles)}>
              <BsChevronDown size={tokens.iconSize[size]} />
            </span>
          )}
          {!expanded && !hideIcon && (
            <span {...css(boxSizeStyles)}>
              <BsChevronRight size={tokens.iconSize[size]} />
            </span>
          )}
          <Text styleOverwrites={localStyles.title}>{title}</Text>
        </div>

        {complementaryComponent && complementaryComponent}
      </div>
      {expanded && (
        <div {...css(localStyles.content)} data-style="Panel.content">
          {children}
        </div>
      )}
    </div>
  );
});
