import { forwardRef, useEffect, useRef, useState } from "react";

import { BadgeType } from "@/types/badge";
import { FONT_FAMILY } from "@/components/font-family/font-family.constants";

import { RATIONAL_BADGE_WIDTH } from "../badge-editor.constants";
import { Icons } from "@/components/svg/icons";
import { IconItem } from "@/types/editor";
import { BADGE_COMPONENTS } from "@/components/svg/badges";
import classNames from "classnames";
import { ShineEffect } from "./shine_effect";

export const Badge = forwardRef(
  (
    {
      badge,
      size = "medium",
    }: {
      badge: BadgeType;
      size?: "medium" | "small";
    },
    ref
  ) => {
    const textRef = useRef<any>(null);
    const svgRef = useRef<any>(null);
    const badgeContentRef = useRef<any>(null);
    const [viewBox, setViewBox] = useState<string>("0 0 24 24");

    useEffect(() => {
      if (!textRef.current) return;
      if (!badgeContentRef.current) return;

      const textWidth = textRef.current.getBoundingClientRect().width;

      let newBadgeWidth = RATIONAL_BADGE_WIDTH;
      if (textWidth > RATIONAL_BADGE_WIDTH) {
        newBadgeWidth = Math.ceil(textWidth / 32) * 32;
      }
      if (
        (findShape?.autoResize || badge.type === "circle") &&
        newBadgeWidth - textWidth < (badge.type === "circle" ? 6 : 3)
      )
        newBadgeWidth += 32;
      badgeContentRef.current.style.width = `${newBadgeWidth}px`;
    }, [
      badge.text,
      badge.fontFamily,
      badge.letterSpacing,
      badge.fontWeight,
      badge.type,
      badge?.icon?.component,
      badge?.icon?.enabled,
      badge?.icon?.position,
    ]);

    const fontFamily = FONT_FAMILY?.find((f) => f.label === badge?.fontFamily);

    const defaultStyle = {
      letterSpacing: badge?.letterSpacing,
      fontWeight: badge?.fontWeight,
    };

    const findIcon = Icons?.find(
      (i: IconItem) => badge?.icon?.component === i.name
    );
    const findShape = BADGE_COMPONENTS?.find(
      (b: any) => b.name === badge?.type
    );

    useEffect(() => {
      return setViewBox(
        svgRef?.current?.getAttribute("viewBox") ?? "0 0 200 200"
      );
    }, [badge?.icon]);

    const IconComponent = findIcon?.component as any;
    const ShapeComponent = findShape?.component as any;

    return (
      <div
        id={size === "medium" ? "discotools-selected-badge" : ""}
        ref={ref as any}
        className="max-w-max flex items-center h-[32px] justify-center relative"
      >
        {findShape?.component && (
          <ShapeComponent.left color={badge?.stringColor ?? badge?.colour} />
        )}
        {badge?.shinyEffect && (
          <>
            <ShineEffect className="absolute left-[6px] -bottom-[0px] z-1" />
            <ShineEffect className="absolute right-[6px] -top-[0px] z-1" />
          </>
        )}
        <div
          className="whitespace-nowrap text-white font-bold flex text-[18px] h-[28px] items-center justify-center text-center transition-all duration-200 relative"
          ref={badgeContentRef}
          style={{
            background: badge?.stringColor ?? badge?.colour,
            borderRadius: badge.type !== "circle" ? 0 : badge?.radius ?? 0,
          }}
        >
          <div
            ref={textRef as any}
            className="flex items-center justify-center gap-2"
          >
            {badge?.icon?.enabled &&
              badge?.icon?.position?.includes("left") &&
              findIcon?.component &&
              badge?.icon?.component && (
                <svg
                  width={16}
                  height={16}
                  fill={badge?.icon?.colour}
                  viewBox={viewBox}
                  style={{ minWidth: 16, minHeight: 16 }}
                >
                  <IconComponent ref={svgRef as any} />
                </svg>
              )}

            {badge?.text?.value && (
              <p
                className={`!bg-clip-text text-transparent ${fontFamily?.value}`}
                style={
                  badge?.text?.gradient?.enabled
                    ? {
                        backgroundImage:
                          badge?.text?.stringColor ?? badge?.text?.colour,
                        ...defaultStyle,
                      }
                    : {
                        backgroundColor:
                          badge?.text?.stringColor ?? badge?.text?.colour,
                        ...defaultStyle,
                      }
                }
              >
                {badge?.text?.value}
              </p>
            )}
            {badge?.icon?.enabled &&
              badge?.icon?.position?.includes("right") &&
              findIcon?.component &&
              badge?.icon?.component && (
                <svg
                  width={16}
                  height={16}
                  fill={badge?.icon?.colour}
                  viewBox={viewBox}
                  style={{ minWidth: 16, minHeight: 16 }}
                >
                  <IconComponent ref={svgRef as any} />
                </svg>
              )}
          </div>
        </div>
        {findShape?.component && (
          <ShapeComponent.right color={badge?.stringColor ?? badge?.colour} />
        )}
      </div>
    );
  }
);
