import { r as __exportAll } from "./chunk-D_gEzPfs.js";
import { join } from "node:path";
import { homedir, hostname } from "node:os";
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { createHash, randomBytes } from "node:crypto";

//#region src/commands/login.ts
/**
* `skykoi login` — authenticate the CLI with a SkyKoi account.
*
* Two modes:
*
*   skykoi login                  # browser device flow
*   skykoi login --token <token>  # paste an existing CLI token
*
* The device flow:
*   1. Generate a 32-byte random secret S; compute H = sha256(S).
*   2. POST H to /api/cli/auth/init; get back a verification URL.
*   3. Open the URL in the user's browser AND poll /api/cli/auth/poll
*      every 2s with raw S.
*   4. Once the user clicks "Approve" on the web page, poll returns
*      { status: "approved", token, userId, orgId }.
*   5. Write ~/.skykoi/auth.json with the token + scope metadata.
*
* The token (raw "skk_…" string) is what the CLI uses for all
* subsequent platform API calls — passed as `Authorization: Bearer
* <token>`. The platform's requireRoleFromRequest detects the `skk_`
* prefix and resolves the auth context from the CliToken row.
*/
var login_exports = /* @__PURE__ */ __exportAll({
	loginCommand: () => loginCommand,
	readAuthFile: () => readAuthFile
});
const DEFAULT_PLATFORM_URL = "https://www.skykoi.com";
function resolvePlatformUrl(opt) {
	return (opt || process.env.SKYKOI_PLATFORM_URL || DEFAULT_PLATFORM_URL).replace(/[\r\n\t]/g, "").replace(/\/$/, "").replace(/^https?:\/\/skykoi\.com$/i, "https://www.skykoi.com");
}
function authFilePath() {
	return join(homedir(), ".skykoi", "auth.json");
}
async function readAuthFile() {
	try {
		const buf = await readFile(authFilePath(), "utf-8");
		const parsed = JSON.parse(buf);
		if (typeof parsed?.token !== "string") return null;
		return parsed;
	} catch {
		return null;
	}
}
async function writeAuthFile(data) {
	const path = authFilePath();
	await mkdir(join(homedir(), ".skykoi"), { recursive: true });
	await writeFile(path, JSON.stringify(data, null, 2) + "\n", {
		encoding: "utf-8",
		mode: 384
	});
	return path;
}
async function openBrowser(url) {
	const { spawn } = await import("node:child_process");
	const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
	const args = process.platform === "win32" ? [
		"/c",
		"start",
		"",
		url
	] : [url];
	try {
		spawn(cmd, args, {
			stdio: "ignore",
			detached: true
		}).unref();
	} catch {}
}
async function loginCommand(opts = {}) {
	const platformUrl = resolvePlatformUrl(opts.platformUrl);
	if (opts.token && opts.token.trim()) {
		const token = opts.token.trim();
		if (!token.startsWith("skk_")) return {
			ok: false,
			error: "Token must start with `skk_`. Run `skykoi login` to generate one in the browser."
		};
		const res = await fetch(`${platformUrl}/api/auth/me`, { headers: { Authorization: `Bearer ${token}` } }).catch((err) => ({
			ok: false,
			status: 0,
			statusText: err?.message ?? "network error",
			json: async () => ({})
		}));
		if (!("ok" in res) || !res.ok) return {
			ok: false,
			error: `Token verification failed (${res?.status ?? "?"})`
		};
		const me = await res.json().catch(() => ({}));
		if (!me.userId || !me.orgId) return {
			ok: false,
			error: "Token validated but no user/org returned. Token may be malformed."
		};
		const path = await writeAuthFile({
			token,
			userId: me.userId,
			orgId: me.orgId,
			platformUrl,
			savedAt: (/* @__PURE__ */ new Date()).toISOString()
		});
		return {
			ok: true,
			userId: me.userId,
			orgId: me.orgId,
			authFile: path
		};
	}
	const secret = randomBytes(32).toString("base64url");
	const requestHash = createHash("sha256").update(secret).digest("hex");
	const host = (opts.hostname || hostname() || "this device").slice(0, 80);
	const initRes = await fetch(`${platformUrl}/api/cli/auth/init`, {
		method: "POST",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify({
			requestHash,
			hostname: host,
			userAgent: `skykoi-cli node-${process.version} ${process.platform}`
		})
	}).catch((err) => ({
		ok: false,
		status: 0,
		statusText: err?.message ?? "network error",
		json: async () => ({})
	}));
	if (!("ok" in initRes) || !initRes.ok) return {
		ok: false,
		error: `Failed to start login (${initRes?.status ?? "?"}). Check your network and SKYKOI_PLATFORM_URL.`
	};
	const init = await initRes.json();
	const verificationUrl = init.verificationUrl;
	if (!verificationUrl) return {
		ok: false,
		error: "Platform did not return a verification URL."
	};
	const pollIntervalMs = Math.max(1e3, (init.pollIntervalSec ?? 2) * 1e3);
	console.log("");
	console.log(`  Visit:  ${verificationUrl}`);
	console.log(`  (Opening your browser; if it doesn't open, copy/paste the URL.)`);
	console.log("");
	if (!opts.noBrowser) await openBrowser(verificationUrl);
	console.log("  Waiting for approval…");
	const deadline = Date.now() + (opts.timeoutMs ?? 600 * 1e3);
	while (Date.now() < deadline) {
		await new Promise((r) => setTimeout(r, pollIntervalMs));
		let pollRes;
		try {
			pollRes = await fetch(`${platformUrl}/api/cli/auth/poll`, {
				method: "POST",
				headers: { "Content-Type": "application/json" },
				body: JSON.stringify({ requestSecret: secret })
			});
		} catch {
			continue;
		}
		if (!pollRes.ok) continue;
		const data = await pollRes.json().catch(() => ({}));
		if (data.status === "approved" && data.token && data.userId && data.orgId) {
			const path = await writeAuthFile({
				token: data.token,
				userId: data.userId,
				orgId: data.orgId,
				platformUrl,
				savedAt: (/* @__PURE__ */ new Date()).toISOString()
			});
			console.log("");
			console.log(`  ✓ Logged in. Token saved to ${path}`);
			return {
				ok: true,
				userId: data.userId,
				orgId: data.orgId,
				authFile: path
			};
		}
		if (data.status === "denied") return {
			ok: false,
			error: "Login denied in the browser."
		};
		if (data.status === "expired") return {
			ok: false,
			error: "Login request expired. Run `skykoi login` again."
		};
	}
	return {
		ok: false,
		error: "Timed out waiting for browser approval."
	};
}

//#endregion
export { login_exports as n, readAuthFile as r, loginCommand as t };