import "./style.pcss";

import type { FC, ReactElement } from "react";
import { useState, useEffect, useMemo } from "react";
import type { IIcon } from "./config/types";
import { getIconHref } from "./utils/getIconHref";
import { getSvgAttrs } from "./utils/getSvgAttrs";
import { constants } from "../../constants";
import type { IComponentBaseProps } from "../../types/components";
import { getExtraSizes } from "../../utils/getExtraSizes";
import { getSanitizedHTML } from "../../utils/getSanitizedHTML";
import { useCN } from "../../utils/react/useCN";

const fallbackSize = constants.defaultSizes[0];

/**
 * Компонент иконки
 * @returns {ReactElement}
 */
const Icon: FC<IComponentBaseProps & IIcon> = ({
  baseClass = "icon",
  extraClasses = {},
  extraAttrs = {},
  children = null,
  size = fallbackSize,
  src = "",
  type = "asset",
  style = "outlined",
  width,
  height,
}): ReactElement => {

  const { getCN } = useCN(baseClass);

  const [ source, setSource ] = useState<string>(() => getIconHref(src, type));

  useEffect(() => {
    setSource(getIconHref(src, type));
  }, [ src, type ]);

  const renderProps = useMemo(() => {
    if (children) {
      return { children };
    }

    switch (type) {
      case "asset": {
        const fallbackAttrs = getSvgAttrs(size);
        const w = width || fallbackAttrs.width;
        const h = height || fallbackAttrs.height;
        const attrs = (!!w && !!h) ? `width=${w} height=${h}` : ``;
        const svg = `<svg ${attrs} class="${getCN("src")}"><use href="${source}" /></svg>`;
        return {
          dangerouslySetInnerHTML: {
            __html: getSanitizedHTML(svg),
          },
        };
      }

      case "material": {
        return {
          children: (
            <span className={getCN("src", {}, [ `material-symbols-${style}` ])}>
              {source}
            </span>
          ),
        };
      }

      default:
        console.error(`[Icon] Please check the "src" prop ("${src}"), failed to set icon content`);
        return {};
    }
  }, [ children, type, src, getCN, source, style, size ]);

  return (
    <span role={"presentation"} className={getCN("", getExtraSizes({ size, extraClasses }))} {...renderProps} {...extraAttrs} />
  );
};

export type { IIcon };
export { Icon };
