// ==========================================================================
// 0. Userflow — 操作流程圖（前台）
// 讀 page_data["u-diagrams"].tabs 為 JSON 結構，與後台編輯器同款資料
// 每個 node 可帶 image — 點下去跳彈窗看大圖
// ==========================================================================

// dot-aware orthogonal routing（與後台同款）
const ufFeDotAnchor = (n, dot) => {
  if (dot === "top")    return { x: n.x + n.w / 2, y: n.y };
  if (dot === "right")  return { x: n.x + n.w,     y: n.y + n.h / 2 };
  if (dot === "bottom") return { x: n.x + n.w / 2, y: n.y + n.h };
  return { x: n.x, y: n.y + n.h / 2 };
};
const ufFeDirOf = (dot) => {
  if (dot === "top")    return { x: 0,  y: -1 };
  if (dot === "right")  return { x: 1,  y: 0 };
  if (dot === "bottom") return { x: 0,  y: 1 };
  return { x: -1, y: 0 };
};
const ufFeSimplify = (pts) => {
  const out = [];
  for (const p of pts) {
    const last = out[out.length - 1];
    if (last && Math.abs(last.x - p.x) < 0.5 && Math.abs(last.y - p.y) < 0.5) continue;
    out.push(p);
  }
  return out;
};
const UF_FE_STRAIGHT_TOL = 12;
const ufFeRoute = (a, b, sd, td, bendOffset = 0) => {
  const sa = ufFeDotAnchor(a, sd), ta = ufFeDotAnchor(b, td);
  const sdir = ufFeDirOf(sd), tdir = ufFeDirOf(td);
  const srcHoriz = sdir.x !== 0, tgtHoriz = tdir.x !== 0;

  if (!bendOffset && srcHoriz && tgtHoriz && Math.abs(sa.y - ta.y) <= UF_FE_STRAIGHT_TOL) {
    const y = (sa.y + ta.y) / 2;
    return { d: `M ${sa.x} ${y} L ${ta.x} ${y}`, mid: { x: (sa.x + ta.x) / 2, y } };
  }
  if (!bendOffset && !srcHoriz && !tgtHoriz && Math.abs(sa.x - ta.x) <= UF_FE_STRAIGHT_TOL) {
    const x = (sa.x + ta.x) / 2;
    return { d: `M ${x} ${sa.y} L ${x} ${ta.y}`, mid: { x, y: (sa.y + ta.y) / 2 } };
  }

  const OFF = 22;
  const p1 = { x: sa.x + sdir.x * OFF, y: sa.y + sdir.y * OFF };
  const p2 = { x: ta.x + tdir.x * OFF, y: ta.y + tdir.y * OFF };
  let pts = [sa, p1];
  if (srcHoriz && tgtHoriz) {
    const midX = (p1.x + p2.x) / 2 + bendOffset;
    pts.push({ x: midX, y: p1.y }); pts.push({ x: midX, y: p2.y });
  } else if (!srcHoriz && !tgtHoriz) {
    const midY = (p1.y + p2.y) / 2 + bendOffset;
    pts.push({ x: p1.x, y: midY }); pts.push({ x: p2.x, y: midY });
  } else if (srcHoriz && !tgtHoriz) {
    pts.push({ x: p2.x, y: p1.y });
  } else {
    pts.push({ x: p1.x, y: p2.y });
  }
  pts.push(p2, ta);
  pts = ufFeSimplify(pts);
  const d = pts.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
  const mid = pts[Math.floor(pts.length / 2)];
  return { d, mid };
};
const ufFePath = (a, b, sourceDot, targetDot, bendOffset) => {
  if (!a || !b) return { d: "", mid: null };
  if (sourceDot && targetDot) return ufFeRoute(a, b, sourceDot, targetDot, bendOffset);
  const dx = (b.x + b.w/2) - (a.x + a.w/2);
  const dy = (b.y + b.h/2) - (a.y + a.h/2);
  let sd, td;
  if (Math.abs(dx) >= Math.abs(dy)) { sd = dx > 0 ? "right" : "left"; td = dx > 0 ? "left" : "right"; }
  else                              { sd = dy > 0 ? "bottom" : "top"; td = dy > 0 ? "top" : "bottom"; }
  return ufFeRoute(a, b, sd, td, bendOffset);
};

