/* 第2幕 — 商談資料作成 (Sales)
   提案をもとに、AIがスライドを1枚ずつ生成。3×2のスライドソーター上で、各サムネイルが
   プレースホルダ → レンダリング（シマー）→ 完成、と順に埋まる。カウンターが 0→6枚。
   DeckView({t}) は時間propのみ受け取る純View（連結用）。カーソルは生成ボタンを実DOM計測。 */

const { useState: useStateS2, useEffect: useEffectS2, useRef: useRefS2 } = React;

const S2_LOOP = 12.2;
const S2_clamp = (p) => Math.max(0, Math.min(1, p));
const S2_easeOut = (p) => 1 - Math.pow(1 - p, 3);
const S2_easeInOut = (p) => (p < 0.5 ? 4 * p * p * p : 1 - Math.pow(-2 * p + 2, 3) / 2);
function S2_center(el, flow) { if (!el || !flow) return null; let x = 0, y = 0, n = el; while (n && n !== flow) { x += n.offsetLeft; y += n.offsetTop; n = n.offsetParent; } return { x: x + el.offsetWidth / 2, y: y + el.offsetHeight / 2 }; }

const S2_SLIDES = ['表紙', '課題', 'ご提案', '期待効果', '概算・プラン', '次のステップ'];
const S2_GEN = 1.1;          // cursor clicks 生成
const S2_S0 = 1.6, S2_GAP = 1.45, S2_REN = 0.95;
const S2_start = (i) => S2_S0 + i * S2_GAP;
const S2_done = (i) => S2_start(i) + S2_REN;
const S2_DONEALL = S2_done(5) + 0.3;

injectCSS('animS2-css', `
.dk { position:relative; width:720px; height:720px; background:var(--paper); overflow:hidden;
  font-family:'Inter','Noto Sans JP',sans-serif; color:var(--ink); }
.dk, .dk * { box-sizing:border-box; }
.dk-top { position:absolute; left:44px; right:44px; top:42px; display:flex; align-items:flex-end; }
.dk-eye { font-family:'JetBrains Mono',monospace; font-size:10.5px; letter-spacing:.12em; color:var(--ink-3); text-transform:uppercase; display:flex; align-items:center; gap:8px; }
.dk-eye .dot { width:6px; height:6px; border-radius:50%; background:var(--blue); animation:s2-pulse 1.6s ease-in-out infinite; }
@keyframes s2-pulse { 0%,100%{opacity:1} 50%{opacity:.35} }
.dk-h1 { font-family:'Sora','Noto Sans JP',sans-serif; font-weight:600; font-size:27px; letter-spacing:-.01em; margin-top:8px; }
.dk-count { margin-left:auto; text-align:right; }
.dk-count .n { font-family:'JetBrains Mono',monospace; font-size:26px; font-weight:500; color:var(--ink); font-variant-numeric:tabular-nums; line-height:1; }
.dk-count .n b { color:var(--blue); }
.dk-count .l { font-family:'JetBrains Mono',monospace; font-size:9px; letter-spacing:.08em; color:var(--ink-3); text-transform:uppercase; margin-top:5px; }

.dk-grid { position:absolute; left:44px; right:44px; top:150px; display:grid; grid-template-columns:repeat(3,1fr); gap:18px 18px; }
.dk-item { display:flex; flex-direction:column; gap:9px; }
.dk-cell { position:relative; aspect-ratio:16/10; border-radius:11px; overflow:hidden; border:1px solid var(--line);
  background:var(--white); box-shadow:var(--shadow-sm); }
.dk-ph { position:absolute; inset:0; border:1.5px dashed var(--ink-300); border-radius:11px; display:flex; align-items:center; justify-content:center;
  background:var(--paper-2); transition:opacity .3s ease; }
.dk-ph .sp { width:20px; height:20px; border:2px solid var(--ink-300); border-top-color:var(--blue); border-radius:50%; animation:s2-spin .8s linear infinite; opacity:.0; }
.dk-ph .sp.go { opacity:1; }
@keyframes s2-spin { to { transform:rotate(360deg) } }
.dk-mini { position:absolute; inset:0; padding:11px 12px; display:flex; flex-direction:column; }
.dk-shim { position:absolute; inset:0; pointer-events:none; background:linear-gradient(100deg, transparent 30%, rgba(47,125,225,.18) 50%, transparent 70%);
  background-size:220% 100%; }
.dk-cap { display:flex; align-items:center; gap:7px; }
.dk-cap .pg { font-family:'JetBrains Mono',monospace; font-size:9.5px; color:var(--ink-3); letter-spacing:.05em; }
.dk-cap .nm { font-size:12px; font-weight:600; color:var(--ink-2); }
.dk-cap .ck { margin-left:auto; width:15px; height:15px; border-radius:50%; background:var(--ok); display:flex; align-items:center; justify-content:center; opacity:0; transform:scale(.5); transition:all .3s ease; }
.dk-cap .ck.in { opacity:1; transform:none; }

/* mini-slide internals */
.mn-bar { height:6px; border-radius:3px; background:var(--ink-300); }
.mn-head { height:8px; width:55%; border-radius:3px; background:var(--ink); margin-bottom:9px; }
.mn-cover { position:absolute; inset:0; background:var(--blue); display:flex; flex-direction:column; justify-content:center; padding:0 14px; gap:7px; }
.mn-cover .mk { width:20px; height:20px; border-radius:5px; background:rgba(255,255,255,.92); margin-bottom:4px; }
.mn-cover .l1 { height:7px; width:70%; border-radius:3px; background:#fff; }
.mn-cover .l2 { height:6px; width:45%; border-radius:3px; background:rgba(255,255,255,.6); }
.mn-lines { display:flex; flex-direction:column; gap:7px; }
.mn-blocks { display:flex; gap:6px; }
.mn-blocks .b { flex:1; height:26px; border-radius:5px; background:var(--blue-100); border:1px solid var(--blue-300); }
.mn-bars { display:flex; align-items:flex-end; gap:7px; height:34px; margin-top:auto; }
.mn-bars .b { flex:1; border-radius:3px 3px 0 0; background:var(--blue); }
.mn-bars .b.amb { background:var(--accent); }
.mn-rows { display:flex; flex-direction:column; gap:7px; }
.mn-rows .r { display:flex; align-items:center; gap:6px; }
.mn-rows .r .lab { height:6px; flex:1; border-radius:3px; background:var(--ink-300); }
.mn-rows .r .pr { height:6px; width:30%; border-radius:3px; background:var(--blue); }
.mn-rows .r .ck { width:12px; height:12px; border-radius:50%; border:1.5px solid var(--ok); flex:0 0 auto; }

.dk-foot { position:absolute; left:44px; right:44px; bottom:34px; display:flex; align-items:center; gap:10px;
  opacity:0; transform:translateY(6px); transition:opacity .4s ease, transform .4s ease; }
.dk-foot.in { opacity:1; transform:none; }
.dk-foot .c { width:26px; height:26px; border-radius:50%; background:rgba(43,163,122,.13); border:1.5px solid var(--ok); display:flex; align-items:center; justify-content:center; }
.dk-foot .tx { font-weight:600; font-size:14px; }
.dk-foot .tg { margin-left:auto; font-family:'JetBrains Mono',monospace; font-size:9px; letter-spacing:.1em; text-transform:uppercase; color:#fff; background:var(--blue); border-radius:999px; padding:5px 10px; }

.dk-cur { position:absolute; top:0; left:0; z-index:60; pointer-events:none; }
.dk-rip { position:absolute; width:42px; height:42px; margin:-21px 0 0 -21px; border-radius:50%; z-index:55; pointer-events:none;
  background:radial-gradient(circle, rgba(47,125,225,.4) 0%, rgba(47,125,225,0) 70%); }
.dk-genbtn { position:absolute; right:44px; top:150px; display:flex; align-items:center; gap:7px; background:var(--blue); color:#fff;
  border-radius:10px; padding:9px 15px; font-weight:600; font-size:13px; box-shadow:var(--shadow-sm); transition:background .15s, opacity .3s ease; }
`);

