import React, { useState, useEffect } from "react";
import styles from "./index.module.scss";
import BubbleItem from "./BubbleItem";

export interface BubbleOption {
  id: string | number;
  label: string;
  value: string | number;
  disabled?: boolean;
  icon?: React.ReactNode;
  description?: string;
}

export interface BubbleProps {
  options: BubbleOption[];
  value?: string | number | (string | number)[];
  onChange?: (
    value: string | number | (string | number)[],
    option: BubbleOption | BubbleOption[]
  ) => void;
  multiple?: boolean;
  layout?: "horizontal" | "vertical" | "grid";
  columns?: number;
  size?: "small" | "medium" | "large";
  className?: string;
  itemClassName?: string;
  style?: React.CSSProperties;
  disabled?: boolean;
}

const Bubble: React.FC<BubbleProps> = ({
  options,
  value,
  onChange,
  multiple = false,
  layout = "horizontal",
  columns = 3,
  size = "small",
  className = "",
  itemClassName = "",
  style = {},
  disabled = false,
}) => {
  const [selectedValues, setSelectedValues] = useState<(string | number)[]>([]);

  // 同步外部传入的value
  useEffect(() => {
    if (value !== undefined) {
      const newValues = Array.isArray(value) ? value : [value];
      setSelectedValues(newValues);
    }
  }, [value]);

  const handleOptionClick = (option: BubbleOption) => {
    if (disabled || option.disabled) return;

    let newSelectedValues: (string | number)[];

    if (multiple) {
      if (selectedValues.includes(option.value)) {
        newSelectedValues = selectedValues.filter((v) => v !== option.value);
      } else {
        newSelectedValues = [...selectedValues, option.value];
      }
    } else {
      newSelectedValues = [option.value];
    }

    setSelectedValues(newSelectedValues);

    // 调用onChange回调，传递选中的值和对应的选项
    if (onChange) {
      if (multiple) {
        const selectedOptions = options.filter((opt) =>
          newSelectedValues.includes(opt.value)
        );
        onChange(newSelectedValues, selectedOptions);
      } else {
        onChange(option.value, option);
      }
    }
  };

  const isSelected = (option: BubbleOption) => {
    return selectedValues.includes(option.value);
  };

  const renderHorizontalLayout = () => (
    <div className={styles.bubbleHorizontal}>
      {options.map((option) => (
        <BubbleItem
          key={option.id}
          option={option}
          isSelected={isSelected(option)}
          size={size}
          disabled={disabled}
          onClick={handleOptionClick}
          itemClassName={itemClassName}
        />
      ))}
    </div>
  );

  const renderVerticalLayout = () => (
    <div className={styles.bubbleVertical}>
      {options.map((option) => (
        <BubbleItem
          key={option.id}
          option={option}
          isSelected={isSelected(option)}
          size={size}
          disabled={disabled}
          onClick={handleOptionClick}
          itemClassName={itemClassName}
        />
      ))}
    </div>
  );

  const renderGridLayout = () => (
    <div
      className={styles.bubbleGrid}
      style={{
        gridTemplateColumns: `repeat(${columns}, 1fr)`,
        gap: size === "small" ? "6px" : size === "large" ? "16px" : "12px",
      }}
    >
      {options.map((option) => (
        <BubbleItem
          key={option.id}
          option={option}
          isSelected={isSelected(option)}
          size={size}
          disabled={disabled}
          onClick={handleOptionClick}
          itemClassName={itemClassName || styles.bubbleOption}
        />
      ))}
    </div>
  );

  const renderLayout = () => {
    switch (layout) {
      case "horizontal":
        return renderHorizontalLayout();
      case "vertical":
        return renderVerticalLayout();
      case "grid":
        return renderGridLayout();
      default:
        return renderHorizontalLayout();
    }
  };

  return (
    <div className={`${styles.bubbleContainer} ${className}`} style={style}>
      {renderLayout()}
    </div>
  );
};

export default Bubble;
