import cx from "classnames";
import React, { HTMLAttributes, ReactNode } from "react";
import { Autocomplete } from "../Autocomplete/Autocomplete";
import { Select } from "../Select/Select";
import { TextInput } from "../TextInput/TextInput";

import { Item } from "./Item";

const CLASS_ROOT = "control-group";

interface ControlShape {
  type: "autocomplete" | "text" | "select";
  [key: string]: any;
}

interface GroupProps extends HTMLAttributes<HTMLDivElement> {
  control: ControlShape;
  addonPrefix?: ReactNode | ReactNode[];
  size?: "large";
  addonSuffix?: ReactNode | ReactNode[];
  className?: string;
  /** Invalid state */
  isInvalid?: boolean;
}

const Group: React.FC<GroupProps> = ({
  control,
  addonPrefix,
  addonSuffix,
  size,
  className,
  isInvalid,
  ...other
}) => {
  const { type, ...controlProps } = control;

  const ControlElement = (props: any) => {
    switch (type) {
      case "autocomplete":
        return <Autocomplete {...props} />;
      case "select":
        return <Select {...props} />;
      default:
        return <TextInput {...props} />;
    }
  };

  const renderItems = (items: ReactNode | ReactNode[] | undefined) =>
    React.Children.map(items, (item) => {
      if (typeof item === "string") {
        return <Item size={size}>{item}</Item>;
      } else if (React.isValidElement(item)) {
        const itemType = (item as any).type;
        const isNativeElement = typeof itemType === "string";
        const isButtonElement =
          isNativeElement && (itemType === "button" || itemType === "a");

        // Wrap native HTML elements (span, p, div) but NOT buttons or links
        // Don't wrap React components (Button, etc.)
        if (isNativeElement && !isButtonElement) {
          return <Item size={size}>{item}</Item>;
        }

        // For buttons, links, and React components, clone with size prop if needed
        const propsToAdd =
          item.props && typeof item.props === "object" && "size" in item.props
            ? {}
            : { size };
        return React.cloneElement(item, propsToAdd);
      }
      return item;
    });

  return (
    <div className={cx(CLASS_ROOT, className)} {...other}>
      {renderItems(addonPrefix)}
      <ControlElement {...controlProps} size={size} />
      {renderItems(addonSuffix)}
    </div>
  );
};

Group.displayName = "ControlGroup";

export { Group };
