import type { ReactNode, Ref } from "react";
import { Children, cloneElement, isValidElement } from "react";
import classNames from "classnames/dedupe";
import type { DOMProps } from "../../types/dom";
import "./List.css";

export type ListStyleType =
  | "disc"
  | "circle"
  | "square"
  | "decimal"
  | "georgian"
  | "trad-chinese-informal"
  | "kannada";

export interface ListProps extends DOMProps {
  children?: ReactNode;
  isOrdered?: boolean;
  isReversed?: boolean;
  start?: number;
  liststyletype?: ListStyleType;
  icon?: ReactNode;
  className?: string;
  ref?: Ref<HTMLElement>;
}

const List = ({ ref, ...props }: ListProps) => {
  const Component: "ol" | "ul" = props.isOrdered ? "ol" : "ul";
  const { children, icon, ...otherProps } = props;

  // Remove props that should not exist on ol or ul element

  const { isOrdered, liststyletype, isReversed, ...restProps } = otherProps;

  const mappedProps = {
    ...restProps,
    reversed: isReversed,
  };

  const classes = classNames(
    "mobius",
    "mobius-list",
    {
      "--has-icon": icon,
      [`--is-${liststyletype}`]: liststyletype,
    },
    otherProps.className,
  );

  return (
    <Component
      ref={ref as React.Ref<HTMLOListElement & HTMLUListElement>}
      {...mappedProps}
      className={classes}
    >
      {Children.map(children, child => {
        if (isValidElement(child)) {
          // List items accept a parentIcon prop which is not part of standard HTML
          return cloneElement(child, {
            parentIcon: icon,
          } as { parentIcon?: ReactNode });
        }

        return child;
      })}
    </Component>
  );
};

List.displayName = "List";
export { List };
