#!/usr/bin/env bash
# install-bumbee-dsh.sh
# Cai dat Bumbee Session Hub vao DeepSeek Harness (DSH) tren macOS/Linux.
# Tu chua toan bo: chi can file .sh nay, khong can mang theo file nao khac.
#
# Yeu cau truoc khi chay:
#   - Node.js da cai (kiem tra: node -v)
#   - May nay da noi Tailscale toi server-google-vscode (100.101.26.30)
#     vi Session Hub lay du lieu that tu do (khong co Tailscale se khong
#     thay du lieu, nhung DSH van dung binh thuong).
#
# Chay:
#   chmod +x install-bumbee-dsh.sh && ./install-bumbee-dsh.sh

set -euo pipefail

echo "== Bumbee Session Hub installer cho DeepSeek Harness =="

if ! command -v node >/dev/null 2>&1; then
  echo "Khong tim thay Node.js. Cai Node.js (https://nodejs.org) roi chay lai script nay."
  exit 1
fi
echo "Node.js: $(node -v)"

DSH_HOME_DIR="${DSH_HOME:-$HOME/.dsh}"
PLUGIN_DIR="$DSH_HOME_DIR/session-hub-panel-plugin"
PROFILE_DIR="$DSH_HOME_DIR/profiles/web"
PROFILE_NODE_MODULES="$DSH_HOME_DIR/profiles/node_modules"
LINK_PATH="$PROFILE_NODE_MODULES/bumbee-dsh-session-hub-panel"
PATCH_FILE="$PROFILE_DIR/cordis.patch.yml"

# ---------------------------------------------------------------------------
# 1. Khoi tao DSH profile "web" mac dinh (bootstrap lan dau neu chua co)
# ---------------------------------------------------------------------------
if [ ! -d "$PROFILE_DIR" ]; then
  echo "Khoi tao DSH lan dau (tai ve neu can)..."
  npx --yes @deepseek-ai/dsh --profile web --dump-config >/dev/null
fi

if [ ! -d "$PROFILE_DIR" ]; then
  echo "Khong the khoi tao profile 'web' cua DSH. Chay 'npx @deepseek-ai/dsh web' thu cong 1 lan roi chay lai script nay."
  exit 1
fi

# ---------------------------------------------------------------------------
# 2. Ghi plugin files
# ---------------------------------------------------------------------------
echo "Ghi plugin vao $PLUGIN_DIR ..."
mkdir -p "$PLUGIN_DIR"

cat > "$PLUGIN_DIR/package.json" << 'EOF'
{
  "name": "bumbee-dsh-session-hub-panel",
  "private": true,
  "version": "0.1.0",
  "type": "module",
  "main": "index.js",
  "exports": {
    ".": "./index.js",
    "./client": "./client.js",
    "./package.json": "./package.json"
  },
  "dsh": {
    "client": {
      "platform": "web"
    }
  }
}
EOF

cat > "$PLUGIN_DIR/index.js" << 'EOF'
// Host half: no server-side behavior needed, the panel is a pure browser
// iframe over the already-live Session Hub API (server-google-vscode:8421).
export function apply() {}
EOF

