import { DEFAULT_CHAT_CHANNEL } from "../../channels/registry.js";
import { loadSessionStore, resolveAgentMainSessionKey, resolveStorePath, } from "../../config/sessions.js";
import { resolveMessageChannelSelection } from "../../infra/outbound/channel-selection.js";
import { resolveOutboundTarget, resolveSessionDeliveryTarget, } from "../../infra/outbound/targets.js";
import { buildChannelAccountBindings } from "../../routing/bindings.js";
import { normalizeAgentId } from "../../routing/session-key.js";
export async function resolveDeliveryTarget(cfg, agentId, jobPayload) {
    const requestedChannel = typeof jobPayload.channel === "string" ? jobPayload.channel : "last";
    const explicitTo = typeof jobPayload.to === "string" ? jobPayload.to : undefined;
    const sessionCfg = cfg.session;
    const mainSessionKey = resolveAgentMainSessionKey({ cfg, agentId });
    const storePath = resolveStorePath(sessionCfg?.store, { agentId });
    const store = loadSessionStore(storePath);
    const main = store[mainSessionKey];
    const preliminary = resolveSessionDeliveryTarget({
        entry: main,
        requestedChannel,
        explicitTo,
        allowMismatchedLastTo: true,
    });
    let fallbackChannel;
    if (!preliminary.channel) {
        try {
            const selection = await resolveMessageChannelSelection({ cfg });
            fallbackChannel = selection.channel;
        }
        catch {
            fallbackChannel = preliminary.lastChannel ?? DEFAULT_CHAT_CHANNEL;
        }
    }
    const resolved = fallbackChannel
        ? resolveSessionDeliveryTarget({
            entry: main,
            requestedChannel,
            explicitTo,
            fallbackChannel,
            allowMismatchedLastTo: true,
            mode: preliminary.mode,
        })
        : preliminary;
    const channel = resolved.channel ?? fallbackChannel ?? DEFAULT_CHAT_CHANNEL;
    const mode = resolved.mode;
    const toCandidate = resolved.to;
    // 当会话没有 lastAccountId（例如首次运行的隔离 cron 会话）时，
    // 回退到从 bindings 配置中获取 agent 绑定的账户。
    // 这确保隔离会话中的 message 工具为多账户设置解析正确的机器人令牌。
    let accountId = resolved.accountId;
    if (!accountId && channel) {
        const bindings = buildChannelAccountBindings(cfg);
        const byAgent = bindings.get(channel);
        const boundAccounts = byAgent?.get(normalizeAgentId(agentId));
        if (boundAccounts && boundAccounts.length > 0) {
            accountId = boundAccounts[0];
        }
    }
    if (!toCandidate) {
        return { channel, to: undefined, accountId, mode };
    }
    const docked = resolveOutboundTarget({
        channel,
        to: toCandidate,
        cfg,
        accountId,
        mode,
    });
    return {
        channel,
        to: docked.ok ? docked.to : undefined,
        accountId,
        mode,
        error: docked.ok ? undefined : docked.error,
    };
}
