import React, { ComponentRef, forwardRef } from "react"
import { IconComponent, IconProps } from "../../icons"
import { classNames } from "../../utils/classNames"
import { CenterAligned } from "../CenterAligned"

const DEFAULT_SIZE = 22
const DEFAULT_MARGIN = 11
const MARGIN_FACTOR = DEFAULT_MARGIN / DEFAULT_SIZE
const OUTLINED_ADDITIONAL_MARGIN = 8

export type IconCalloutIconProps = {
  icon: IconComponent
}

export type IconCalloutCustomProps = {
  children: React.ReactNode
}

export type IconCalloutProps = (
  | IconCalloutIconProps
  | IconCalloutCustomProps
) & {
  size?: number
  className?: string
  variant?: "default" | "solid" | "outlined"
} & Omit<IconProps, "size" | "className">

export const IconCallout = forwardRef<
  ComponentRef<typeof CenterAligned>,
  IconCalloutProps
>(function IconCallout(
  { size = DEFAULT_SIZE, className, style, variant = "default", ...rest },
  ref,
) {
  const styleSize = `calc(${size}px + ${size * MARGIN_FACTOR}px)`

  const IconComponent = "icon" in rest ? rest.icon : undefined
  const iconProps = { ...rest, icon: undefined }

  if (variant === "outlined") {
    const outlinedStyleSize = `calc(${size}px + ${size * MARGIN_FACTOR}px + ${OUTLINED_ADDITIONAL_MARGIN}px)`
    return (
      <CenterAligned
        className={classNames(
          "rounded-md border border-border-1 bg-bg-primary p-1",
          className,
        )}
        ref={ref}
        style={{
          width: outlinedStyleSize,
          height: outlinedStyleSize,
          ...style,
        }}
      >
        <CenterAligned
          className={classNames(
            "aspect-square shrink-0 rounded-xs border border-border-1 bg-bg-additional-1",
            className,
          )}
          style={{
            width: styleSize,
            height: styleSize,
            ...style,
          }}
        >
          {IconComponent ? (
            <IconComponent size={size} {...iconProps} />
          ) : (
            rest.children
          )}
        </CenterAligned>
      </CenterAligned>
    )
  }

  return (
    <CenterAligned
      className={classNames(
        "aspect-square rounded-md bg-bg-additional-1 p-1",
        variant === "default" && "border border-border-1",
        className,
      )}
      ref={ref}
      style={{
        width: styleSize,
        height: styleSize,
        ...style,
      }}
    >
      {IconComponent ? (
        <IconComponent size={size} {...iconProps} />
      ) : (
        rest.children
      )}
    </CenterAligned>
  )
})