function MiniSlide({ type, p }) {
  const op = S2_clamp((p - 0.25) / 0.75);
  const st = { opacity: op };
  if (type === 0) return <div className="mn-cover" style={st}><div className="mk"></div><div className="l1"></div><div className="l2"></div></div>;
  return (
    <div className="dk-mini" style={st}>
      <div className="mn-head"></div>
      {type === 1 && <div className="mn-lines"><div className="mn-bar" style={{ width: '92%' }}></div><div className="mn-bar" style={{ width: '78%' }}></div><div className="mn-bar" style={{ width: '64%' }}></div></div>}
      {type === 2 && <div className="mn-blocks"><span className="b"></span><span className="b"></span><span className="b"></span></div>}
      {type === 3 && <div className="mn-bars"><span className="b" style={{ height: '45%' }}></span><span className="b" style={{ height: '62%' }}></span><span className="b amb" style={{ height: '95%' }}></span><span className="b" style={{ height: '70%' }}></span></div>}
      {type === 4 && <div className="mn-rows"><div className="r"><span className="lab"></span><span className="pr"></span></div><div className="r"><span className="lab"></span><span className="pr"></span></div><div className="r"><span className="lab"></span><span className="pr"></span></div></div>}
      {type === 5 && <div className="mn-rows"><div className="r"><span className="ck"></span><span className="lab"></span></div><div className="r"><span className="ck"></span><span className="lab"></span></div><div className="r"><span className="ck"></span><span className="lab"></span></div></div>}
    </div>
  );
}

