/* global React */
const { useEffect, useRef, useState } = React;

/* ============ Animated text counter ============ */
function Counter({ target, suffix = "", duration = 1400, decimals = 0 }) {
  const [v, setV] = useState(0);
  const ref = useRef(null);
  const started = useRef(false);
  useEffect(() => {
    const obs = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting && !started.current) {
          started.current = true;
          const t0 = performance.now();
          const tick = (now) => {
            const p = Math.min(1, (now - t0) / duration);
            const eased = 1 - Math.pow(1 - p, 3);
            setV(target * eased);
            if (p < 1) requestAnimationFrame(tick);
          };
          requestAnimationFrame(tick);
        }
      });
    }, { threshold: 0.4 });
    if (ref.current) obs.observe(ref.current);
    return () => obs.disconnect();
  }, [target, duration]);
  const formatted = decimals > 0 ? v.toFixed(decimals).replace(".", ",") : Math.round(v).toLocaleString("fr-FR");
  return <span ref={ref}>{formatted}{suffix}</span>;
}

/* ============ Reveal on scroll ============ */
function Reveal({ children, delay = 0, as: Tag = "div", className = "", style }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const obs = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          setTimeout(() => setShown(true), delay);
          obs.disconnect();
        }
      });
    }, { threshold: 0.15 });
    if (ref.current) obs.observe(ref.current);
    return () => obs.disconnect();
  }, [delay]);
  return <Tag ref={ref} className={`fade-in ${shown ? "in" : ""} ${className}`} style={style}>{children}</Tag>;
}

/* ============ Live clock (newsroom style) ============ */
function LiveClock() {
  const [now, setNow] = useState(new Date());
  useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  const hh = String(now.getHours()).padStart(2, "0");
  const mm = String(now.getMinutes()).padStart(2, "0");
  const ss = String(now.getSeconds()).padStart(2, "0");
  return <span className="mono">{hh}:{mm}:{ss} CET</span>;
}

/* ============ Typewriter (variant B hero) ============ */
function Typewriter({ lines = [], typeSpeed = 36, holdMs = 1600, eraseSpeed = 18, className = "" }) {
  const [text, setText] = useState("");
  const [i, setI] = useState(0);
  const [phase, setPhase] = useState("type"); // type, hold, erase
  useEffect(() => {
    if (lines.length === 0) return;
    let to;
    const current = lines[i];
    if (phase === "type") {
      if (text.length < current.length) {
        to = setTimeout(() => setText(current.slice(0, text.length + 1)), typeSpeed);
      } else {
        to = setTimeout(() => setPhase("erase"), holdMs);
      }
    } else if (phase === "erase") {
      if (text.length > 0) {
        to = setTimeout(() => setText(text.slice(0, -1)), eraseSpeed);
      } else {
        setI((i + 1) % lines.length);
        setPhase("type");
      }
    }
    return () => clearTimeout(to);
  }, [text, phase, i, lines, typeSpeed, holdMs, eraseSpeed]);
  return (
    <span className={className}>
      {text}
      <span style={{
        display: "inline-block", width: 10, height: "0.9em",
        background: "var(--static-mint)", marginLeft: 4,
        verticalAlign: "text-bottom",
        animation: "cursor-blink 1s steps(2) infinite"
      }} />
    </span>);

}

/* ============ Word-by-word reveal ============ */
function WordReveal({ text, delay = 0, stagger = 70, className = "", style }) {
  const words = text.split(" ");
  return (
    <span className={className} style={style}>
      {words.map((w, idx) => (
        <span key={idx} className="reveal-word" style={{ marginRight: "0.28em" }}>
          <span style={{ animationDelay: `${delay + idx * stagger}ms` }}>{w}</span>
        </span>
      ))}
    </span>
  );
}

/* ============ Browser-bar mockup (case studies) ============ */
function BrowserBar({ url }) {
  return (
    <div style={{
      display: "flex", alignItems: "center", gap: 8,
      padding: "10px 12px",
      background: "var(--bg-slate)",
      borderTopLeftRadius: "var(--r-nested)",
      borderTopRightRadius: "var(--r-nested)",
      borderBottom: "1px solid var(--border-frame)"
    }}>
      <span style={{ width: 8, height: 8, borderRadius: "50%", background: "#ff5b1f" }} />
      <span style={{ width: 8, height: 8, borderRadius: "50%", background: "#ffd400" }} />
      <span style={{ width: 8, height: 8, borderRadius: "50%", background: "#3cffd0" }} />
      <span style={{
        marginLeft: 12,
        fontFamily: "var(--font-mono)", fontSize: 10,
        letterSpacing: "1.1px", textTransform: "uppercase",
        color: "var(--fg-secondary)"
      }}>{url}</span>
    </div>);

}

/* ============ Generic placeholder card (AlarmTech mock without screenshot) ============ */
function AlarmMockCard() {
  return (
    <div style={{
      width: "100%", height: "100%",
      background: "var(--bg-absolute-black)",
      display: "flex", flexDirection: "column", justifyContent: "space-between",
      padding: 16, gap: 8
    }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <div style={{
          fontFamily: "var(--font-display)", fontWeight: 900,
          fontSize: 18, letterSpacing: 0.3, color: "var(--fg-primary)"
        }}>ALARMTECH 31</div>
        <span style={{
          fontFamily: "var(--font-mono)", fontSize: 8,
          color: "var(--static-mint)", letterSpacing: 1.2, textTransform: "uppercase"
        }}>NF&amp;A2P</span>
      </div>
      <div style={{
        fontFamily: "var(--font-display)", fontWeight: 900,
        fontSize: 22, lineHeight: 0.95, color: "var(--fg-primary)"
      }}>Sécurité<br />certifiée.<br /><span style={{ color: "var(--static-mint)" }}>Toulouse.</span></div>
      <div style={{
        display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 4
      }}>
        {["Alarme", "Vidéo", "Contrôle"].map((s) =>
        <span key={s} style={{
          fontFamily: "var(--font-mono)", fontSize: 8,
          background: "var(--bg-slate)", color: "var(--fg-muted)",
          padding: "5px 6px", borderRadius: 4,
          letterSpacing: 1, textTransform: "uppercase", textAlign: "center"
        }}>{s}</span>
        )}
      </div>
      <button style={{
        background: "var(--static-mint)", color: "var(--bg-absolute-black)",
        border: 0, borderRadius: 20, padding: "6px 12px",
        fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 9,
        letterSpacing: 1.5, textTransform: "uppercase", cursor: "pointer",
        alignSelf: "flex-start"
      }}>Devis 5 min →</button>
    </div>);

}

Object.assign(window, {
  Counter, Reveal, LiveClock, Typewriter, WordReveal, BrowserBar, AlarmMockCard
});