import { apiByKey } from "../api/index.js";
import { metricsByPaths } from "../metrics/index.js";

/** @param {any} message */
function chartFrom(message) {
  return message?.artifacts?.findLast?.(
    (/** @type {any} */ artifact) => artifact.type === "chart",
  );
}

/**
 * Only the latest assistant response owns conversational tool context. This
 * prevents an unrelated old chart, API call, or source result from silently
 * becoming active again.
 *
 * @param {import("../../storage.js").StoredMessage[]} history
 * @param {() => void} onProgress
 */
export async function loadSessionContext(history, onProgress) {
  const assistantMessages = [...history].reverse().filter(
    ({ role }) => role === "assistant",
  );
  const message = assistantMessages[0];
  if (!message) {
    return {
      metrics: [],
      recentMetrics: [],
      source: [],
    };
  }

  const chart = chartFrom(message);
  const activePaths = [...new Set([
    ...(message.metricPaths ?? []),
    ...(chart?.chart.series.map((/** @type {any} */ series) => series.path) ?? []),
  ])];
  const recentPaths = [...new Set(
    assistantMessages.slice(1, 4).flatMap((recent) => [
      ...(recent.metricPaths ?? []),
      ...(chartFrom(recent)?.chart.series.map(
        (/** @type {any} */ series) => series.path,
      ) ?? []),
    ]),
  )].filter((path) => !activePaths.includes(path));
  const paths = [...activePaths, ...recentPaths];
  const [metrics, operation] = await Promise.all([
    paths.length ? metricsByPaths(paths, onProgress) : [],
    message.apiContext?.key ? apiByKey(message.apiContext.key) : undefined,
  ]);

  return {
    ...(chart ? { chart } : {}),
    ...(message.capability ? { capability: message.capability } : {}),
    metrics: metrics.filter(({ path }) => activePaths.includes(path)),
    recentMetrics: metrics.filter(({ path }) => recentPaths.includes(path)),
    ...(operation
      ? {
          api: {
            operation,
            arguments: message.apiContext?.arguments ?? {},
            fields: message.apiContext?.fields ?? [],
            records: message.apiContext?.records ?? [],
          },
        }
      : {}),
    source: message.sourceContext ?? [],
    ...(message.knowledgeContext
      ? { knowledge: message.knowledgeContext }
      : {}),
  };
}
