"use client";

import { useEffect, useState } from "react";

interface CardioLoaderProps {
  size?: number | string;
  stroke?: number | string;
  speed?: number | string;
  color?: string;
  className?: string;
}

/**
 * Cardio loader from `ldrs` — registered on first client mount.
 *
 * The custom-element `<l-cardio>` is registered globally once. We render
 * a same-sized placeholder on the server / before hydration to:
 *   1. avoid the React "unknown HTML tag" warning during SSR
 *   2. preserve layout so the surrounding flex/grid doesn't jump
 */
export function CardioLoader({
  size = 50,
  stroke = 4,
  speed = 2,
  color = "currentColor",
  className,
}: CardioLoaderProps) {
  const [registered, setRegistered] = useState(false);

  useEffect(() => {
    // Dynamic import keeps the ldrs bundle out of the SSR payload and
    // ensures `customElements.define` only runs in the browser.
    let cancelled = false;
    void import("ldrs").then((mod) => {
      if (cancelled) return;
      mod.cardio.register();
      setRegistered(true);
    });
    return () => {
      cancelled = true;
    };
  }, []);

  const sizePx = typeof size === "number" ? `${size}px` : size;

  if (!registered) {
    return (
      <span
        aria-hidden="true"
        className={className}
        style={{
          display: "inline-block",
          width: sizePx,
          // Cardio is a horizontal heartbeat — its bounding box is wider
          // than tall (~3:1). Match that so the placeholder doesn't push
          // surrounding content around when the real loader mounts.
          height: `calc(${sizePx} * 0.42)`,
        }}
      />
    );
  }

  return (
    <span
      role="status"
      aria-label="Loading"
      className={className}
      style={{ display: "inline-flex", color }}
    >
      <l-cardio
        size={String(size)}
        stroke={String(stroke)}
        speed={String(speed)}
        color={color}
      ></l-cardio>
    </span>
  );
}
