/* Cadran — "Upload image → gjenkjent" animation scene */
const { Stage, Sprite, useTime, Easing, interpolate, animate, clamp } = window;

const GULL = '#C4B075';
const GULL_LYS = '#FFE7A0';
const BRUN = '#1C180D';
const INK = '#1C180D';
const PAPER = '#F7F6F2';
const HAIR = 'rgba(28,24,13,0.14)';
const GROT = "'Die Grotesk A','Helvetica Neue',sans-serif";
const GROT_B = "'Die Grotesk B','Helvetica Neue',sans-serif";
const SERIF = "'Gestura Text',Georgia,serif";

// ---------- timeline (seconds) ----------
const T = {
  modalIn: 0.16,
  cursorIn: 0.8,
  click1: 1.76,
  uploadStart: 2.0,
  uploadEnd: 3.2,
  received: 3.5,
  scanStart: 4.4,
  scanEnd: 7.4,
  brackets: 4.8,
  chip: 7.4,
  f1: 8.0,   // Brand
  f2: 8.0,   // Model
  f3: 8.0,   // Serial
  f4: 8.0,   // Reference
  goldBtn: 8.8,
  cursor2: 9.0,
  click2: 10.0,
  modalOut: 10.3,
  doneIn: 10.7,
  end: 12.2,
};

const typed = (text, t, start) => (t < start ? '' : text);

// ---------- layout ----------
const M = { x: 340, y: 150, w: 1240, h: 780 };      // modal
const Z = { x: M.x + 48, y: M.y + 118, w: 540, h: 600 }; // left zone
const PH = { w: 540, h: 460 };                        // photo
const DIAL = { x: Z.x + 272, y: Z.y + 219, r: 118 };  // dial center abs
const F = { x: M.x + 648, w: 540 };                   // fields column

function Cursor({ x, y, o = 1, s = 1 }) {
  return (
    <svg width="34" height="34" viewBox="0 0 24 24"
      style={{ position: 'absolute', left: x, top: y, opacity: o,
        transform: `scale(${s})`, transformOrigin: '4px 3px', zIndex: 60,
        filter: 'drop-shadow(0 2px 6px rgba(0,0,0,0.35))' }}>
      <path d="M4 2 L4 19 L8.5 15.5 L11.5 22 L14.5 20.5 L11.5 14.5 L17.5 14 Z"
        fill="#fff" stroke={INK} strokeWidth="1.4" strokeLinejoin="round" />
    </svg>
  );
}

function Ripple({ t, at, x, y }) {
  if (t < at || t > at + 0.6) return null;
  const p = (t - at) / 0.6;
  const r = 10 + p * 34;
  return (
    <div style={{ position: 'absolute', left: x - r, top: y - r, width: r * 2, height: r * 2,
      borderRadius: '50%', border: `2px solid ${GULL}`, opacity: 1 - p, zIndex: 59 }} />
  );
}

function Field({ label, value, active, done, caret, flash = 0 }) {
  const border = active ? GULL : done ? GULL : HAIR;
  const flashBg = `rgba(196,176,117,${0.55 * flash})`;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 7 }}>
        <div style={{ fontFamily: GROT, fontSize: 19, fontWeight: 700, color: INK, whiteSpace: 'nowrap' }}>{label}</div>
        {active || done ? (
          <svg width="15" height="15" viewBox="0 0 24 24" style={{ transform: `scale(${1 + 0.4 * flash})` }}>
            <path d="M13 2 L4 14 H11 L10 22 L20 9 H13 Z" fill={GULL} />
          </svg>
        ) : null}
      </div>
      <div style={{ position: 'relative', height: 58, borderRadius: 14, border: `2px solid ${border}`,
        background: active || done ? 'rgba(196,176,117,0.08)' : '#fff',
        display: 'flex', alignItems: 'center', padding: '0 18px', overflow: 'hidden',
        boxShadow: active ? `0 0 0 4px rgba(196,176,117,0.22)` : 'none',
        transition: 'box-shadow 200ms' }}>
        <div style={{ position: 'absolute', inset: 0, background: flashBg, pointerEvents: 'none' }} />
        <span style={{ position: 'relative', fontFamily: GROT, fontSize: 22, color: INK,
          whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: '100%' }}>{value}</span>
      </div>
    </div>
  );
}

