// HoloCard — adapted from React Bits ProfileCard.
// Holographic 3D card with mouse-tracking tilt, shine, glare, and rarity glow.
// Used in: drop pop-up, album collection, admin preview.

const HOLO_ANIM = {
  INITIAL_DURATION: 1200,
  INITIAL_X_OFFSET: 70,
  INITIAL_Y_OFFSET: 60,
  ENTER_TRANSITION_MS: 180,
};

const _clamp = (v, min = 0, max = 100) => Math.min(Math.max(v, min), max);
const _round = (v, p = 3) => parseFloat(v.toFixed(p));
const _adjust = (v, fMin, fMax, tMin, tMax) =>
  _round(tMin + ((tMax - tMin) * (v - fMin)) / (fMax - fMin));

function HoloCard({
  card,
  size = "md",       // "sm" | "md" | "lg"
  enableTilt = true,
  showInfo = true,
  className = "",
  onClick,
}) {
  const wrapRef = React.useRef(null);
  const shellRef = React.useRef(null);
  const enterTimerRef = React.useRef(null);
  const leaveRafRef = React.useRef(null);

  const rarity = window.CardSystem.getRarity(card?.rarity);

  const tiltEngine = React.useMemo(() => {
    if (!enableTilt) return null;
    let rafId = null, running = false, lastTs = 0;
    let curX = 0, curY = 0, tgX = 0, tgY = 0;
    const TAU_DEFAULT = 0.14, TAU_INITIAL = 0.6;
    let initialUntil = 0;

    const setVars = (x, y) => {
      const shell = shellRef.current; const wrap = wrapRef.current;
      if (!shell || !wrap) return;
      const w = shell.clientWidth || 1, h = shell.clientHeight || 1;
      const px = _clamp((100 / w) * x), py = _clamp((100 / h) * y);
      const cx = px - 50, cy = py - 50;
      const props = {
        '--pointer-x': `${px}%`,
        '--pointer-y': `${py}%`,
        '--background-x': `${_adjust(px, 0, 100, 35, 65)}%`,
        '--background-y': `${_adjust(py, 0, 100, 35, 65)}%`,
        '--pointer-from-center': `${_clamp(Math.hypot(py - 50, px - 50) / 50, 0, 1)}`,
        '--pointer-from-top': `${py / 100}`,
        '--pointer-from-left': `${px / 100}`,
        '--rotate-x': `${_round(-(cx / 5))}deg`,
        '--rotate-y': `${_round(cy / 4)}deg`,
      };
      for (const [k, v] of Object.entries(props)) wrap.style.setProperty(k, v);
    };
    const step = (ts) => {
      if (!running) return;
      if (lastTs === 0) lastTs = ts;
      const dt = (ts - lastTs) / 1000; lastTs = ts;
      const tau = ts < initialUntil ? TAU_INITIAL : TAU_DEFAULT;
      const k = 1 - Math.exp(-dt / tau);
      curX += (tgX - curX) * k;
      curY += (tgY - curY) * k;
      setVars(curX, curY);
      const far = Math.abs(tgX - curX) > 0.05 || Math.abs(tgY - curY) > 0.05;
      if (far) rafId = requestAnimationFrame(step);
      else { running = false; lastTs = 0; if (rafId) { cancelAnimationFrame(rafId); rafId = null; } }
    };
    const start = () => {
      if (running) return;
      running = true; lastTs = 0;
      rafId = requestAnimationFrame(step);
    };
    return {
      setImmediate(x, y) { curX = x; curY = y; setVars(x, y); },
      setTarget(x, y) { tgX = x; tgY = y; start(); },
      toCenter() {
        const s = shellRef.current; if (!s) return;
        this.setTarget(s.clientWidth / 2, s.clientHeight / 2);
      },
      beginInitial(d) { initialUntil = performance.now() + d; start(); },
      getCurrent() { return { x: curX, y: curY, tx: tgX, ty: tgY }; },
      cancel() { if (rafId) cancelAnimationFrame(rafId); rafId = null; running = false; lastTs = 0; },
    };
  }, [enableTilt]);

  React.useEffect(() => {
    if (!enableTilt || !tiltEngine) return;
    const shell = shellRef.current; if (!shell) return;
    const offsets = (e, el) => {
      const r = el.getBoundingClientRect();
      return { x: e.clientX - r.left, y: e.clientY - r.top };
    };
    const onMove = (e) => {
      const { x, y } = offsets(e, shell);
      tiltEngine.setTarget(x, y);
    };
    const onEnter = (e) => {
      shell.classList.add('hc-active');
      shell.classList.add('hc-entering');
      if (enterTimerRef.current) clearTimeout(enterTimerRef.current);
      enterTimerRef.current = setTimeout(() => shell.classList.remove('hc-entering'), HOLO_ANIM.ENTER_TRANSITION_MS);
      const { x, y } = offsets(e, shell);
      tiltEngine.setTarget(x, y);
    };
    const onLeave = () => {
      tiltEngine.toCenter();
      const settle = () => {
        const { x, y, tx, ty } = tiltEngine.getCurrent();
        if (Math.hypot(tx - x, ty - y) < 0.6) {
          shell.classList.remove('hc-active');
          leaveRafRef.current = null;
        } else {
          leaveRafRef.current = requestAnimationFrame(settle);
        }
      };
      if (leaveRafRef.current) cancelAnimationFrame(leaveRafRef.current);
      leaveRafRef.current = requestAnimationFrame(settle);
    };
    shell.addEventListener('pointerenter', onEnter);
    shell.addEventListener('pointermove', onMove);
    shell.addEventListener('pointerleave', onLeave);
    const ix = (shell.clientWidth || 0) - HOLO_ANIM.INITIAL_X_OFFSET;
    const iy = HOLO_ANIM.INITIAL_Y_OFFSET;
    tiltEngine.setImmediate(ix, iy);
    tiltEngine.toCenter();
    tiltEngine.beginInitial(HOLO_ANIM.INITIAL_DURATION);
    return () => {
      shell.removeEventListener('pointerenter', onEnter);
      shell.removeEventListener('pointermove', onMove);
      shell.removeEventListener('pointerleave', onLeave);
      if (enterTimerRef.current) clearTimeout(enterTimerRef.current);
      if (leaveRafRef.current) cancelAnimationFrame(leaveRafRef.current);
      tiltEngine.cancel();
    };
  }, [tiltEngine, enableTilt]);

  const cardStyle = {
    '--inner-gradient': rarity.inner,
    '--behind-glow-color': rarity.glow,
    '--rarity-color': rarity.color,
    '--behind-glow-size': size === "lg" ? "55%" : "40%",
  };

  return (
    <div
      ref={wrapRef}
      className={`hc-wrap hc-${size} ${className}`.trim()}
      style={cardStyle}
      onClick={onClick}
    >
      <div className="hc-behind" />
      <div ref={shellRef} className="hc-shell">
        <section className={`hc-card hc-rarity-${rarity.id}`}>
          <div className="hc-inside">
            <div className="hc-shine" />
            <div className="hc-glare" />
            <div className="hc-image">
              {card?.image ? (
                <img
                  src={card.image}
                  alt={card?.name || ""}
                  draggable="false"
                  className="hc-img-pannable"
                  style={{
                    '--img-px': `${card.imageOffsetX ?? 50}%`,
                    '--img-py': `${card.imageOffsetY ?? 50}%`,
                    '--img-scale': card.imageScale ?? 1,
                  }}
                />
              ) : (
                <div className="hc-image-placeholder">
                  <div className="hc-placeholder-text">SIN IMAGEN</div>
                </div>
              )}
            </div>
            {showInfo && (
              <div className="hc-info">
                <div className="hc-info-top">
                  <div className="hc-rarity-tag">{rarity.label}</div>
                  {card?.category && (
                    <div className="hc-category-tag">{card.category.toUpperCase()}</div>
                  )}
                </div>
                <div className="hc-info-bottom">
                  <h3 className="hc-name">{card?.name || "SIN NOMBRE"}</h3>
                  {card?.flavor && <p className="hc-flavor">{card.flavor}</p>}
                </div>
              </div>
            )}
          </div>
        </section>
      </div>
    </div>
  );
}

window.HoloCard = HoloCard;
