/* =========================================================
   Fusion AI 데모 — 앱 (업로드 → AI CAM 연산 → 결과)
   requires: demo-parts.jsx (PARTS, CamViewport)
   ========================================================= */
const { useState, useRef, useCallback } = React;
const SAMPLE_KEYS = ["bracket", "housing", "core"];

function Icon({ d, w = 24 }) {
  return <svg viewBox="0 0 24 24" width={w} height={w} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">{d}</svg>;
}
const fmtThousand = (n) => n.toLocaleString("en-US");

function App() {
  const theme = (typeof document !== "undefined" && document.body && document.body.dataset.theme === "light") ? "light" : "dark";
  const logoSrc = theme === "light" ? "assets/logo.svg" : "assets/logo-light.svg";
  const [phase, setPhase] = useState("empty"); // empty | ready | computing | done
  const [part, setPart] = useState(null);
  const [drag, setDrag] = useState(false);
  const [material, setMaterial] = useState("");
  const [toolset, setToolset] = useState("std");

  const [progress, setProgress] = useState(0);
  const [stage, setStage] = useState("");
  const [logs, setLogs] = useState([]);
  const [drawnCount, setDrawnCount] = useState(0);
  const [activeIndex, setActiveIndex] = useState(null);
  const [activeDur, setActiveDur] = useState(700);

  const [tab, setTab] = useState("ops");
  const [highlightOp, setHighlightOp] = useState(null);
  const [toast, setToast] = useState("");
  const runId = useRef(0);
  const fileInput = useRef(null);

  const loadPart = (p, fileName) => {
    runId.current++;
    const next = fileName ? { ...p, file: fileName, name: fileName.replace(/\.[^.]+$/, "") } : p;
    setPart(next); setMaterial(next.material); setPhase("ready");
    setProgress(0); setLogs([]); setDrawnCount(0); setActiveIndex(null); setHighlightOp(null); setTab("ops");
  };

  const onFiles = (files) => {
    if (!files || !files.length) return;
    loadPart(PARTS.bracket, files[0].name); // 데모: 업로드 형상은 샘플 지오메트리로 시뮬레이션
  };

  const showToast = (msg) => { setToast(msg); setTimeout(() => setToast(""), 2400); };

  const sleep = (ms, id) => new Promise((res) => setTimeout(() => { if (id === runId.current) res(true); else res(false); }, ms));

  const runCompute = useCallback(async () => {
    if (!part) return;
    const id = ++runId.current;
    setPhase("computing"); setProgress(0); setLogs([]); setDrawnCount(0); setActiveIndex(null); setHighlightOp(null);

    const pre = [
      { stage: "형상 분석", log: <span><span className="ac">[geom]</span> STEP 파싱 · 곡면 {part.faces}개 로드</span>, dur: 480 },
      { stage: "특징 인식", log: <span><span className="ac">[ai]</span> 특징 인식 — {part.features}</span>, dur: 620 },
      { stage: "공구 선정", log: <span><span className="ac">[cam]</span> 공구 라이브러리 매칭 · {part.tools.length}개 선정</span>, dur: 520 },
      { stage: "절삭조건 추론", log: <span><span className="ac">[ai]</span> 절삭조건 추론 · 현장 데이터 3,000+ 참조</span>, dur: 600 },
    ];
    const opSteps = part.operations.map((op, i) => ({
      stage: "툴패스 생성", drawIndex: i, dur: 620 + (op.strat.includes("Adaptive") || op.strat.includes("Scallop") ? 360 : 120),
      log: <span><span className="ac">[path]</span> {op.name} · {op.tool} <span style={{ color: "#6E7178" }}>({op.strat})</span></span>,
    }));
    const post = [{ stage: "검증 · 포스트", log: <span><span className="ok">[ok]</span> 과절삭·간섭 검증 통과 · NC 생성 준비</span>, dur: 460 }];
    const steps = [...pre, ...opSteps, ...post];
    const total = steps.reduce((a, s) => a + s.dur, 0);

    let elapsed = 0;
    for (let k = 0; k < steps.length; k++) {
      const st = steps[k];
      if (id !== runId.current) return;
      setStage(st.stage);
      setLogs((L) => [...L, { id: k, node: st.log }].slice(-4));
      if (st.drawIndex != null) { setActiveDur(st.dur); setActiveIndex(st.drawIndex); }
      else setActiveIndex(null);
      // smooth progress across this step
      const startP = (elapsed / total) * 100;
      elapsed += st.dur;
      const endP = (elapsed / total) * 100;
      const t0 = performance.now();
      // animate progress
      await new Promise((res) => {
        const frame = (now) => {
          const t = Math.min(1, (now - t0) / st.dur);
          setProgress(startP + (endP - startP) * t);
          if (t < 1 && id === runId.current) requestAnimationFrame(frame); else res();
        };
        requestAnimationFrame(frame);
      });
      if (id !== runId.current) return;
      if (st.drawIndex != null) { setDrawnCount(st.drawIndex + 1); setActiveIndex(null); }
    }
    if (id !== runId.current) return;
    setProgress(100); setActiveIndex(null); setDrawnCount(part.operations.length);
    setPhase("done"); setTab("ops");
  }, [part]);

  const reset = () => { runId.current++; setPhase("empty"); setPart(null); setProgress(0); setLogs([]); setDrawnCount(0); setActiveIndex(null); };

  /* ----------------------- render ----------------------- */
  return (
    <React.Fragment>
      {/* TOP BAR */}
      <div className="app-top">
        <a className="brand" href="index.html" aria-label="홈">
          <img src={logoSrc} alt="Fusion Industry" />
          <span className="tagpill">Web Demo</span>
        </a>
        <div className="crumbs">
          <span>Fusion AI</span><span>/</span>
          <b>{part ? part.name : "형상 업로드"}</b>
        </div>
        <div className="top-right">
          <a className="t-link" href="index.html#start">정식 제품 →</a>
          <a className="btn-support" href="support.html" target="_blank" rel="noopener">
            <span className="dotg"></span> 원격 기술지원
          </a>
        </div>
      </div>

      {/* BODY */}
      <div className="app-body">
        {/* VIEWPORT */}
        <div className={"viewport" + (drag ? " drag" : "")}
          onDragOver={(e) => { e.preventDefault(); if (phase === "empty") setDrag(true); }}
          onDragLeave={() => setDrag(false)}
          onDrop={(e) => { e.preventDefault(); setDrag(false); if (phase === "empty") onFiles(e.dataTransfer.files); }}>
          <div className="vp-grid"></div>
          <div className="vp-stage">
            <CamViewport part={part} phase={phase} drawnCount={drawnCount} activeIndex={activeIndex} activeDur={activeDur} highlightOp={highlightOp} theme={theme} />
          </div>

          {/* HUD */}
          {part && (
            <div className="vp-hud">
              <div className="vp-readout">
                <div><span className="k">PART</span> {part.file}</div>
                <div><span className="k">MAT</span> {material}</div>
                <div><span className="k">VIEW</span> ISO · <span className="ac">{phase === "done" ? "TOOLPATH" : phase === "computing" ? "COMPUTING" : "STOCK"}</span></div>
              </div>
              <div className="vp-cube">
                <div className="vc on">ISO</div>
                <div className="vc">TOP</div>
                <div className="vc">FRT</div>
              </div>
              <div className="vp-scalebar"><span>{Math.round(part.plate.w / 4)} mm</span><span className="bar"></span></div>
            </div>
          )}

          {/* DROPZONE (empty) */}
          {phase === "empty" && (
            <div className={"dropzone" + (drag ? " drag" : "")}>
              <div className="dz-card">
                <div className="dz-ico"><Icon d={<><path d="M12 16V4" /><path d="M7 9l5-5 5 5" /><path d="M4 16v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2" /></>} /></div>
                <div className="dz-title">형상 파일을 올려보세요</div>
                <div className="dz-sub">소형 CAM 엔진 + Fusion AI 가 웹에서 바로<br />툴패스와 절삭조건을 생성합니다.</div>
                <div className="dz-formats">STEP · IGES · STL · X_T · SLDPRT</div>
                <button className="sample-chip" style={{ marginTop: 20 }} onClick={() => fileInput.current && fileInput.current.click()}>
                  <Icon w={16} d={<><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><path d="M7 10l5 5 5-5" /><path d="M12 15V3" /></>} /> 내 컴퓨터에서 선택
                </button>
                <input ref={fileInput} type="file" hidden onChange={(e) => onFiles(e.target.files)} accept=".step,.stp,.iges,.igs,.stl,.x_t,.sldprt" />
                <div className="dz-or">또는 샘플 형상으로 체험</div>
                <div className="dz-samples">
                  {SAMPLE_KEYS.map((k) => (
                    <button key={k} className="sample-chip" onClick={() => loadPart(PARTS[k])}>
                      <span className="sw" style={{ background: PARTS[k].color }}></span>{PARTS[k].name}
                    </button>
                  ))}
                </div>
              </div>
            </div>
          )}

          {/* COMPUTE BAR */}
          {phase === "computing" && (
            <div className="compute-bar">
              <div className="cb-inner">
                <div className="cb-head">
                  <div className="cb-stage"><span className="cb-spin"></span>{stage}</div>
                  <div className="cb-pct">{Math.round(progress)}%</div>
                </div>
                <div className="cb-track"><div className="cb-fill" style={{ width: progress + "%" }}></div></div>
                <div className="cb-log">
                  {logs.map((l) => <div className="ln" key={l.id}>{l.node}</div>)}
                </div>
              </div>
            </div>
          )}
        </div>

        {/* RIGHT PANEL */}
        <div className="panel">
          {phase === "empty" && (
            <div className="panel-empty">
              <div className="pe-ico"><Icon d={<><rect x="3" y="3" width="18" height="18" rx="2" /><path d="M3 9h18M9 21V9" /></>} /></div>
              <div className="pe-t">결과가 여기에 표시됩니다</div>
              <div className="pe-s">형상을 업로드하면 분석 정보와 가공 설정이 나타납니다.</div>
            </div>
          )}

          {(phase === "ready" || phase === "computing") && part && (
            <React.Fragment>
              <div className="panel-scroll">
                <div className="p-sec">
                  <div className="p-sec-t">형상 정보</div>
                  <div className="p-file">
                    <div className="pf-ico"><Icon w={20} d={<><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><path d="M14 2v6h6" /></>} /></div>
                    <div>
                      <div className="pf-name">{part.file}</div>
                      <div className="pf-meta">{part.features}</div>
                    </div>
                  </div>
                  <div className="specrows" style={{ marginTop: 16 }}>
                    <div className="specrow"><span className="k">소재</span><span className="v">{material}</span></div>
                    <div className="specrow"><span className="k">형상 크기</span><span className="v">{part.size}</span></div>
                    <div className="specrow"><span className="k">스톡</span><span className="v">{part.stock}</span></div>
                    <div className="specrow"><span className="k">곡면 수</span><span className="v">{part.faces}</span></div>
                  </div>
                </div>

                <div className="p-sec">
                  <div className="p-sec-t">가공 설정</div>
                  <div className="field">
                    <label>소재</label>
                    <select className="selectbox" value={material} onChange={(e) => setMaterial(e.target.value)} disabled={phase === "computing"}>
                      <option>{part.material}</option>
                      <option>AL 7075-T6</option><option>SCM440</option><option>SUS304</option><option>Ti-6Al-4V</option>
                    </select>
                  </div>
                  <div className="field">
                    <label>가공 방식</label>
                    <div className="seg">
                      <button className="on">3축</button>
                      <button disabled style={{ opacity: .5, cursor: "not-allowed" }}>5축 (베타)</button>
                    </div>
                  </div>
                  <div className="field">
                    <label>공구 세트</label>
                    <div className="seg">
                      <button className={toolset === "std" ? "on" : ""} onClick={() => phase !== "computing" && setToolset("std")}>표준</button>
                      <button className={toolset === "hs" ? "on" : ""} onClick={() => phase !== "computing" && setToolset("hs")}>고속 가공</button>
                    </div>
                  </div>
                </div>
              </div>
              <div className="panel-foot">
                <button className="btn-run" disabled={phase === "computing"} onClick={runCompute}>
                  {phase === "computing"
                    ? <><span className="cb-spin"></span> AI CAM 연산 중…</>
                    : <><Icon w={20} d={<><path d="M5 3l14 9-14 9V3z" /></>} /> AI CAM 연산 시작</>}
                </button>
                <button className="btn-sec2" onClick={reset} disabled={phase === "computing"}>다른 형상 업로드</button>
              </div>
            </React.Fragment>
          )}

          {phase === "done" && part && (
            <React.Fragment>
              <div className="panel-scroll">
                {/* summary */}
                <div className="p-sec">
                  <div className="res-summary">
                    <div className="res-cell big">
                      <div className="rc-k">예상 절삭 시간</div>
                      <div className="rc-v">{part.summary.total}<span className="u"> min</span></div>
                    </div>
                    <div className="res-cell"><div className="rc-k">공정</div><div className="rc-v">{part.summary.ops}</div></div>
                    <div className="res-cell"><div className="rc-k">공구</div><div className="rc-v">{part.summary.tools}</div></div>
                    <div className="res-cell"><div className="rc-k">소재 제거율</div><div className="rc-v">{part.summary.removed}</div></div>
                    <div className="res-cell"><div className="rc-k">소재</div><div className="rc-v" style={{ fontSize: 15 }}>{material}</div></div>
                  </div>
                </div>

                {/* tabs */}
                <div className="tabs">
                  <button className={tab === "ops" ? "on" : ""} onClick={() => setTab("ops")}>툴패스</button>
                  <button className={tab === "tools" ? "on" : ""} onClick={() => setTab("tools")}>공구</button>
                  <button className={tab === "cond" ? "on" : ""} onClick={() => setTab("cond")}>절삭조건</button>
                </div>

                {tab === "ops" && (
                  <div className="oplist">
                    {part.operations.map((op, i) => (
                      <div key={i} className={"op" + (highlightOp === i ? " on" : "")}
                        onMouseEnter={() => setHighlightOp(i)} onMouseLeave={() => setHighlightOp(null)}
                        onClick={() => setHighlightOp(highlightOp === i ? null : i)}>
                        <div className="op-n">{i + 1}</div>
                        <div>
                          <div className="op-name">{op.name}</div>
                          <div className="op-sub">
                            <span className="sw"><span className="dot" style={{ background: op.color }}></span>{op.strat}</span>
                            <span>{op.tool}</span>
                          </div>
                        </div>
                        <div className="op-time">{op.time}<small>분:초</small></div>
                      </div>
                    ))}
                  </div>
                )}

                {tab === "tools" && (
                  <div className="toollist">
                    {part.tools.map((t) => (
                      <div key={t.id} className="tool">
                        <div className="tl-ico"><Icon w={22} d={<><path d="M12 2v7" /><path d="M9 9h6l-1 11h-4z" /><path d="M9 9l-2-3M15 9l2-3" /></>} /></div>
                        <div>
                          <div className="tl-id">{t.id}</div>
                          <div className="tl-name">{t.type} {t.dia}</div>
                          <div className="tl-meta">{t.flutes}날 · {t.mat}</div>
                        </div>
                        <div className="tl-sf">
                          <div><span className="k">S</span> {fmtThousand(t.S)}</div>
                          <div><span className="k">F</span> {fmtThousand(t.F)}</div>
                        </div>
                      </div>
                    ))}
                  </div>
                )}

                {tab === "cond" && (
                  <div className="condlist">
                    {part.operations.map((op, i) => (
                      <div key={i} className="cond">
                        <div className="cond-h"><span className="cn">{op.name}</span><span className="ct">{op.tool} · {op.strat}</span></div>
                        <div className="cond-grid">
                          <div className="cg"><div className="cgk">RPM (S)</div><div className="cgv">{fmtThousand(op.S)}</div></div>
                          <div className="cg"><div className="cgk">Feed (F)</div><div className="cgv">{fmtThousand(op.F)}</div></div>
                          <div className="cg"><div className="cgk">절입 ap</div><div className="cgv">{op.ap}{op.ap !== "—" ? " mm" : ""}</div></div>
                          <div className="cg"><div className="cgk">폭 ae</div><div className="cgv">{op.ae}{op.ae !== "—" ? " mm" : ""}</div></div>
                        </div>
                      </div>
                    ))}
                  </div>
                )}

                <div className="note-demo">데모 결과는 샘플 형상 기준의 예시값입니다. 실제 가공값은 정식 Fusion AI에서 장비·공구·소재 조건에 따라 산출됩니다.</div>
              </div>

              <div className="res-foot">
                <button className="btn-x x-ghost" onClick={() => showToast("리포트 PDF를 생성했습니다 (데모)")}><Icon w={18} d={<><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><path d="M14 2v6h6" /></>} /> 리포트</button>
                <button className="btn-x x-primary" onClick={() => showToast("NC 파일을 내보냈습니다 (데모)")}><Icon w={18} d={<><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><path d="M7 10l5 5 5-5" /><path d="M12 15V3" /></>} /> NC 내보내기</button>
              </div>
            </React.Fragment>
          )}
        </div>
      </div>

      <div className={"toast" + (toast ? " show" : "")}><span className="tk">✓</span>{toast}</div>
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById("app")).render(<App />);
