import { createLogger } from "../utils/logger/index.js";
import { init_logger } from "../utils/logger.js";
import { init_loader, saveConfig } from "../config/loader.js";
import { effectiveWorkspacePathForSession } from "../session/session-workspace.js";
import { getRoutingInfo, getSessionDisplayName } from "./session-key.js";
import { wrapMarkdownExportAsHtml } from "../session/chat-export.js";
import { mkdir, writeFile } from "fs/promises";
import { join } from "path";
//#region src/chat-commands/context.ts
init_logger();
init_loader();
const log = createLogger("CommandContext");
var CommandContextImpl = class {
	sessionKey;
	source;
	channelId;
	chatId;
	senderId;
	isGroup;
	config;
	abortCurrentTurn;
	persistentGoalApis;
	deps;
	constructor(deps) {
		this.sessionKey = deps.sessionKey;
		this.source = deps.source;
		this.channelId = deps.channelId;
		this.chatId = deps.chatId;
		this.senderId = deps.senderId;
		this.isGroup = deps.isGroup;
		this.config = deps.config;
		this.deps = deps;
		if (deps.abortCurrentTurn) {
			const run = deps.abortCurrentTurn;
			this.abortCurrentTurn = async () => {
				await run();
			};
		}
		this.persistentGoalApis = deps.persistentGoalApis;
	}
	async reply(text, options) {
		await this.deps.replyHandler(text, options);
	}
	async replyComponent(component) {
		if (this.deps.componentHandler) await this.deps.componentHandler(component);
		else await this.reply(this.renderComponentAsText(component));
	}
	async setTyping(typing) {
		if (this.deps.typingHandler) await this.deps.typingHandler(typing);
	}
	async getSession() {
		return this.deps.sessionStore.load(this.sessionKey);
	}
	async resetSession() {
		if (this.deps.resetSession) await this.deps.resetSession(this.sessionKey);
		else if (typeof this.deps.sessionStore.reset === "function") {
			if (!await this.deps.sessionStore.reset(this.sessionKey)) throw new Error("Session not found");
			this.deps.invalidateAgentSession?.(this.sessionKey);
		} else {
			await this.clearSession();
			return;
		}
		const routing = getRoutingInfo(this.sessionKey);
		await this.deps.bus.publishOutbound({
			channel: routing.channel,
			chat_id: routing.chatId,
			content: "✅ New session started. Previous transcript archived; model and session overrides kept.",
			type: "message",
			metadata: { threadId: routing.threadId }
		});
		log.info({ sessionKey: this.sessionKey }, "Session reset");
	}
	async clearSession() {
		const messages = await this.getSession();
		if (messages.length > 0) {
			await this.deps.sessionStore.archive(this.sessionKey);
			log.info({
				sessionKey: this.sessionKey,
				messageCount: messages.length
			}, "Session archived");
		}
		await this.deps.sessionStore.deleteSession(this.sessionKey);
		this.deps.invalidateAgentSession?.(this.sessionKey);
		const routing = getRoutingInfo(this.sessionKey);
		await this.deps.bus.publishOutbound({
			channel: routing.channel,
			chat_id: routing.chatId,
			content: "✅ Session cleared.",
			type: "message",
			metadata: { threadId: routing.threadId }
		});
		log.info({ sessionKey: this.sessionKey }, "Session cleared");
	}
	async archiveSession() {
		await this.deps.sessionStore.archive(this.sessionKey);
		log.info({ sessionKey: this.sessionKey }, "Session archived");
	}
	async listSessions() {
		const messages = await this.getSession();
		return [{
			key: this.sessionKey,
			name: getSessionDisplayName(this.sessionKey),
			messageCount: messages.length,
			createdAt: /* @__PURE__ */ new Date(),
			updatedAt: /* @__PURE__ */ new Date(),
			isActive: true
		}];
	}
	async switchSession(sessionKey) {
		log.info({
			from: this.sessionKey,
			to: sessionKey
		}, "Session switch requested");
	}
	getCurrentModel() {
		if (this.deps.getCurrentModel) return this.deps.getCurrentModel();
		return this.config.agents?.defaults?.model?.primary || "minimax/minimax-m2.1";
	}
	async listModels() {
		if (this.deps.listModels) return this.deps.listModels();
		return [];
	}
	async switchModel(modelId) {
		if (this.deps.switchModel) return this.deps.switchModel(modelId);
		await this.reply("❌ Model switching not available in this context.");
		return false;
	}
	async getUsage() {
		if (this.deps.getUsage) return this.deps.getUsage();
		const messages = await this.getSession();
		let promptTokens = 0;
		let completionTokens = 0;
		for (const msg of messages) if ("usage" in msg && msg.usage) {
			promptTokens += msg.usage.input || 0;
			completionTokens += msg.usage.output || 0;
		}
		return {
			promptTokens,
			completionTokens,
			totalTokens: promptTokens + completionTokens,
			messageCount: messages.length
		};
	}
	supports(feature) {
		return this.deps.supportedFeatures.includes(feature);
	}
	getConfig() {
		return this.config;
	}
	async updateConfig(path, value) {
		try {
			const keys = path.split(".");
			let target = this.config;
			for (let i = 0; i < keys.length - 1; i++) {
				const key = keys[i];
				if (!(key in target) || typeof target[key] !== "object" || target[key] === null) target[key] = {};
				target = target[key];
			}
			target[keys[keys.length - 1]] = value;
			await saveConfig(this.config);
			log.info({
				path,
				value
			}, "Config updated via command");
			return true;
		} catch (error) {
			log.error({
				err: error,
				path,
				value
			}, "Failed to update config");
			return false;
		}
	}
	/**
	* Get the session config store (if available)
	*/
	getSessionConfigStore() {
		return this.deps.sessionConfigStore;
	}
	/**
	* Get current thinking level (session override or default)
	*/
	async getThinkingLevel() {
		const configStore = this.deps.sessionConfigStore;
		if (configStore) {
			const sessionConfig = await configStore.get(this.sessionKey);
			if (sessionConfig?.thinkingLevel) return sessionConfig.thinkingLevel;
		}
		return this.config.agents?.defaults?.thinkingDefault;
	}
	/**
	* Set thinking level for this session
	*/
	async setThinkingLevel(level) {
		const configStore = this.deps.sessionConfigStore;
		if (configStore) await configStore.update(this.sessionKey, { thinkingLevel: level });
		this.deps.applySessionThinkingLevel?.(this.sessionKey, level);
	}
	syncAgentThinkingLevel(level) {
		this.deps.applySessionThinkingLevel?.(this.sessionKey, level);
	}
	async compactSession(options) {
		if (!this.deps.compactSession) return null;
		const r = await this.deps.compactSession(this.sessionKey, options);
		return {
			compacted: r.compacted,
			tokensBefore: r.tokensBefore,
			tokensAfter: r.tokensAfter,
			summary: r.summary
		};
	}
	async btwQuery(question) {
		if (!this.deps.btwQuery) return {
			text: "",
			error: "Side questions are not available in this environment."
		};
		return this.deps.btwQuery(this.sessionKey, question);
	}
	async exportSessionToWorkspace(format) {
		const exportFmt = format === "json" ? "json" : "markdown";
		let body = await this.deps.sessionStore.exportSession(this.sessionKey, exportFmt);
		if (format === "html") body = wrapMarkdownExportAsHtml(`Session ${this.sessionKey}`, body);
		const sc = this.deps.sessionConfigStore ? await this.deps.sessionConfigStore.get(this.sessionKey) : null;
		const dir = join(effectiveWorkspacePathForSession(this.config, this.sessionKey, sc), "exports");
		await mkdir(dir, { recursive: true });
		const safe = this.sessionKey.replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 96);
		const ext = format === "json" ? "json" : format === "html" ? "html" : "md";
		const outPath = join(dir, `session-${safe}-${Date.now()}.${ext}`);
		await writeFile(outPath, body, "utf-8");
		return { path: outPath };
	}
	async agentContextReport(mode = "list") {
		if (!this.deps.getSessionContextReport) return "Context report is not available in this environment.";
		return this.deps.getSessionContextReport(this.sessionKey, mode);
	}
	/**
	* Get current reasoning level (session override or default)
	*/
	async getReasoningLevel() {
		const configStore = this.deps.sessionConfigStore;
		if (configStore) {
			const sessionConfig = await configStore.get(this.sessionKey);
			if (sessionConfig?.reasoningLevel) return sessionConfig.reasoningLevel;
		}
		return this.config.agents?.defaults?.reasoningDefault;
	}
	/**
	* Set reasoning level for this session
	*/
	async setReasoningLevel(level) {
		const configStore = this.deps.sessionConfigStore;
		if (configStore) await configStore.update(this.sessionKey, { reasoningLevel: level });
	}
	/**
	* Get current verbose level (session override or default)
	*/
	async getVerboseLevel() {
		const configStore = this.deps.sessionConfigStore;
		if (configStore) {
			const sessionConfig = await configStore.get(this.sessionKey);
			if (sessionConfig?.verboseLevel) return sessionConfig.verboseLevel;
		}
		return this.config.agents?.defaults?.verboseDefault;
	}
	/**
	* Set verbose level for this session
	*/
	async setVerboseLevel(level) {
		const configStore = this.deps.sessionConfigStore;
		if (configStore) await configStore.update(this.sessionKey, { verboseLevel: level });
	}
	renderComponentAsText(component) {
		switch (component.type) {
			case "buttons": return component.buttons.map((b) => `[${b.text}]`).join(" ");
			case "select": return component.options.map((o) => `- ${o.label}`).join("\n");
			case "model-picker": return component.providers.map((p) => `**${p.name}**\n${p.models.map((m) => `  - ${m.name}`).join("\n")}`).join("\n\n");
			case "usage-display": return `📊 Usage Stats:\n📥 Prompt: ${component.stats.promptTokens.toLocaleString()} tokens\n📤 Completion: ${component.stats.completionTokens.toLocaleString()} tokens\n📊 Total: ${component.stats.totalTokens.toLocaleString()} tokens`;
			case "session-list": return component.sessions.map((s) => `${s.isActive ? "▶️" : "  "} ${s.key} (${s.messageCount} messages)`).join("\n");
			case "text-input": return component.placeholder || "Enter text...";
			default: return "[UI Component]";
		}
	}
};
/**
* Create a command context from dependencies
*/
function createCommandContext(deps) {
	return new CommandContextImpl(deps);
}
//#endregion
export { CommandContextImpl, createCommandContext };

//# sourceMappingURL=context.js.map