import { css } from "@emotion/react";
import type { ReactNode } from "react";
import { useCallback } from "react";
import {
  ToggleButton as AriaToggleButton,
  type ToggleButtonProps as AriaToggleButtonProps,
  type ToggleButtonRenderProps,
} from "react-aria-components";

import type { ButtonProps } from "@phoenix/components/core/button";
import { buttonCSS } from "@phoenix/components/core/button";
import { useSize } from "@phoenix/components/core/contexts/SizeContext";
import type { StylableProps } from "@phoenix/components/core/types";
import { classNames } from "@phoenix/utils/classNames";

const baseToggleButtonCSS = css(
  buttonCSS,
  `
    text-wrap: nowrap;
    &[data-selected="true"] {
      background-color: var(--global-button-primary-background-color);
      --button-border-color: var(--global-button-primary-border-color);
      color: var(--global-button-primary-foreground-color);
      &:hover:not([data-disabled]) {
        background-color: var(--global-button-primary-background-color-hover);
      }
    }
    &[data-hovered]:not([data-disabled]):not([data-selected="true"]) {
      background-color: var(--global-input-field-border-color-hover);
    }
    &[data-focus-visible] {
      outline: var(--focus-ring-thickness) solid var(--focus-ring-color);
      outline-offset: calc(-1 * var(--focus-ring-thickness));
    }
    &[data-selected="true"][data-focus-visible] {
      outline-color: var(--global-button-primary-foreground-color);
    }
`
);

export interface ToggleButtonProps
  extends
    AriaToggleButtonProps,
    // Inherit the leading and trailing visuals. Might warrent moving to an interface
    Pick<ButtonProps, "leadingVisual" | "trailingVisual" | "size"> {}

export const ToggleButton = ({
  className,
  css: cssProp,
  ...props
}: ToggleButtonProps & StylableProps) => {
  const {
    leadingVisual,
    trailingVisual,
    size: propSize,
    children,
    ...rest
  } = props;
  // If the toggle button is nested under a button group, use the size of the button group
  const contextSize = useSize();
  const size = propSize ?? contextSize;
  const renderContent = useCallback(
    (props: ToggleButtonRenderProps & { defaultChildren: ReactNode }) => {
      return (
        <>
          {leadingVisual}
          {typeof children === "function" ? children(props) : children}
          {trailingVisual}
        </>
      );
    },
    [leadingVisual, trailingVisual, children]
  );
  return (
    <AriaToggleButton
      css={css(baseToggleButtonCSS, cssProp)}
      data-size={size}
      data-childless={!children}
      className={classNames("toggle-button", className)}
      {...rest}
    >
      {renderContent}
    </AriaToggleButton>
  );
};
