import React, { PropsWithChildren } from "react";
import {
  IconAnimationType,
  Icon,
  IconSize,
  IconAnimationOptions,
} from "../../types/icon";
import { EmbeddedTooltip } from "../../types/props";
import { OSIcon } from "./OSIcon";
import { OSIconStack } from "./OSIconStack";
import { OSIconStateful } from "./OSIconStateful";
import { Property } from "csstype";
import { FAIdentifier } from "../../types/fa-icons";

/**
 * Properties for {@link OSIcon}.
 *
 * Additional properties passed to child `<span/>` or `<a/>` element, depending if `link` is defined.
 */
export interface OSIconProps
  extends Icon,
    EmbeddedTooltip,
    React.HTMLAttributes<HTMLElement> {
  /** Hyperlink to allow clicking of icon. */
  link?: string;
}

/**
 * Properties for {@link OSIconStack}.
 *
 * Additional properties passed to child \<div/> element.
 */
export interface OSIconStackProps
  extends PropsWithChildren,
    EmbeddedTooltip,
    React.HTMLAttributes<HTMLElement> {
  /**
   * Sizing of FontAwesome icon container. Can be FontAwesome specific sizing, or generic `fontSize`.
   * Note that due to mechanics of FontAwesome stacking, this will be double the set value.
   *
   * Alternatively, sizing can be set via `fontSize` CSS property.
   * @default "1x"
   */
  size?: IconSize | Property.FontSize<string | number> | undefined;
  animation?: IconAnimationOptions | IconAnimationType | undefined;
}

/**
 * Properties for {@link OSIconStateful}
 *
 * Additional properties passed to child {@link OSIcon|`<OSIcon/>`} element.
 */
export interface OSIconStatefulProps<T extends string | number> extends Omit<OSIconProps, "identifier"> {
  /** Fallback icon identifier if state is not recognized */
  identifier?: FAIdentifier | undefined;

  /** Currently active state of icon */
  currentState?: T;

  /** Available states of icon */
  states: OSIconState<T>[];
}

/**
 * Used with {@link OSIconStatefulProps|OSStatefulIcon}.
 * Definition of icon state to be added to icon.
 */
export interface OSIconState<T extends string | number> {
  /** Identifying value for state */
  state: T;
  /** 
   * Icon information. Supports all icon details.
   * `undefined` falls back to parent icon (if present), `false` hides icon regardless of fallback.
   */
  icon?: Icon | null | false | undefined;
}
