import React, { useRef } from "react";
import { isIconSize, parseAnimation, parseOptions } from "./helpers";
import { Tooltip } from "primereact/tooltip";
import { OSCSSProperties } from "../../types/react";
import { OSIconProps } from "./props";


/**
 * Standardized, fixed-width icon using FontAwesome.
 * 
 * @classes `os-icon` `os-icon-tooltip` `os-clickable`
 * 
 * @example 
 * <OSIcon id="icon-user" identifier="user" colour="var(--os-accent)" size="3x" />
 * 
 * @see https://docs.fontawesome.com/web
 */
export const OSIcon = React.memo(({
    identifier,
    pack,
    className,
    weight,
    colour,
    opacity,
    flip,
    rotation,
    size,
    animation,
    options,
    tooltip,
    tooltipOptions,
    link,
    ...props
}: OSIconProps) => {

    const elementRef = useRef<any>(null);

    //Always be fixed width
    const classes = [
        "os-icon",
        "fa-fw",
        "self-center"];
    const styles: OSCSSProperties = { ...props.style };

    //Set identifier
    classes.push(`fa-${identifier}`);

    //Set pack
    classes.push(`fa-${pack ?? "classic"}`);

    //Set weight (Leave empty if undefined to adopt css styling)
    if (weight) {
        classes.push(`fa-${weight}`);
    }

    //Set flip
    if (flip && flip !== "none") {
        classes.push(`fa-flip-${flip}`);
    }

    //Add rotation
    if (rotation) {
        classes.push("fa-rotate-by");
        styles["--fa-rotate-angle"] = `${rotation ?? 0}deg`
    };

    //Add size
    if (size) {
        if (isIconSize(size)) {
            classes.push(`fa-${size}`);
        } else {
            styles.fontSize = size;
        }
    }

    //Set colour
    if (colour) {
        styles.color = colour;
    }

    //Add animation
    parseAnimation(animation, classes, styles);

    //Add opacity (respect global opacity style as well)
    if (opacity !== undefined) {
        styles.opacity = opacity * (+(styles.opacity ?? 1));
    }

    //Add options
    parseOptions(options, styles);

    //Apply style class if clickable
    if (props.onClick) {
        classes.push("os-clickable");
    }


    /**
     * Internal component to correctly handle link if present
     */
    function Icon(props: React.HTMLAttributes<HTMLElement>) {
        return (<>
            {link
                ? <a {...props} ref={elementRef} href={link} />
                : <i {...props} ref={elementRef} />
            }
        </>);
    }

    return (<>
        <Icon role="presentation"
            aria-description={`${identifier} icon`}
            {...props}
            className={[...classes, className].join(" ")}
            style={styles} />
        {tooltip && (elementRef !== null) && <Tooltip className="os-icon-tooltip" target={elementRef as React.RefObject<HTMLElement>} {...tooltipOptions}>{tooltip}</Tooltip>}
    </>);
})