// Reusable hooks + small motion components for the FMProject site.
const { useState: _useState, useEffect: _useEffect, useRef: _useRef, useCallback } = React;

// ─── useReveal: fade+slide in when element enters viewport ───────────
function useReveal(opts = {}) {
  const ref = _useRef(null);
  const [visible, setVisible] = _useState(false);
  _useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (typeof IntersectionObserver === "undefined") {
      setVisible(true);
      return;
    }
    const io = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setVisible(true);
          io.disconnect();
        }
      },
      { threshold: opts.threshold ?? 0.15, rootMargin: opts.rootMargin ?? "0px 0px -40px 0px" }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return [ref, visible];
}

const Reveal = ({ children, delay = 0, as: Tag = "div", className = "", style = {}, y = 16 }) => {
  const [ref, visible] = useReveal();
  return (
    <Tag
      ref={ref}
      className={className}
      style={{
        ...style,
        opacity: visible ? 1 : 0,
        transform: visible ? "translateY(0)" : `translateY(${y}px)`,
        transition: `opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1) ${delay}ms, transform 0.7s cubic-bezier(0.22, 1, 0.36, 1) ${delay}ms`,
        willChange: "opacity, transform",
      }}
    >
      {children}
    </Tag>
  );
};

// ─── useCountUp: animate a number when in view ───────────────────────
function useCountUp(end, { duration = 1200, start = 0 } = {}) {
  const [ref, visible] = useReveal({ threshold: 0.4 });
  const [val, setVal] = _useState(start);
  _useEffect(() => {
    if (!visible) return;
    const t0 = performance.now();
    let raf;
    const tick = (t) => {
      const p = Math.min(1, (t - t0) / duration);
      const eased = 1 - Math.pow(1 - p, 3); // ease-out cubic
      setVal(Math.round(start + (end - start) * eased));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [visible]);
  return [ref, val];
}

// ─── ScrollProgress: thin bar at top of page ─────────────────────────
const ScrollProgress = () => {
  const [pct, setPct] = _useState(0);
  _useEffect(() => {
    const onScroll = () => {
      const h = document.documentElement.scrollHeight - window.innerHeight;
      setPct(h > 0 ? (window.scrollY / h) * 100 : 0);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <div
      aria-hidden="true"
      style={{
        position: "fixed",
        top: 0,
        left: 0,
        right: 0,
        height: 2,
        zIndex: 50,
        pointerEvents: "none",
      }}
    >
      <div
        style={{
          height: "100%",
          width: `${pct}%`,
          background: "linear-gradient(90deg, #2563EB 0%, #60A5FA 60%, #93C5FD 100%)",
          transition: "width 0.08s linear",
          boxShadow: "0 0 12px rgba(96,165,250,0.65)",
        }}
      />
    </div>
  );
};

// ─── CursorGlow: ambient blue glow that follows the mouse on hero ────
const CursorGlow = ({ targetSelector = "#hero" }) => {
  const dotRef = _useRef(null);
  _useEffect(() => {
    const target = document.querySelector(targetSelector);
    if (!target) return;
    let raf;
    let tx = 0, ty = 0, x = 0, y = 0;
    let active = false;
    const onMove = (e) => {
      const rect = target.getBoundingClientRect();
      tx = e.clientX - rect.left;
      ty = e.clientY - rect.top;
      active = true;
      if (dotRef.current) dotRef.current.style.opacity = "1";
    };
    const onLeave = () => {
      active = false;
      if (dotRef.current) dotRef.current.style.opacity = "0";
    };
    const tick = () => {
      x += (tx - x) * 0.12;
      y += (ty - y) * 0.12;
      if (dotRef.current) {
        dotRef.current.style.transform = `translate3d(${x - 280}px, ${y - 280}px, 0)`;
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    target.addEventListener("mousemove", onMove);
    target.addEventListener("mouseleave", onLeave);
    return () => {
      cancelAnimationFrame(raf);
      target.removeEventListener("mousemove", onMove);
      target.removeEventListener("mouseleave", onLeave);
    };
  }, [targetSelector]);
  return (
    <div
      ref={dotRef}
      aria-hidden="true"
      style={{
        position: "absolute",
        top: 0,
        left: 0,
        width: 560,
        height: 560,
        borderRadius: "50%",
        background:
          "radial-gradient(circle, rgba(59,130,246,0.18) 0%, rgba(37,99,235,0.06) 40%, transparent 70%)",
        pointerEvents: "none",
        opacity: 0,
        transition: "opacity 250ms ease",
        mixBlendMode: "screen",
        zIndex: 1,
      }}
    />
  );
};

// ─── Marquee: infinite horizontal trust-signal strip ─────────────────
const Marquee = ({ items, speed = 50, className = "" }) => {
  // duplicate items for seamless loop
  const row = [...items, ...items];
  return (
    <div
      className={"relative overflow-hidden " + className}
      style={{
        WebkitMaskImage:
          "linear-gradient(90deg, transparent 0, black 8%, black 92%, transparent 100%)",
        maskImage:
          "linear-gradient(90deg, transparent 0, black 8%, black 92%, transparent 100%)",
      }}
    >
      <div
        className="flex gap-12 whitespace-nowrap"
        style={{
          animation: `fm-marquee ${speed}s linear infinite`,
          width: "max-content",
        }}
      >
        {row.map((it, i) => (
          <div
            key={i}
            className="flex items-center gap-3 text-sm font-medium"
            style={{ color: "rgba(241,245,249,0.55)" }}
          >
            {it.icon && (
              <span style={{ color: "rgba(96,165,250,0.7)" }}>
                <it.icon size={16} />
              </span>
            )}
            <span style={{ letterSpacing: "0.02em" }}>{it.label}</span>
            <span aria-hidden="true" style={{ color: "rgba(96,165,250,0.25)" }}>·</span>
          </div>
        ))}
      </div>
    </div>
  );
};

// ─── ChatPreview: animated dialogue inside a card ────────────────────
const ChatPreview = () => {
  const script = [
    { who: "user", text: "Mikor kapom meg az új SIM-et?" },
    { who: "bot", text: "Jó napot! A rendelés #4831 holnap 10:00–14:00 között érkezik. Kéri az SMS értesítést?" },
    { who: "user", text: "Igen, köszönöm." },
    { who: "bot", text: "Beállítottam. Segíthetek bármi másban?" },
  ];
  const [step, setStep] = _useState(0);
  const [typing, setTyping] = _useState(false);
  const [ref, visible] = useReveal({ threshold: 0.3 });

  _useEffect(() => {
    if (!visible) return;
    let cancelled = false;
    let timers = [];

    const run = (i) => {
      if (cancelled) return;
      if (i >= script.length) {
        // restart loop after pause
        timers.push(setTimeout(() => {
          if (cancelled) return;
          setStep(0);
          setTyping(false);
          timers.push(setTimeout(() => run(0), 600));
        }, 3500));
        return;
      }
      const isBot = script[i].who === "bot";
      if (isBot) {
        setTyping(true);
        timers.push(setTimeout(() => {
          if (cancelled) return;
          setTyping(false);
          setStep(i + 1);
          timers.push(setTimeout(() => run(i + 1), 700));
        }, 1100));
      } else {
        setStep(i + 1);
        timers.push(setTimeout(() => run(i + 1), 900));
      }
    };

    timers.push(setTimeout(() => run(0), 400));
    return () => {
      cancelled = true;
      timers.forEach(clearTimeout);
    };
  }, [visible]);

  return (
    <div
      ref={ref}
      className="rounded-xl px-3 py-2.5 w-full max-w-[260px]"
      style={{
        background: "#080D1A",
        border: "1px solid rgba(255,255,255,0.07)",
        boxShadow: "inset 0 1px 0 rgba(255,255,255,0.04)",
      }}
    >
      <div className="flex items-center justify-between mb-2 pb-1.5" style={{ borderBottom: "1px solid rgba(255,255,255,0.05)" }}>
        <div className="flex items-center gap-1.5">
          <span className="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse" />
          <span className="text-[10px] font-mono" style={{ color: "rgba(96,165,250,0.7)" }}>
            FMP-Assistant
          </span>
        </div>
        <span className="text-[9px] font-mono" style={{ color: "rgba(241,245,249,0.32)" }}>
          live
        </span>
      </div>

      <div className="space-y-1.5 min-h-[88px]">
        {script.slice(Math.max(0, step - 2), step).map((m, idx) => (
          <div
            key={`${step}-${idx}`}
            className={"flex " + (m.who === "user" ? "justify-end" : "justify-start")}
            style={{
              animation: "fm-msg-in 0.35s cubic-bezier(0.22, 1, 0.36, 1) both",
            }}
          >
            <div
              className="max-w-[85%] px-2.5 py-1.5 rounded-lg text-[11.5px] leading-snug"
              style={
                m.who === "user"
                  ? { background: "rgba(37,99,235,0.85)", color: "white", borderBottomRightRadius: 4 }
                  : { background: "rgba(255,255,255,0.06)", color: "rgba(241,245,249,0.9)", borderBottomLeftRadius: 4 }
              }
            >
              {m.text}
            </div>
          </div>
        ))}
        {typing && (
          <div className="flex justify-start" style={{ animation: "fm-msg-in 0.25s ease both" }}>
            <div
              className="px-3 py-2 rounded-lg flex items-center gap-1"
              style={{ background: "rgba(255,255,255,0.06)", borderBottomLeftRadius: 4 }}
            >
              {[0, 1, 2].map((i) => (
                <span
                  key={i}
                  className="w-1 h-1 rounded-full"
                  style={{
                    background: "rgba(96,165,250,0.85)",
                    animation: `fm-typing 1.1s ${i * 0.15}s infinite ease-in-out`,
                  }}
                />
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

Object.assign(window, {
  useReveal,
  Reveal,
  useCountUp,
  ScrollProgress,
  CursorGlow,
  Marquee,
  ChatPreview,
});