function Bracket({ x, y, rot }) {
  return (
    <div style={{ position: 'absolute', left: x, top: y, width: 34, height: 34,
      borderLeft: `3px solid ${GULL_LYS}`, borderTop: `3px solid ${GULL_LYS}`,
      transform: `rotate(${rot}deg)`, zIndex: 40 }} />
  );
}

function SceneBody() {
  const t = useTime();

  // modal enter / exit
  const mIn = animate({ from: 0, to: 1, start: T.modalIn, end: T.modalIn + 0.6, ease: Easing.easeOutCubic })(t);
  const mOut = animate({ from: 1, to: 0, start: T.modalOut, end: T.modalOut + 0.45, ease: Easing.easeInCubic })(t);
  const mO = Math.min(mIn, mOut);
  const mScale = 0.96 + 0.04 * mIn - (1 - mOut) * 0.05;

  // cursor 1: enter → button
  const btn1 = { x: Z.x + PH.w / 2, y: Z.y + 300 };
  const c1x = interpolate([T.cursorIn, T.click1 - 0.15], [1560, btn1.x + 6], Easing.easeInOutCubic)(t);
  const c1y = interpolate([T.cursorIn, T.click1 - 0.15], [1010, btn1.y + 4], Easing.easeInOutCubic)(t);
  const c1o = interpolate([T.cursorIn - 0.2, T.cursorIn, T.click1 + 0.5, T.click1 + 0.9], [0, 1, 1, 0])(t);
  const c1s = t > T.click1 && t < T.click1 + 0.22 ? 0.85 : 1;

  // upload progress
  const prog = clamp((t - T.uploadStart) / (T.uploadEnd - T.uploadStart), 0, 1);
  const photoReveal = animate({ from: 0, to: 1, start: T.uploadStart + 0.2, end: T.uploadEnd, ease: Easing.easeInOutQuad })(t);

  // scanning
  const scanP = clamp((t - T.scanStart) / (T.scanEnd - T.scanStart), 0, 1);
  const scanY = Z.y + Math.abs(Math.sin(scanP * Math.PI * 2)) * 0; // unused
  const passes = 2;
  const sweep = scanP * passes % 1;
  const dir = Math.floor(scanP * passes) % 2 === 0;
  const lineY = Z.y + (dir ? sweep : 1 - sweep) * (PH.h - 4);
  const scanning = t >= T.scanStart && t < T.scanEnd;

  // fields
  const merke = typed('Baume et Mercier', t, T.f1);
  const modell = typed('Riviera', t, T.f2);
  const serie = typed('66060', t, T.f3, 12);
  const ref = typed('M0A10620', t, T.f4, 14);
  const activeF = (start, text, cps = 18) => t >= start && t < start + text.length / cps + 0.25;
  const flashF = (start) => clamp(1 - (t - start) / 0.7, 0, 1) * (t >= start ? 1 : 0);

  // data beam: dots traveling from the recognized photo to the fields
  const beamActive = t >= T.chip && t < T.f1 + 0.3;
  const beamP = clamp((t - T.chip) / (T.f1 + 0.3 - T.chip), 0, 1);

  // cursor 2 → Opprett
  const btn2 = { x: M.x + M.w - 118, y: M.y + M.h - 76 };
  const c2x = interpolate([T.cursor2, T.click2 - 0.15], [Z.x + 420, btn2.x + 4], Easing.easeInOutCubic)(t);
  const c2y = interpolate([T.cursor2, T.click2 - 0.15], [Z.y + 520, btn2.y + 2], Easing.easeInOutCubic)(t);
  const c2o = interpolate([T.cursor2 - 0.2, T.cursor2, T.modalOut, T.modalOut + 0.3], [0, 1, 1, 0])(t);
  const c2s = t > T.click2 && t < T.click2 + 0.22 ? 0.85 : 1;

  const goldReady = t >= T.goldBtn;
  const uploaded = t >= T.uploadStart + 0.3;

  return (
    <div data-screen-label={`t=${Math.floor(t)}s`}
      style={{ position: 'absolute', inset: 0, background: '#EFEEE9', overflow: 'hidden', fontFamily: GROT }}>

      {/* modal */}
      <div style={{ position: 'absolute', left: M.x, top: M.y, width: M.w, height: M.h,
        background: PAPER, borderRadius: 24, opacity: mO,
        transform: `scale(${mScale})`, boxShadow: '0 40px 90px rgba(0,0,0,0.5)' }}>

        <div style={{ fontFamily: SERIF, fontSize: 36, color: INK, padding: '34px 48px 0',
          letterSpacing: '-0.01em' }}>New service order</div>
        <div style={{ position: 'absolute', right: 34, top: 34, fontSize: 26, color: 'rgba(28,24,13,0.5)' }}>✕</div>

        {/* left zone */}
        <div style={{ position: 'absolute', left: 48, top: 118, width: Z.w, height: Z.h,
          borderRadius: 18, border: `1px solid ${HAIR}`, background: '#fff', overflow: 'hidden' }}>

          {/* upload prompt state */}
          <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
            alignItems: 'center', justifyContent: 'center', gap: 22,
            opacity: interpolate([T.uploadStart, T.uploadStart + 0.35], [1, 0])(t) }}>
            <div style={{ width: 84, height: 84, borderRadius: 20, border: `2px dashed ${GULL}`,
              display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <svg width="38" height="38" viewBox="0 0 24 24" fill="none" stroke={GULL} strokeWidth="1.6">
                <rect x="3" y="3" width="18" height="18" rx="3" />
                <circle cx="9" cy="9" r="1.8" />
                <path d="M3 17 L9 12 L14 16 L18 13 L21 15" />
              </svg>
            </div>
            <div style={{ background: t > T.click1 && t < T.click1 + 0.22 ? '#A8945C' : GULL,
              color: BRUN, fontFamily: GROT, fontWeight: 700, fontSize: 21,
              padding: '15px 30px', borderRadius: 12 }}>Upload image</div>
            <div style={{ fontFamily: GROT, fontSize: 17, color: 'rgba(28,24,13,0.55)' }}>
              Or scan the QR code with your phone</div>
          </div>

          {/* photo */}
          {uploaded ? (
            <div style={{ position: 'absolute', left: 0, top: 0, width: PH.w, height: PH.h,
              overflow: 'hidden' }}>
              <img src="assets/watch-photo.png" alt=""
                style={{ width: '100%', height: '100%', objectFit: 'cover',
                  clipPath: `inset(0 0 ${(1 - photoReveal) * 100}% 0)`,
                  transform: `scale(${1.06 - 0.06 * photoReveal})`,
                  filter: photoReveal < 1 ? 'brightness(1.05)' : 'none' }} />
              {/* scan overlay */}
              {scanning ? (
                <div>
                  <div style={{ position: 'absolute', left: 0, top: lineY - Z.y, width: '100%', height: 3,
                    background: GULL_LYS, boxShadow: `0 0 22px 6px rgba(196,176,117,0.65)` }} />
                  <div style={{ position: 'absolute', inset: 0,
                    background: 'linear-gradient(rgba(196,176,117,0.10),rgba(196,176,117,0))' }} />
                </div>
              ) : null}
              {/* dial brackets */}
              {t >= T.brackets && t < T.modalOut ? (
                <div style={{ opacity: interpolate([T.brackets, T.brackets + 0.4], [0, 1])(t) }}>
                  <Bracket x={DIAL.x - Z.x - DIAL.r} y={DIAL.y - Z.y - DIAL.r} rot={0} />
                  <Bracket x={DIAL.x - Z.x + DIAL.r - 34} y={DIAL.y - Z.y - DIAL.r} rot={90} />
                  <Bracket x={DIAL.x - Z.x + DIAL.r - 34} y={DIAL.y - Z.y + DIAL.r - 34} rot={180} />
                  <Bracket x={DIAL.x - Z.x - DIAL.r} y={DIAL.y - Z.y + DIAL.r - 34} rot={270} />
                </div>
              ) : null}
              {/* recognition chip */}
              {t >= T.chip ? (
                <div style={{ position: 'absolute', left: '50%', top: DIAL.y - Z.y + DIAL.r + 18,
                  transform: `translateX(-50%) translateY(${(1 - animate({ from: 0, to: 1, start: T.chip, end: T.chip + 0.4, ease: Easing.easeOutCubic })(t)) * 10}px)`,
                  opacity: animate({ from: 0, to: 1, start: T.chip, end: T.chip + 0.4 })(t),
                  background: BRUN, color: GULL_LYS, fontFamily: GROT_B, fontSize: 15,
                  letterSpacing: '0.08em', textTransform: 'uppercase',
                  padding: '10px 18px', borderRadius: 999, whiteSpace: 'nowrap' }}>
                  Baume &amp; Mercier · Riviera</div>
              ) : null}
            </div>
          ) : null}

          {/* progress / status */}
          {uploaded ? (
            <div style={{ position: 'absolute', left: 0, top: PH.h, width: '100%', height: Z.h - PH.h,
              display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 14 }}>
              {t < T.received ? (
                <div style={{ width: 300 }}>
                  <div style={{ height: 5, borderRadius: 3, background: 'rgba(28,24,13,0.1)' }}>
                    <div style={{ height: '100%', width: `${prog * 100}%`, borderRadius: 3, background: GULL }} />
                  </div>
                  <div style={{ fontFamily: GROT_B, fontSize: 14, letterSpacing: '0.08em',
                    textTransform: 'uppercase', color: 'rgba(28,24,13,0.55)', marginTop: 10, textAlign: 'center' }}>
                    Uploading … {Math.round(prog * 100)} %</div>
                </div>
              ) : (
                <div style={{ display: 'flex', alignItems: 'center', gap: 10,
                  opacity: animate({ from: 0, to: 1, start: T.received, end: T.received + 0.35 })(t) }}>
                  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke={GULL} strokeWidth="2">
                    <circle cx="12" cy="12" r="10" />
                    <path d="M7.5 12.5 L10.5 15.5 L16.5 9" />
                  </svg>
                  <span style={{ fontFamily: GROT, fontSize: 20, fontWeight: 700, color: '#8a7940' }}>
                    {scanning ? 'Analyzing image …' : t >= T.scanEnd ? 'Watch recognized' : 'Image received'}</span>
                </div>
              )}
            </div>
          ) : null}
        </div>

        {/* auto-fill callout */}
        {t >= T.chip ? (
          <div style={{ position: 'absolute', left: F.x - M.x, top: 74, display: 'flex', gap: 10,
            alignItems: 'center', background: 'rgba(196,176,117,0.4)', borderRadius: 999,
            padding: '8px 18px 8px 12px', width: 'max-content', maxWidth: F.w, whiteSpace: 'nowrap',
            opacity: animate({ from: 0, to: 1, start: T.chip, end: T.chip + 0.4 })(t),
            transform: `translateY(${(1 - animate({ from: 0, to: 1, start: T.chip, end: T.chip + 0.4, ease: Easing.easeOutCubic })(t)) * 8}px)` }}>
            <svg width="16" height="16" viewBox="0 0 24 24" style={{ flex: 'none' }}><path d="M13 2 L4 14 H11 L10 22 L20 9 H13 Z" fill="#8a7940" /></svg>
            <span style={{ fontFamily: GROT_B, fontSize: 13, letterSpacing: '0.06em',
              textTransform: 'uppercase', color: '#8a7940', whiteSpace: 'nowrap' }}>
              Fields below filled automatically from the photo</span>
          </div>
        ) : null}

        {/* fields */}
        <div style={{ position: 'absolute', left: F.x - M.x, top: 138, width: F.w,
          display: 'flex', flexDirection: 'column', gap: 20 }}>
          <Field label="Brand *" value={merke} active={activeF(T.f1, 'Baume et Mercier')} done={merke.length === 16} caret={activeF(T.f1, 'Baume et Mercier')} flash={flashF(T.f1)} />
          <Field label="Model" value={modell} active={activeF(T.f2, 'Riviera')} done={modell.length === 7} caret={activeF(T.f2, 'Riviera')} flash={flashF(T.f2)} />
          <Field label="Serial number *" value={serie} active={activeF(T.f3, '66060', 12)} done={serie.length === 5} caret={activeF(T.f3, '66060', 12)} flash={flashF(T.f3)} />
          <Field label="Reference number" value={ref} active={activeF(T.f4, 'M0A10620', 14)} done={ref.length === 8} caret={activeF(T.f4, 'M0A10620', 14)} flash={flashF(T.f4)} />
        </div>

        {/* buttons */}
        <div style={{ position: 'absolute', right: 48, bottom: 44, display: 'flex', gap: 16 }}>
          <div style={{ fontFamily: GROT, fontSize: 20, color: INK, padding: '14px 28px',
            borderRadius: 12, border: `1px solid ${HAIR}`, background: '#fff' }}>Cancel</div>
          <div style={{ fontFamily: GROT, fontSize: 20, fontWeight: 700, padding: '14px 30px',
            borderRadius: 12,
            background: goldReady ? (t > T.click2 && t < T.click2 + 0.22 ? '#A8945C' : GULL) : 'rgba(28,24,13,0.12)',
            color: goldReady ? BRUN : 'rgba(28,24,13,0.4)',
            boxShadow: goldReady && t < T.click2 ? `0 0 0 ${4 + 3 * Math.sin((t - T.goldBtn) * 5)}px rgba(196,176,117,0.25)` : 'none' }}>
            Create</div>
        </div>
      </div>

      {/* done state */}
      {t >= T.doneIn ? (
        <div style={{ position: 'absolute', inset: 0, background: BRUN, display: 'flex', flexDirection: 'column',
          alignItems: 'center', justifyContent: 'center', gap: 26,
          opacity: animate({ from: 0, to: 1, start: T.doneIn, end: T.doneIn + 0.5 })(t) }}>
          <svg width="110" height="110" viewBox="0 0 110 110">
            <circle cx="55" cy="55" r="50" fill="none" stroke={GULL} strokeWidth="2.5"
              strokeDasharray={315}
              strokeDashoffset={315 * (1 - animate({ from: 0, to: 1, start: T.doneIn, end: T.doneIn + 0.7, ease: Easing.easeOutCubic })(t))}
              transform="rotate(-90 55 55)" />
            <path d="M36 57 L50 71 L76 43" fill="none" stroke={GULL_LYS} strokeWidth="4"
              strokeLinecap="round" strokeLinejoin="round"
              strokeDasharray={60}
              strokeDashoffset={60 * (1 - animate({ from: 0, to: 1, start: T.doneIn + 0.4, end: T.doneIn + 0.9, ease: Easing.easeOutCubic })(t))} />
          </svg>
          <div style={{ fontFamily: SERIF, fontSize: 52, color: '#EFEEE9', letterSpacing: '-0.01em' }}>
            Service order created</div>
          <div style={{ fontFamily: GROT_B, fontSize: 17, letterSpacing: '0.1em', textTransform: 'uppercase',
            color: GULL }}>Recognized and registered in seconds</div>
        </div>
      ) : null}

      {/* beam: dots flowing from photo to fields */}
      {beamActive ? (
        <svg style={{ position: 'absolute', left: Z.x + PH.w, top: DIAL.y - 6, width: F.x - (Z.x + PH.w), height: 12, overflow: 'visible' }}>
          {[0, 1, 2].map((i) => {
            const p = clamp(beamP * 1.6 - i * 0.22, 0, 1);
            if (p <= 0 || p >= 1) return null;
            const x = p * (F.x - (Z.x + PH.w));
            return <circle key={i} cx={x} cy={6} r={5} fill={GULL_LYS} opacity={Math.sin(p * Math.PI)} />;
          })}
        </svg>
      ) : null}

      {/* cursors + ripples */}
      <Cursor x={c1x} y={c1y} o={c1o} s={c1s} />
      <Cursor x={c2x} y={c2y} o={c2o} s={c2s} />
      <Ripple t={t} at={T.click1} x={btn1.x + 8} y={btn1.y + 6} />
      <Ripple t={t} at={T.click2} x={btn2.x + 6} y={btn2.y + 4} />
    </div>
  );
}

function CadranUploadAnimationEN() {
  return (
    <Stage width={1320} height={860} duration={12.5} background={BRUN} loop autoplay>
      <Sprite start={0} end={12.5}>
        <div style={{ position: 'absolute', left: -398, top: -165.4, width: 1920, height: 1080, transform: 'scale(1.1026)', transformOrigin: 'top left' }}>
          <SceneBody />
        </div>
      </Sprite>
    </Stage>
  );
}

window.CadranUploadAnimationEN = CadranUploadAnimationEN;