cat > "$PLUGIN_DIR/client.js" << 'EOF'
// Client half, DSH's own __ModuleLoader__ factory format.
//
// FINAL: the approved Session Hub UI (tabs, real session tree, Keep Note)
// IS the home screen -- shown immediately on every load, exactly as
// approved. Two more real entry points into it: the sidebar wordmark
// ("Bumbee" logo) and the empty-state hero ("Into the Bumbee Anything")
// both open it now too, not just the sidebar nav icon.
window.__ModuleLoader__.load({
	id: "bumbee-dsh-session-hub-panel",
	factory: (require) => {
		var module = { exports: {} };
		var exports = module.exports;
		Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });

		let react = require("react");
		let react_jsx_runtime = require("react/jsx-runtime");

		const SESSION_HUB_URL = "http://100.101.26.30:8421/";

		const REBRAND_CSS = `
			[class*="_brand"] svg { visibility: hidden; }
			[class*="_brand"] { position: relative; cursor: pointer; }
			[class*="_brand"]::after {
				content: "${"\u{1F41D}"} Bumbee";
				position: absolute;
				inset: 0;
				display: flex;
				align-items: center;
				gap: 6px;
				font-size: 15px;
				font-weight: 700;
				letter-spacing: 0.01em;
				color: inherit;
				pointer-events: none;
				white-space: nowrap;
			}
			[class*="_railFish"] { visibility: hidden; position: relative; }
			[class*="_railFish"]::after {
				content: "${"\u{1F41D}"}";
				visibility: visible;
				position: absolute;
				inset: 0;
				display: flex;
				align-items: center;
				justify-content: center;
				font-size: 16px;
				line-height: 1;
			}
			[class*="_headline"] { cursor: pointer; }
			[class*="_headlineText"] { visibility: hidden; position: relative; }
			[class*="_headlineText"]::after {
				content: "Into the Bumbee Anything";
				visibility: visible;
				position: absolute;
				inset: 0;
				white-space: nowrap;
			}
		`;

		function injectRebrandCss() {
			if (document.getElementById("bumbee-rebrand-style")) return;
			const style = document.createElement("style");
			style.id = "bumbee-rebrand-style";
			style.textContent = REBRAND_CSS;
			document.head.appendChild(style);
		}

		// The brand button and the empty-state hero are native DSH elements
		// (owned by dsh-client-ui-sidebar / dsh-client-ui-conversation), not
		// something this plugin renders -- so opening Bumbee Studio from them
		// means attaching real click listeners to the live DOM nodes once they
		// exist, and re-attaching whenever DSH re-renders them (session
		// switches etc. can replace the nodes). A WeakSet marks nodes already
		// wired so a MutationObserver churn never double-binds a listener.
		function wireOpenStudioTriggers() {
			const wired = new WeakSet();
			const openStudio = (event) => {
				event.preventDefault();
				event.stopPropagation();
				window.dispatchEvent(new CustomEvent("bumbee:open-studio"));
			};
			const attach = () => {
				document.querySelectorAll('[class*="_brand"], [class*="_headline"]').forEach((el) => {
					if (wired.has(el)) return;
					wired.add(el);
					el.addEventListener("click", openStudio, true);
				});
			};
			attach();
			const observer = new MutationObserver(attach);
			observer.observe(document.body, { childList: true, subtree: true });
		}

		function SessionHubHome({ wide }) {
			// Home screen: open by default, every fresh load.
			const [open, setOpen] = react.useState(true);

			react.useEffect(() => {
				// The approved UI's iframe posts "bumbee:go-to-chat" (a real button
				// inside it) when the user wants the actual DeepSeek Harness chat
				// underneath.
				const onMessage = (event) => {
					if (event.data === "bumbee:go-to-chat") setOpen(false);
				};
				// The rebranded sidebar logo and the rebranded empty-state hero
				// both dispatch this to reopen Bumbee Studio.
				const onOpenStudio = () => setOpen(true);

				window.addEventListener("message", onMessage);
				window.addEventListener("bumbee:open-studio", onOpenStudio);
				return () => {
					window.removeEventListener("message", onMessage);
					window.removeEventListener("bumbee:open-studio", onOpenStudio);
				};
			}, []);

			return react_jsx_runtime.jsxs(react_jsx_runtime.Fragment, {
				children: [
					react_jsx_runtime.jsxs("button", {
						type: "button",
						onClick: () => setOpen(true),
						title: "Bumbee Session Hub",
						style: {
							display: "flex",
							alignItems: "center",
							gap: 8,
							width: "100%",
							padding: wide ? "8px 10px" : "8px 0",
							justifyContent: wide ? "flex-start" : "center",
							border: "none",
							background: "transparent",
							borderRadius: 8,
							cursor: "pointer",
							color: "inherit",
							font: "inherit",
						},
						children: [
							react_jsx_runtime.jsx("span", { style: { fontSize: 16, lineHeight: 1 }, children: "\u{1F41D}" }),
							wide && react_jsx_runtime.jsx("span", { style: { fontSize: 13 }, children: "Session Hub" }),
						],
					}),
					// Mounted once, stays mounted: reopening after closing is instant,
					// no reload.
					react_jsx_runtime.jsxs("div", {
						role: "dialog",
						"aria-modal": "true",
						"aria-label": "Bumbee Session Hub",
						style: {
							position: "fixed",
							inset: 0,
							zIndex: 10000,
							display: open ? "flex" : "none",
							flexDirection: "column",
							background: "#0b0b0c",
						},
						children: [
							react_jsx_runtime.jsxs("div", {
								style: {
									display: "flex",
									alignItems: "center",
									justifyContent: "space-between",
									padding: "10px 16px",
									borderBottom: "1px solid rgba(127,127,127,0.2)",
									flex: "0 0 auto",
								},
								children: [
									react_jsx_runtime.jsxs("div", {
										style: { display: "flex", alignItems: "center", gap: 8, color: "#eee", fontSize: 14, fontWeight: 600 },
										children: [
											react_jsx_runtime.jsx("span", { children: "\u{1F41D}" }),
											react_jsx_runtime.jsx("span", { children: "Bumbee Session Hub" }),
										],
									}),
									react_jsx_runtime.jsx("button", {
										type: "button",
										onClick: () => setOpen(false),
										"aria-label": "Close",
										title: "Ve man hinh chat DeepSeek Harness",
										style: {
											border: "none",
											background: "rgba(255,255,255,0.08)",
											color: "#eee",
											width: 30,
											height: 30,
											borderRadius: 8,
											cursor: "pointer",
											fontSize: 16,
										},
										children: "\u{2715}",
									}),
								],
							}),
							react_jsx_runtime.jsx("div", {
								style: { flex: "1 1 auto", minHeight: 0 },
								children: react_jsx_runtime.jsx("iframe", {
									src: SESSION_HUB_URL,
									title: "Bumbee Session Hub",
									style: { width: "100%", height: "100%", border: "none" },
								}),
							}),
						],
					}),
				],
			});
		}

		function apply(ctx) {
			injectRebrandCss();
			wireOpenStudioTriggers();
			ctx.slots.inject("sidebar.footer.action", () =>
				ctx.slots.register(
					{
						name: "sidebar.footer.action",
						id: "bumbee-session-hub-nav",
					},
					SessionHubHome
				)
			);
		}

		exports.apply = apply;
		exports.inject = ["slots"];
		return module.exports;
	},
});
EOF

