import type { CSSInterpolation } from '../../_util/cssinjs';

import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
import { alignItemsValues, flexWrapValues, justifyContentValues } from '../utils';

/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
  // Component token here
}

export interface FlexToken extends FullToken<'Flex'> {
  /**
   * @nameZH 小间隙
   * @nameEN Small Gap
   * @desc 控制元素的小间隙。
   * @descEN Control the small gap of the element.
   */
  flexGapSM: number;
  /**
   * @nameZH 间隙
   * @nameEN Gap
   * @desc 控制元素的间隙。
   * @descEN Control the gap of the element.
   */
  flexGap: number;
  /**
   * @nameZH 大间隙
   * @nameEN Large Gap
   * @desc 控制元素的大间隙。
   * @descEN Control the large gap of the element.
   */
  flexGapLG: number;
}

const genFlexStyle: GenerateStyle<FlexToken> = token => {
  const { componentCls } = token;
  return {
    [componentCls]: {
      display: 'flex',
      '&-vertical': {
        flexDirection: 'column',
      },
      '&-rtl': {
        direction: 'rtl',
      },
      '&:empty': {
        display: 'none',
      },
    },
  };
};

const genFlexGapStyle: GenerateStyle<FlexToken> = token => {
  const { componentCls } = token;
  return {
    [componentCls]: {
      '&-gap-small': {
        gap: token.flexGapSM,
      },
      '&-gap-middle': {
        gap: token.flexGap,
      },
      '&-gap-large': {
        gap: token.flexGapLG,
      },
    },
  };
};

const genFlexWrapStyle: GenerateStyle<FlexToken> = token => {
  const { componentCls } = token;
  const wrapStyle: CSSInterpolation = {};
  flexWrapValues.forEach(value => {
    wrapStyle[`${componentCls}-wrap-${value}`] = { flexWrap: value };
  });
  return wrapStyle;
};

const genAlignItemsStyle: GenerateStyle<FlexToken> = token => {
  const { componentCls } = token;
  const alignStyle: CSSInterpolation = {};
  alignItemsValues.forEach(value => {
    alignStyle[`${componentCls}-align-${value}`] = { alignItems: value };
  });
  return alignStyle;
};

const genJustifyContentStyle: GenerateStyle<FlexToken> = token => {
  const { componentCls } = token;
  const justifyStyle: CSSInterpolation = {};
  justifyContentValues.forEach(value => {
    justifyStyle[`${componentCls}-justify-${value}`] = { justifyContent: value };
  });
  return justifyStyle;
};

export default genComponentStyleHook<'Flex'>('Flex', token => {
  const flexToken = mergeToken<FlexToken>(token, {
    flexGapSM: token.paddingXS,
    flexGap: token.padding,
    flexGapLG: token.paddingLG,
  });
  return [
    genFlexStyle(flexToken),
    genFlexGapStyle(flexToken),
    genFlexWrapStyle(flexToken),
    genAlignItemsStyle(flexToken),
    genJustifyContentStyle(flexToken),
  ];
});