import React from "react";
import classNames from "classnames";
import { ControlledProps, useDefaultValue } from "../form/controlled";
import { SegmentOption } from "./SegmentOption";
import { StyledProps } from "../_type";
import { Button } from "../button";
import { useConfig } from "../_util/config-context";
import { SegmentGroup, SegmentGroupItem } from "./SegmentGroup";
import { forwardRefWithStatics } from "../_util/forward-ref-with-statics";
import { mergeEventProps } from "../_util/merge-event-props";

export interface SegmentMultipleProps
  extends ControlledProps<string[]>,
    StyledProps {
  options?: SegmentOption[];

  /**
   * 分组
   */
  groups?: {
    [groupKey: string]: React.ReactNode;
  };

  /**
   * 是否为无边框样式
   * @default false
   */
  rimless?: boolean;

  /**
   * 包含分组时，外层分组容器自定义类名
   * @since 2.6.11
   */
  groupClassName?: string;

  /**
   * 包含分组时，外层分组容器自定义样式
   * @since 2.6.11
   */
  groupStyle?: React.CSSProperties;
}

export const SegmentMultiple = forwardRefWithStatics(
  function SegmentMultiple(
    props: SegmentMultipleProps,
    ref: React.Ref<HTMLDivElement>
  ) {
    const {
      value,
      onChange,
      groups,
      groupClassName,
      groupStyle,
      options,
    } = useDefaultValue(props);
    const valueSet = new Set<string>(value);
    if (groups) {
      return (
        <SegmentGroup ref={ref} className={groupClassName} style={groupStyle}>
          {Object.entries(groups).map(([key, name]) => {
            const subOptions = options.filter(i => i.groupKey === key);
            return (
              <SegmentGroupItem name={name} key={key}>
                <SegmentMain
                  {...props}
                  valueSet={valueSet}
                  options={subOptions}
                  allOptions={options}
                  value={value}
                  onChange={onChange}
                />
              </SegmentGroupItem>
            );
          })}
        </SegmentGroup>
      );
    }
    return (
      <SegmentMain
        {...props}
        valueSet={valueSet}
        value={value}
        onChange={onChange}
      />
    );
  },
  {
    defaultLabelAlign: "middle",
  }
);

SegmentMultiple.displayName = "SegmentMultiple";

const SegmentMain = React.forwardRef(function SegmentMain(
  {
    onChange,
    rimless,
    options,
    style,
    className,
    // 兼容分组
    valueSet,
    allOptions = options,
    ...props
  }: SegmentMultipleProps & {
    valueSet: Set<string>;
    allOptions?: SegmentMultipleProps["options"];
  },
  ref: React.Ref<HTMLDivElement>
) {
  const { classPrefix } = useConfig();
  return (
    <div
      ref={ref}
      className={classNames(`${classPrefix}-segment`, className, {
        [`${classPrefix}-segment--rimless`]: rimless,
      })}
      style={style}
      {...mergeEventProps(props)}
    >
      {options.map(option => (
        <Button
          key={option.value}
          htmlType="button"
          disabled={option.disabled}
          tooltip={option.tooltip}
          className={classNames(option.className, {
            "is-selected": valueSet.has(option.value),
          })}
          style={option.style}
          onClick={
            option.disabled
              ? null
              : event => {
                  let newValue: string[];

                  // 之前已经选中，新值排除此值
                  if (valueSet.has(option.value)) {
                    newValue = allOptions
                      .filter(x => x !== option && valueSet.has(x.value))
                      .map(x => x.value);
                  }
                  // 之前没有选中，新值包含次值
                  else {
                    newValue = allOptions
                      .filter(x => x === option || valueSet.has(x.value))
                      .map(x => x.value);
                  }
                  onChange(newValue, { event });
                }
          }
        >
          {option.text || option.value}
        </Button>
      ))}
    </div>
  );
});

SegmentMain.displayName = "SegmentMain";