# ---------------------------------------------------------------------------
# 3. Symlink that (Unix ln -s la symlink that, khong dinh loi "gia" nhu
#    tren Windows Git Bash) de Node resolve duoc goi
#    "bumbee-dsh-session-hub-panel" tu profile.
# ---------------------------------------------------------------------------
mkdir -p "$PROFILE_NODE_MODULES"
rm -rf "$LINK_PATH"
ln -s "$PLUGIN_DIR" "$LINK_PATH"
echo "Da tao symlink: $LINK_PATH -> $PLUGIN_DIR"

# ---------------------------------------------------------------------------
# 4. Ghi vao cordis.patch.yml (backup truoc, khong ghi de neu da co san)
# ---------------------------------------------------------------------------
INSERT_BLOCK='- insert:
    - id: bumbee-session-hub-panel
      name: bumbee-dsh-session-hub-panel'

if [ -f "$PATCH_FILE" ]; then
  if grep -q "bumbee-dsh-session-hub-panel" "$PATCH_FILE"; then
    echo "cordis.patch.yml da co Bumbee Session Hub roi, bo qua."
  else
    BACKUP="$PATCH_FILE.bak-$(date +%Y%m%d%H%M%S)"
    cp "$PATCH_FILE" "$BACKUP"
    echo "Da backup file goc: $BACKUP"

    # File mac dinh cua DSH la comment + mot dong "[]" duy nhat la noi dung
    # YAML that su (mang rong). Chi khi tim thay dong do moi thay the no --
    # con lai (file da co insert/id khac) thi append vao cuoi, khong bao gio
    # vua giu "[]" vua them insert ben duoi (2 gia tri YAML top-level se loi
    # parse).
    if grep -qE '^\[\]\s*$' "$PATCH_FILE"; then
      awk -v block="$INSERT_BLOCK" '{
        if ($0 ~ /^\[\]\s*$/) { print block } else { print }
      }' "$PATCH_FILE" > "$PATCH_FILE.tmp"
      mv "$PATCH_FILE.tmp" "$PATCH_FILE"
    else
      printf '\n%s\n' "$INSERT_BLOCK" >> "$PATCH_FILE"
    fi
    echo "Da them Bumbee Session Hub vao cordis.patch.yml"
  fi
else
  printf '%s\n' "$INSERT_BLOCK" > "$PATCH_FILE"
  echo "Da tao cordis.patch.yml voi Bumbee Session Hub"
fi

# ---------------------------------------------------------------------------
# 5. Kiem tra file co compose duoc khong (khong boot that, chi dump-config)
# ---------------------------------------------------------------------------
echo "Kiem tra cau hinh..."
DUMP_OUTPUT="$(npx --yes @deepseek-ai/dsh --profile web --dump-config 2>&1)" || {
  echo "LOI: cau hinh khong hop le. Xem chi tiet:"
  echo "$DUMP_OUTPUT"
  exit 1
}
if ! echo "$DUMP_OUTPUT" | grep -q "bumbee-dsh-session-hub-panel"; then
  echo "CANH BAO: khong thay Bumbee trong cau hinh da compose, kiem tra lai cordis.patch.yml"
  exit 1
fi

echo ""
echo "== Cai dat xong =="
echo "Chay DSH nhu binh thuong:  npx @deepseek-ai/dsh web"
echo "Session Hub se tu mo lam man hinh chinh. Can Tailscale toi 100.101.26.30 de thay du lieu that."