// 單個 node 渲染（前台用，沒有編輯能力）
const UfNode = ({ n, onClick }) => {
  const clickable = !!n.image;
  const base = {
    position: "absolute", left: n.x, top: n.y,
    width: n.w, height: n.h,
    display: "flex", alignItems: "center", justifyContent: "center",
    color: n.textColor || "#fff", fontSize: 13, fontWeight: 500,
    textAlign: "center", padding: 6, userSelect: "none",
    cursor: clickable ? "pointer" : "default",
    transition: "transform .15s, box-shadow .15s",
    boxShadow: "0 2px 6px rgba(0,0,0,.08)",
  };
  const shapeStyle = (() => {
    if (n.shape === "ellipse") return { ...base, background: n.fill, borderRadius: "50%" };
    if (n.shape === "round")   return { ...base, background: n.fill, borderRadius: 18 };
    if (n.shape === "diamond") return { ...base, background: "transparent", boxShadow: "none" };
    if (n.shape === "text")    return { ...base, background: "transparent", boxShadow: "none", color: n.textColor || "#111" };
    return { ...base, background: n.fill, borderRadius: 6 };
  })();
  return (
    <div style={shapeStyle}
      onClick={clickable ? () => onClick(n) : undefined}
      onMouseEnter={(e) => { if (clickable) e.currentTarget.style.transform = "scale(1.04)"; }}
      onMouseLeave={(e) => { if (clickable) e.currentTarget.style.transform = "scale(1)"; }}>
      {n.shape === "diamond" && (
        <svg style={{ position: "absolute", inset: 0, width: "100%", height: "100%" }}>
          <polygon points={`${n.w/2},2 ${n.w-2},${n.h/2} ${n.w/2},${n.h-2} 2,${n.h/2}`} fill={n.fill} />
        </svg>
      )}
      <span style={{ position: "relative", zIndex: 2, padding: "0 6px", lineHeight: 1.3 }}>
        {n.label}
      </span>
      {n.image && (() => {
        const pos = n.shape === "diamond" ? { right: "20%", top: "15%" }
                : n.shape === "ellipse"   ? { right: "12%", top: "15%" }
                : { right: 4, top: 4 };
        return (
          <span title="點此查看畫面" style={{
            position: "absolute", ...pos,
            minWidth: 22, height: 18, padding: "0 6px", borderRadius: 9,
            background: "#fff", color: "#16a34a",
            border: "1.5px solid #16a34a",
            fontSize: 11, fontWeight: 700,
            display: "flex", alignItems: "center", justifyContent: "center",
            boxShadow: "0 1px 3px rgba(0,0,0,.15)", zIndex: 3,
            letterSpacing: ".02em",
          }}>圖</span>
        );
      })()}
    </div>
  );
};

// 單個流程圖畫布（前台唯讀）
const UfCanvas = ({ tab, pan, zoom, onNodeClick }) => {
  const maxX = Math.max(600, ...tab.nodes.map(n => n.x + n.w + 40));
  const maxY = Math.max(440, ...tab.nodes.map(n => n.y + n.h + 40));
  return (
    <div style={{
      position: "absolute", inset: 0,
      width: maxX, height: maxY,
      transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
      transformOrigin: "top left",
    }}>
      <svg style={{ position: "absolute", inset: 0, width: "20000px", height: "20000px", pointerEvents: "none", overflow: "visible" }}>
        <defs>
          <marker id="uf-fe-arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="10" markerHeight="10" orient="auto-start-reverse">
            <path d="M 0 0 L 10 5 L 0 10 z" fill="#475569" />
          </marker>
        </defs>
        {tab.edges.map(e => {
          const a = tab.nodes.find(n => n.id === e.source);
          const b = tab.nodes.find(n => n.id === e.target);
          if (!a || !b) return null;
          const { d, mid } = ufFePath(a, b, e.sourceDot, e.targetDot, e.bendOffset || 0);
          return (
            <g key={e.id}>
              <path d={d} stroke="#475569" strokeWidth={1.6} fill="none" strokeLinejoin="round" markerEnd="url(#uf-fe-arrow)" />
              {e.label && mid && (() => {
                const w = Math.max(44, e.label.length * 9 + 14);
                return (
                  <g>
                    <rect x={mid.x - w/2} y={mid.y - 11} width={w} height={20} rx={4}
                      fill="#fff" stroke="var(--n-200)" />
                    <text x={mid.x} y={mid.y + 4} textAnchor="middle"
                      fontSize="11" fill="var(--n-800)">
                      {e.label}
                    </text>
                  </g>
                );
              })()}
            </g>
          );
        })}
      </svg>
      {tab.nodes.map(n => <UfNode key={n.id} n={n} onClick={onNodeClick} />)}
    </div>
  );
};

