import { Type } from "@sinclair/typebox";

//#region src/infra/outbound/message-action-spec.ts
const MESSAGE_ACTION_TARGET_MODE = {
	send: "to",
	broadcast: "none",
	poll: "to",
	react: "to",
	reactions: "to",
	read: "to",
	edit: "to",
	unsend: "to",
	reply: "to",
	sendWithEffect: "to",
	renameGroup: "to",
	setGroupIcon: "to",
	addParticipant: "to",
	removeParticipant: "to",
	leaveGroup: "to",
	sendAttachment: "to",
	delete: "to",
	pin: "to",
	unpin: "to",
	"list-pins": "to",
	permissions: "to",
	"thread-create": "to",
	"thread-list": "none",
	"thread-reply": "to",
	search: "none",
	sticker: "to",
	"sticker-search": "none",
	"member-info": "none",
	"role-info": "none",
	"emoji-list": "none",
	"emoji-upload": "none",
	"sticker-upload": "none",
	"role-add": "none",
	"role-remove": "none",
	"channel-info": "channelId",
	"channel-list": "none",
	"channel-create": "none",
	"channel-edit": "channelId",
	"channel-delete": "channelId",
	"channel-move": "channelId",
	"category-create": "none",
	"category-edit": "none",
	"category-delete": "none",
	"topic-create": "to",
	"voice-status": "none",
	"event-list": "none",
	"event-create": "none",
	timeout: "none",
	kick: "none",
	ban: "none",
	"set-presence": "none"
};
const ACTION_TARGET_ALIASES = {
	unsend: ["messageId"],
	edit: ["messageId"],
	react: [
		"chatGuid",
		"chatIdentifier",
		"chatId"
	],
	renameGroup: [
		"chatGuid",
		"chatIdentifier",
		"chatId"
	],
	setGroupIcon: [
		"chatGuid",
		"chatIdentifier",
		"chatId"
	],
	addParticipant: [
		"chatGuid",
		"chatIdentifier",
		"chatId"
	],
	removeParticipant: [
		"chatGuid",
		"chatIdentifier",
		"chatId"
	],
	leaveGroup: [
		"chatGuid",
		"chatIdentifier",
		"chatId"
	]
};
function actionRequiresTarget(action) {
	return MESSAGE_ACTION_TARGET_MODE[action] !== "none";
}
function actionHasTarget(action, params) {
	if (typeof params.to === "string" ? params.to.trim() : "") return true;
	if (typeof params.channelId === "string" ? params.channelId.trim() : "") return true;
	const aliases = ACTION_TARGET_ALIASES[action];
	if (!aliases) return false;
	return aliases.some((alias) => {
		const value = params[alias];
		if (typeof value === "string") return value.trim().length > 0;
		if (typeof value === "number") return Number.isFinite(value);
		return false;
	});
}

//#endregion
//#region src/infra/outbound/channel-target.ts
const CHANNEL_TARGET_DESCRIPTION = "Recipient/channel: E.164 for WhatsApp/Signal, Telegram chat id/@username, Discord/Slack channel/user, or iMessage handle/chat_id";
const CHANNEL_TARGETS_DESCRIPTION = "Recipient/channel targets (same format as --target); accepts ids or names when the directory is available.";
function applyTargetToParams(params) {
	const target = typeof params.args.target === "string" ? params.args.target.trim() : "";
	const hasLegacyTo = typeof params.args.to === "string";
	const hasLegacyChannelId = typeof params.args.channelId === "string";
	const mode = MESSAGE_ACTION_TARGET_MODE[params.action] ?? "none";
	if (mode !== "none") {
		if (hasLegacyTo || hasLegacyChannelId) throw new Error("Use `target` instead of `to`/`channelId`.");
	} else if (hasLegacyTo) throw new Error("Use `target` for actions that accept a destination.");
	if (!target) return;
	if (mode === "channelId") {
		params.args.channelId = target;
		return;
	}
	if (mode === "to") {
		params.args.to = target;
		return;
	}
	throw new Error(`Action ${params.action} does not accept a target.`);
}

//#endregion
//#region src/agents/schema/typebox.ts
function stringEnum(values, options = {}) {
	return Type.Unsafe({
		type: "string",
		enum: [...values],
		...options
	});
}
function optionalStringEnum(values, options = {}) {
	return Type.Optional(stringEnum(values, options));
}
function channelTargetSchema(options) {
	return Type.String({ description: options?.description ?? CHANNEL_TARGET_DESCRIPTION });
}
function channelTargetsSchema(options) {
	return Type.Array(channelTargetSchema({ description: options?.description ?? CHANNEL_TARGETS_DESCRIPTION }));
}

//#endregion
export { applyTargetToParams as a, stringEnum as i, channelTargetsSchema as n, actionHasTarget as o, optionalStringEnum as r, actionRequiresTarget as s, channelTargetSchema as t };