function DeckView({ t }) {
  const flowRef = useRefS2(null);
  const [anchor, setAnchor] = useStateS2({ x: 575, y: 168 });
  useEffectS2(() => {
    const measure = () => { const f = flowRef.current; if (!f) return; const b = S2_center(f.querySelector('.dk-genbtn'), f); if (b) setAnchor(b); };
    measure(); const ids = [setTimeout(measure, 200), setTimeout(measure, 700)];
    window.addEventListener('resize', measure);
    return () => { ids.forEach(clearTimeout); window.removeEventListener('resize', measure); };
  }, []);

  const completed = S2_SLIDES.filter((_, i) => t >= S2_done(i)).length;
  const started = t >= S2_GEN;
  const press = t >= S2_GEN && t < S2_GEN + 0.18;
  const allDone = t > S2_DONEALL;

  // cursor: glide to 生成, click, then fade out
  function cursor() {
    if (t < 0.3) return { x: anchor.x - 90, y: anchor.y + 70, o: 0 };
    if (t < S2_GEN - 0.35) { const p = S2_easeInOut(S2_clamp((t - 0.3) / (S2_GEN - 0.65))); return { x: (anchor.x - 90) + 90 * p, y: (anchor.y + 70) - 70 * p, o: 1 }; }
    if (t < S2_GEN + 0.5) return { x: anchor.x, y: anchor.y, o: 1 };
    return { x: anchor.x, y: anchor.y + 24 * S2_clamp((t - (S2_GEN + 0.5)) / 0.5), o: S2_clamp(1 - (t - (S2_GEN + 0.5)) / 0.5) };
  }
  const cur = cursor();
  const ripple = (t >= S2_GEN && t < S2_GEN + 0.4) ? { x: anchor.x, y: anchor.y, s: 0.3 + S2_easeOut((t - S2_GEN) / 0.4), o: (1 - (t - S2_GEN) / 0.4) * 0.55 } : null;

  return (
    <div className="dk" ref={flowRef}>
      <div className="dk-top">
        <div>
          <div className="dk-eye"><span className="dot"></span>AI · スライド生成</div>
          <div className="dk-h1">商談資料</div>
        </div>
        <div className="dk-count"><div className="n"><b>{completed}</b> / 6</div><div className="l">枚 完成</div></div>
      </div>

      {!started && <div className={'dk-genbtn' + (press ? '' : '')} style={{ opacity: 1 }}><Sparkle size={14} color="#fff" />スライドを生成</div>}

      <div className="dk-grid">
        {S2_SLIDES.map((nm, i) => {
          const s = S2_start(i), d = S2_done(i);
          const p = S2_clamp((t - s) / S2_REN);            // render progress
          const rendering = t >= s && t < d;
          const idle = t < s;
          const done = t >= d;
          const shimPos = (1 - p) * 100;                   // sweep
          return (
            <div key={i} className="dk-item">
              <div className="dk-cell">
                {(idle || rendering) && p < 1 && (
                  <div className="dk-ph" style={{ opacity: idle ? 1 : S2_clamp(1 - p * 1.4) }}>
                    <span className={'sp' + (rendering ? ' go' : '')}></span>
                  </div>
                )}
                {(rendering || done) && <MiniSlide type={i} p={p} />}
                {rendering && <div className="dk-shim" style={{ backgroundPosition: shimPos + '% 0' }}></div>}
              </div>
              <div className="dk-cap">
                <span className="pg">{String(i + 1).padStart(2, '0')}</span>
                <span className="nm">{nm}</span>
                <span className={'ck' + (done ? ' in' : '')}><svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="3.4" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
              </div>
            </div>
          );
        })}
      </div>

      <div className={'dk-foot' + (allDone ? ' in' : '')}>
        <span className="c"><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="var(--ok)" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5"/></svg></span>
        <span className="tx">商談資料 6枚を作成しました</span>
        <span className="tg">プレビュー</span>
      </div>

      {ripple && <span className="dk-rip" style={{ left: ripple.x, top: ripple.y, transform: `scale(${ripple.s})`, opacity: ripple.o }}></span>}
      <span className="dk-cur" style={{ transform: `translate(${cur.x}px, ${cur.y}px) scale(${press ? 0.85 : 1})`, opacity: cur.o }}>
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" style={{ filter: 'drop-shadow(0 2px 4px rgba(14,27,44,.28))' }}>
          <path d="M5 2.5 L5 19 L9.2 14.8 L12 21 L14.4 20 L11.6 13.9 L17.5 13.9 Z" fill="#fff" stroke="#0E1B2C" strokeWidth="1.4" strokeLinejoin="round" />
        </svg>
      </span>
    </div>
  );
}

function Deck() {
  const [t, setT] = useStateS2(0);
  const startRef = useRefS2(null), frozenRef = useRefS2(null);
  useEffectS2(() => {
    let raf;
    const tick = (now) => {
      if (startRef.current == null) startRef.current = now;
      if (frozenRef.current == null) setT(((now - startRef.current) / 1000) % S2_LOOP);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    window.__seek = (v) => { frozenRef.current = v; setT(v); };
    window.__play = () => { frozenRef.current = null; startRef.current = performance.now(); };
    return () => cancelAnimationFrame(raf);
  }, []);
  if (typeof window !== 'undefined') window.__t = t;
  const op = t > S2_LOOP - 0.5 ? S2_clamp((S2_LOOP - t) / 0.5) : (t < 0.3 ? S2_clamp(t / 0.3) : 1);
  return <div style={{ opacity: op }}><DeckView t={t} /></div>;
}
window.Deck = Deck;
window.DeckView = DeckView;
