import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
import { n as weixinCheck, r as weixinGetUpdates } from "./client-DKAGmFUa.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "minion/plugin-sdk/account-id";

//#region extensions/weixin/src/accounts.ts
const DEFAULT_BASE_URL = "https://ilinkai.weixin.qq.com";
const DEFAULT_POLL_TIMEOUT_SEC = 35;
/**
* List all configured account IDs from the accounts field.
*/
function listConfiguredAccountIds(cfg) {
	const accounts = (cfg.channels?.weixin)?.accounts;
	if (!accounts || typeof accounts !== "object") return [];
	return Object.keys(accounts).filter(Boolean);
}
/**
* List all Weixin account IDs.
* Returns [DEFAULT_ACCOUNT_ID] if no named accounts are configured.
*/
function listWeixinAccountIds(cfg) {
	const ids = listConfiguredAccountIds(cfg);
	if (ids.length === 0) return [DEFAULT_ACCOUNT_ID];
	return [...ids].toSorted((a, b) => a.localeCompare(b));
}
/**
* Resolve the default account ID.
*/
function resolveDefaultWeixinAccountId(cfg) {
	const ids = listWeixinAccountIds(cfg);
	if (ids.includes(DEFAULT_ACCOUNT_ID)) return DEFAULT_ACCOUNT_ID;
	return ids[0] ?? DEFAULT_ACCOUNT_ID;
}
/**
* Get the raw account-specific config.
*/
function resolveAccountConfig(cfg, accountId) {
	const accounts = (cfg.channels?.weixin)?.accounts;
	if (!accounts || typeof accounts !== "object") return;
	return accounts[accountId];
}
/**
* Merge top-level config with account-specific overrides.
*/
function mergeWeixinAccountConfig(cfg, accountId) {
	const { accounts: _ignored, ...base } = cfg.channels?.weixin ?? {};
	const account = resolveAccountConfig(cfg, accountId) ?? {};
	return {
		...base,
		...account
	};
}
/**
* Resolve a complete Weixin account with merged config.
*/
function resolveWeixinAccount(params) {
	const accountId = normalizeAccountId(params.accountId);
	const baseEnabled = (params.cfg.channels?.weixin)?.enabled !== false;
	const merged = mergeWeixinAccountConfig(params.cfg, accountId);
	const accountEnabled = merged.enabled !== false;
	const enabled = baseEnabled && accountEnabled;
	const botToken = merged.botToken?.trim() || void 0;
	return {
		accountId,
		enabled,
		configured: Boolean(botToken),
		name: merged.name?.trim() || void 0,
		botToken,
		baseUrl: merged.baseUrl?.trim() || DEFAULT_BASE_URL,
		pollTimeoutSec: merged.pollTimeoutSec ?? DEFAULT_POLL_TIMEOUT_SEC,
		config: merged
	};
}

//#endregion
//#region extensions/weixin/src/probe.ts
/**
* Health-check probe for a Weixin account.
* Verifies the bot token is valid and the API is reachable.
*/
async function probeWeixin(account) {
	if (!account.botToken) return {
		ok: false,
		error: "missing bot token — run QR login first"
	};
	const start = Date.now();
	const result = await weixinCheck({
		baseUrl: account.baseUrl,
		botToken: account.botToken,
		timeoutMs: 1e4
	});
	const elapsedMs = Date.now() - start;
	if (!result.ok) return {
		ok: false,
		error: result.error,
		elapsedMs
	};
	return {
		ok: true,
		botUin: result.botUin,
		botNickname: result.botNickname,
		status: "connected",
		elapsedMs
	};
}

//#endregion
//#region extensions/weixin/src/types.ts
/** Message type constants */
const WeixinMessageType = {
	TEXT: 1,
	IMAGE: 2,
	VOICE: 3,
	FILE: 4,
	VIDEO: 5
};

