// Customer Journey — animated path through the retention lifecycle.
// A dotted hand-drawn path connects 5 stages; an orange "customer" dot
// travels along it; emails pop up at each stage as the dot passes.

const { useEffect, useRef, useState } = React;

const JOURNEY_GEO = [
  { id: "discovery", icon: "👀", x: 6, y: 50 },
  { id: "first", icon: "🛍️", x: 28, y: 22 },
  { id: "engage", icon: "✦", x: 52, y: 68 },
  { id: "loyal", icon: "♛", x: 76, y: 26 },
  { id: "advocate", icon: "♡", x: 96, y: 58 }
];

function JourneyTrack() {
  const jc = useCopy().journey;
  const JOURNEY_STAGES = JOURNEY_GEO.map((g, i) => Object.assign({}, g, jc.stages[i]));
  const trackRef = useRef(null);
  const [progress, setProgress] = useState(0); // 0..1
  const [playing, setPlaying] = useState(true);
  const rafRef = useRef(null);
  const lastTs = useRef(0);

  useEffect(() => {
    if (!playing) return;
    const DURATION = 12000; // ms full loop
    const tick = (ts) => {
      if (!lastTs.current) lastTs.current = ts;
      const dt = ts - lastTs.current;
      lastTs.current = ts;
      setProgress((p) => {
        let np = p + dt / DURATION;
        if (np > 1) np = 0;
        return np;
      });
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => {
      cancelAnimationFrame(rafRef.current);
      lastTs.current = 0;
    };
  }, [playing]);

  // Compute dot position by interpolating between stages along their x/y
  const dot = (() => {
    const segs = JOURNEY_STAGES.length - 1;
    const t = progress * segs;
    const i = Math.min(Math.floor(t), segs - 1);
    const f = t - i;
    const a = JOURNEY_STAGES[i];
    const b = JOURNEY_STAGES[i + 1];
    // Use a sine-ease bend so motion feels organic
    const ease = (1 - Math.cos(f * Math.PI)) / 2;
    return {
      x: a.x + (b.x - a.x) * ease,
      y: a.y + (b.y - a.y) * ease,
      activeIdx: f > 0.5 ? i + 1 : i,
      neighborhood: JOURNEY_STAGES.reduce((acc, s, idx) => {
        // each stage 'lights' as the dot is near its x
        const dist = Math.abs(s.x - (a.x + (b.x - a.x) * ease));
        acc[idx] = dist < 12 ? 1 : 0;
        return acc;
      }, {})
    };
  })();

  // SVG path: smooth curve through all stage points
  const pathD = (() => {
    const pts = JOURNEY_STAGES.map((s) => ({ x: s.x, y: s.y }));
    if (pts.length < 2) return "";
    let d = `M ${pts[0].x} ${pts[0].y}`;
    for (let i = 0; i < pts.length - 1; i++) {
      const p0 = pts[i];
      const p1 = pts[i + 1];
      const mx = (p0.x + p1.x) / 2;
      // alternate curve direction for hand-drawn feel
      const cy = i % 2 === 0 ? p0.y - 16 : p0.y + 16;
      d += ` Q ${mx} ${cy}, ${p1.x} ${p1.y}`;
    }
    return d;
  })();

  // Progress path stroke-dash for the traced segment
  const pathRef = useRef(null);
  const [pathLen, setPathLen] = useState(0);
  useEffect(() => {
    if (pathRef.current) {
      setPathLen(pathRef.current.getTotalLength());
    }
  }, []);

  return (
    <div className="journey-board">
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 14, gap: 24, flexWrap: "wrap" }}>
        <div>
          <div className="kicker">Customer Journey</div>
          <div style={{ fontFamily: "var(--serif)", fontSize: 28, lineHeight: 1.1, marginTop: 6, maxWidth: "32ch" }}>
            {jc.boardTitle}
          </div>
        </div>
        <div className="journey-controls">
          <button className="btn btn-sm" onClick={() => setPlaying((p) => !p)}>
            {playing ? jc.pause : jc.play}
          </button>
          <button className="btn btn-sm btn-ghost" onClick={() => { setProgress(0); lastTs.current = 0; }}>
            {jc.restart}
          </button>
        </div>
      </div>

      <div className="journey-track" ref={trackRef}>
        <svg
          className="journey-path"
          viewBox="0 0 100 100"
          preserveAspectRatio="none"
          style={{ width: "100%", height: "100%" }}
        >
          <defs>
            <marker id="arrow" viewBox="0 0 10 10" refX="6" refY="5" markerWidth="5" markerHeight="5" orient="auto">
              <path d="M 0 0 L 10 5 L 0 10 z" fill="var(--ink)" />
            </marker>
          </defs>
          {/* dashed background path */}
          <path
            ref={pathRef}
            d={pathD}
            fill="none"
            stroke="var(--ink)"
            strokeWidth="0.5"
            strokeDasharray="1.6 1.6"
            opacity="0.4"
            vectorEffect="non-scaling-stroke"
          />
          {/* traced overlay */}
          {pathLen > 0 && (
            <path
              d={pathD}
              fill="none"
              stroke="var(--accent)"
              strokeWidth="0.9"
              strokeLinecap="round"
              strokeDasharray={pathLen}
              strokeDashoffset={pathLen * (1 - progress)}
              vectorEffect="non-scaling-stroke"
            />
          )}
        </svg>

        {/* stages */}
        {JOURNEY_STAGES.map((s, i) => {
          const active = dot.activeIdx >= i;
          return (
            <div
              key={s.id}
              className="journey-stop"
              style={{
                left: `${s.x}%`,
                top: `${s.y}%`,
                transform: `translate(-50%, -50%) rotate(${(i % 2 === 0 ? -1.2 : 1.4)}deg)`
              }}
            >
              <div className="j-card" style={{ background: active ? "var(--marker)" : "var(--bg-card)", transition: "background .4s" }}>
                <div className="j-stage">{s.stage}</div>
                <div className="j-icon" style={{ background: active ? "var(--accent)" : "var(--marker)", color: active ? "#fff" : "var(--ink)" }}>{s.icon}</div>
                <div className="j-title">{s.title}</div>
                <div className="j-sub">{s.sub}</div>
              </div>
            </div>
          );
        })}

        {/* email pops */}
        {JOURNEY_STAGES.map((s, i) => {
          const show = dot.neighborhood[i] === 1;
          // place email pop offset from stage, alternating up/down
          const offY = (i % 2 === 0) ? 18 : -22;
          return (
            <div
              key={`em-${s.id}`}
              className={`email-pop ${show ? "show" : ""}`}
              style={{
                left: `calc(${s.x}% - 84px)`,
                top: `calc(${s.y}% + ${offY}%)`
              }}
            >
              <div className="from">{s.email.from}</div>
              <div className="subj">{s.email.subj}</div>
            </div>
          );
        })}

        {/* moving dot */}
        <div
          className="j-dot"
          style={{
            left: `${dot.x}%`,
            top: `${dot.y}%`
          }}
        />
      </div>

      <div className="journey-legend">
        <span className="hand" style={{ fontSize: 18, color: "var(--ink)" }}>
          {jc.legend}
        </span>
        <span style={{ marginLeft: "auto", display: "inline-flex", gap: 14, alignItems: "center" }}>
          <span style={{ display: "inline-flex", gap: 6, alignItems: "center" }}>
            <span style={{ width: 10, height: 10, borderRadius: "50%", background: "var(--accent)", border: "1.5px solid var(--ink)" }} />
            {jc.legendDot}
          </span>
          <span style={{ display: "inline-flex", gap: 6, alignItems: "center" }}>
            <span style={{ width: 14, height: 4, background: "var(--accent)", borderRadius: 2 }} />
            {jc.legendPath}
          </span>
        </span>
      </div>
    </div>
  );
}

Object.assign(window, { JourneyTrack });