// 圖片彈窗
const UfImageModal = ({ image, onClose }) => {
  if (!image) return null;
  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, background: "rgba(0,0,0,.7)",
      display: "flex", alignItems: "center", justifyContent: "center",
      zIndex: 10000, padding: 24, animation: "uf-fade .15s ease",
    }}>
      <div onClick={(e) => e.stopPropagation()} style={{ position: "relative", maxWidth: "90vw", maxHeight: "90vh" }}>
        <img src={image.url} alt={image.name || ""} style={{
          maxWidth: "90vw", maxHeight: "90vh", display: "block",
          borderRadius: 8, boxShadow: "0 30px 80px rgba(0,0,0,.45)",
          background: "#fff",
        }} />
        <button onClick={onClose} style={{
          position: "absolute", top: -42, right: -10,
          width: 36, height: 36, borderRadius: "50%",
          background: "#fff", border: "none", cursor: "pointer",
          fontSize: 18, color: "#333",
          boxShadow: "0 4px 12px rgba(0,0,0,.3)",
        }}>×</button>
      </div>
    </div>
  );
};

// ---- 主 Card ----
const UserflowCard = () => {
  const tabs = window.dsBootData?.pageData?.["u-diagrams"]?.tabs || [];
  const intro = window.dsBootData?.pageContents?.["u-diagrams"]?.intro;
  const [tab, setTab] = React.useState(0);
  const [zoom, setZoom] = React.useState(1);
  const [pan, setPan] = React.useState({ x: 0, y: 0 });
  const [modalImg, setModalImg] = React.useState(null);
  const scrollerRef = React.useRef(null);
  const panStartRef = React.useRef(null);
  const [panning, setPanning] = React.useState(false);

  // 中鍵拖移畫布（transform-based pan，支援無限拖）
  const onScrollerMouseDown = (ev) => {
    if (ev.button !== 1) return;
    ev.preventDefault();
    panStartRef.current = { x: ev.clientX, y: ev.clientY, panX: pan.x, panY: pan.y };
    setPanning(true);
  };
  React.useEffect(() => {
    const onMove = (ev) => {
      if (!panStartRef.current) return;
      setPan({
        x: panStartRef.current.panX + (ev.clientX - panStartRef.current.x),
        y: panStartRef.current.panY + (ev.clientY - panStartRef.current.y),
      });
    };
    const onUp = () => { panStartRef.current = null; setPanning(false); };
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseup", onUp);
    return () => {
      window.removeEventListener("mousemove", onMove);
      window.removeEventListener("mouseup", onUp);
    };
  }, []);

  // tab 切換時重設 pan/zoom
  React.useEffect(() => { setPan({ x: 0, y: 0 }); setZoom(1); }, [tab]);

  // Ctrl + / − / 0 縮放
  React.useEffect(() => {
    const onKey = (ev) => {
      if (!(ev.ctrlKey || ev.metaKey)) return;
      if (ev.key === "=" || ev.key === "+") { ev.preventDefault(); setZoom(z => Math.min(2, +(z + 0.1).toFixed(2))); }
      else if (ev.key === "-") { ev.preventDefault(); setZoom(z => Math.max(0.4, +(z - 0.1).toFixed(2))); }
      else if (ev.key === "0") { ev.preventDefault(); setZoom(1); }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  // 空狀態
  if (tabs.length === 0) {
    return (
      <Card id="u-diagrams" title="Userflow Diagrams">
        <div style={{
          padding: "80px 24px", textAlign: "center",
          background: "var(--n-50)", border: "1px dashed var(--n-300)",
          borderRadius: 12, color: "var(--n-600)",
        }}>
          <div style={{ fontSize: 36, marginBottom: 8 }}>🧭</div>
          <div style={{ fontSize: 14, fontWeight: 600, color: "var(--n-700)", marginBottom: 6 }}>尚未建立任何操作流程圖</div>
          <div style={{ fontSize: 12.5, lineHeight: 1.7 }}>
            請至後台「頁面管理 → Userflow Diagrams」新增流程圖。
          </div>
        </div>
      </Card>
    );
  }

  const t = tabs[Math.min(tab, tabs.length - 1)];

  return (
    <Card id="u-diagrams" title="Userflow Diagrams">
      {intro && <p style={{ fontSize: 13, color: "var(--n-700)", lineHeight: 1.7, margin: "0 0 14px" }}>{intro}</p>}

      {/* Tabs */}
      <div style={{
        display: "flex", flexWrap: "wrap", gap: 0,
        borderBottom: "1px solid var(--n-200)", marginBottom: 16, marginTop: 4,
      }}>
        {tabs.map((it, i) => {
          const on = i === tab;
          const color = "#2492ff"; // 統一藍（不再用 it.color 各別色）
          return (
            <div key={it.id} onClick={() => setTab(i)} style={{
              padding: "10px 18px", cursor: "pointer", fontSize: 14,
              color: on ? "var(--n-900)" : "var(--n-600)",
              fontWeight: on ? 600 : 400,
              borderBottom: on ? "2px solid " + color : "2px solid transparent",
              marginBottom: -1,
              display: "flex", alignItems: "center", gap: 8,
              whiteSpace: "nowrap",
              transition: "all var(--dur-fast) var(--ease)",
            }}>
              <span style={{
                width: 10, height: 10, borderRadius: "50%",
                background: on ? color : "transparent",
                border: `2px solid ${color}`,
              }}/>
              {it.label || "未命名"}
            </div>
          );
        })}
      </div>

      {/* Desc */}
      {t.desc && (
        <p style={{ fontSize: 13, color: "var(--n-700)", lineHeight: 1.7, margin: "0 0 14px" }}>{t.desc}</p>
      )}

      {/* Canvas */}
      <div ref={scrollerRef}
        onMouseDown={onScrollerMouseDown}
        onContextMenu={(e) => e.preventDefault()}
        style={{
          position: "relative",
          background: "#fff",
          backgroundImage: "radial-gradient(circle, #e6e9ee 1px, transparent 1px)",
          backgroundSize: `${20 * zoom}px ${20 * zoom}px`,
          backgroundPosition: `${pan.x}px ${pan.y}px`,
          border: "1px solid var(--n-200)", borderRadius: 12,
          overflow: "hidden", height: 620,
          cursor: panning ? "grabbing" : "default",
        }}>
        {t.nodes.length === 0 ? (
          <div style={{
            padding: "80px 24px", textAlign: "center",
            color: "var(--n-500)", fontSize: 13,
          }}>
            這個流程還沒有任何節點。請至後台編輯。
          </div>
        ) : (
          <UfCanvas tab={t} pan={pan} zoom={zoom} onNodeClick={(n) => setModalImg(n.image)} />
        )}

        {/* Zoom controls */}
        <div style={{
          position: "absolute", right: 12, bottom: 12,
          display: "flex", flexDirection: "column", gap: 6, zIndex: 5,
        }}>
          <button onClick={() => setZoom(z => Math.min(2, +(z + 0.1).toFixed(2)))} style={ufZoomBtn}>+</button>
          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11, textAlign: "center", color: "var(--n-600)" }}>
            {Math.round(zoom * 100)}%
          </div>
          <button onClick={() => setZoom(z => Math.max(0.4, +(z - 0.1).toFixed(2)))} style={ufZoomBtn}>−</button>
          <button onClick={() => setZoom(1)} style={ufZoomBtn} title="重設縮放">⟲</button>
        </div>
      </div>

      <p style={{ fontSize: 11, color: "var(--n-500)", marginTop: 10 }}>
        綠色「圖」標記表示該節點綁了圖片 — 點它會彈窗看畫面。中鍵拖移畫布、Ctrl ± 縮放。
      </p>

      <UfImageModal image={modalImg} onClose={() => setModalImg(null)} />
    </Card>
  );
};

const ufZoomBtn = {
  width: 30, height: 30, borderRadius: 6,
  border: "1px solid var(--n-200)", background: "#fff",
  cursor: "pointer", fontSize: 14, color: "var(--n-700)",
  display: "flex", alignItems: "center", justifyContent: "center",
  fontFamily: "inherit", padding: 0,
  boxShadow: "0 1px 3px rgba(0,0,0,.06)",
};

const UserflowSection = () => (
  <Section id="userflow" num="0" zh="Userflow 操作流程圖" en="Userflow · User Journeys">
    <UserflowCard />
  </Section>
);

window.UserflowSection = UserflowSection;