//#endregion
//#region extensions/weixin/src/normalize.ts
const MESSAGE_TYPE_TO_MEDIA = {
	[WeixinMessageType.IMAGE]: "image",
	[WeixinMessageType.VOICE]: "voice",
	[WeixinMessageType.FILE]: "file",
	[WeixinMessageType.VIDEO]: "video"
};
/**
* Normalize a raw iLink Bot API inbound message into a standard context object.
*/
function normalizeWeixinMessage(msg, botUin) {
	const isGroup = Boolean(msg.chatId);
	const body = msg.text ?? "";
	return {
		body,
		rawBody: body,
		from: msg.fromUin,
		to: botUin,
		senderName: msg.fromNickname ?? msg.fromUin,
		senderId: msg.fromUin,
		chatType: isGroup ? "group" : "direct",
		chatId: msg.chatId,
		chatName: msg.chatName,
		provider: "weixin",
		surface: "weixin",
		timestamp: msg.timestamp,
		contextToken: msg.contextToken,
		mediaKey: msg.mediaKey,
		mediaAesKey: msg.mediaAesKey,
		mediaType: MESSAGE_TYPE_TO_MEDIA[msg.type]
	};
}
/**
* Resolve the outbound target for replying to a normalized context.
* For group messages, replies go to the group. For DMs, replies go to the sender.
*/
function resolveOutboundTarget(ctx) {
	if (ctx.chatType === "group" && ctx.chatId) return `group:${ctx.chatId}`;
	return `user:${ctx.from}`;
}

//#endregion
//#region extensions/weixin/src/monitor.ts
var monitor_exports = /* @__PURE__ */ __exportAll({ monitorWeixinProvider: () => monitorWeixinProvider });
/**
* Long-poll monitor for the Weixin iLink Bot API.
* Continuously polls /ilink/bot/getupdates and dispatches
* normalized messages to the onMessage callback.
*/
async function monitorWeixinProvider(opts) {
	const { config, runtime, abortSignal, accountId } = opts;
	if (!config) throw new Error("monitorWeixinProvider requires config");
	const account = resolveWeixinAccount({
		cfg: config,
		accountId
	});
	if (!account.configured || !account.botToken) throw new Error(`Weixin account "${account.accountId}" not configured`);
	const log = runtime?.log ?? console.log;
	const error = runtime?.error ?? console.error;
	const probeResult = await probeWeixin(account);
	const botUin = probeResult.botUin ?? "unknown";
	if (probeResult.ok) log(`[weixin] bot connected: ${probeResult.botNickname ?? botUin}`);
	else error(`[weixin] probe failed: ${probeResult.error} — continuing with polling`);
	let cursor;
	while (!abortSignal?.aborted) try {
		const response = await weixinGetUpdates({
			baseUrl: account.baseUrl,
			botToken: account.botToken,
			cursor,
			pollTimeoutSec: account.pollTimeoutSec
		});
		if (response.get_updates_buf) cursor = response.get_updates_buf;
		if (response.updates?.length) for (const msg of response.updates) {
			if (abortSignal?.aborted) break;
			try {
				const normalized = normalizeWeixinMessage(msg, botUin);
				const replyTo = resolveOutboundTarget(normalized);
				if (opts.onMessage) await opts.onMessage(normalized, replyTo);
			} catch (msgErr) {
				error(`[weixin] error processing message: ${msgErr instanceof Error ? msgErr.message : String(msgErr)}`);
			}
		}
		if (response.errcode && response.errcode !== 0) {
			error(`[weixin] getupdates error: ${response.errmsg ?? `code ${response.errcode}`}`);
			await new Promise((resolve) => setTimeout(resolve, 5e3));
		}
	} catch (pollErr) {
		if (abortSignal?.aborted) break;
		error(`[weixin] poll error: ${pollErr instanceof Error ? pollErr.message : String(pollErr)}`);
		await new Promise((resolve) => setTimeout(resolve, 1e4));
	}
	log("[weixin] monitor stopped");
}

//#endregion
export { probeWeixin as a, resolveWeixinAccount as c, resolveOutboundTarget as i, monitor_exports as n, listWeixinAccountIds as o, normalizeWeixinMessage as r, resolveDefaultWeixinAccountId as s, monitorWeixinProvider as t };