export function createEmptyAttachmentCache() {
  return {
    pageContextHash: "",
    screenshotHash: ""
  };
}

export async function planAttachmentReuse({
  includePageContext,
  includeScreenshot,
  pageSnapshot,
  turnAttachments,
  attachmentCache
}) {
  const cache = normalizeAttachmentCache(attachmentCache);
  const pageContextHash = includePageContext ? await hashValue(pageSnapshot || {}) : "";
  const screenshotHash =
    includeScreenshot && turnAttachments?.screenshotDataUrl
      ? await hashValue(turnAttachments.screenshotDataUrl)
      : "";

  const reusePageContext = !!(includePageContext && pageContextHash && pageContextHash === cache.pageContextHash);
  const reuseScreenshot = !!(includeScreenshot && screenshotHash && screenshotHash === cache.screenshotHash);

  return {
    includePageContext: includePageContext && !reusePageContext,
    includeScreenshot: includeScreenshot && !reuseScreenshot,
    reusedPageContext: reusePageContext,
    reusedScreenshot: reuseScreenshot,
    nextAttachmentCache: {
      pageContextHash: includePageContext ? pageContextHash : cache.pageContextHash,
      screenshotHash: includeScreenshot ? screenshotHash : cache.screenshotHash
    }
  };
}

export function commitAttachmentCache(chatSession, nextAttachmentCache, options = {}) {
  const session = chatSession || {};
  session.attachmentCache = {
    ...normalizeAttachmentCache(session.attachmentCache),
    ...normalizeAttachmentCache(nextAttachmentCache)
  };

  if (options.includePageContext === false) {
    session.attachmentCache.pageContextHash = normalizeAttachmentCache(chatSession?.attachmentCache).pageContextHash;
  }

  if (options.includeScreenshot === false) {
    session.attachmentCache.screenshotHash = normalizeAttachmentCache(chatSession?.attachmentCache).screenshotHash;
  }

  return session.attachmentCache;
}

export function normalizeAttachmentCache(cache) {
  return {
    pageContextHash: String(cache?.pageContextHash || ""),
    screenshotHash: String(cache?.screenshotHash || "")
  };
}

export function buildAttachmentReuseMessage(plan) {
  if (plan.reusedPageContext && plan.reusedScreenshot) {
    return "检测到页面无变化，本轮复用上次页面上下文，不重复发送截图。";
  }

  if (plan.reusedPageContext) {
    return "检测到页面内容无变化，本轮复用上次页面内容。";
  }

  if (plan.reusedScreenshot) {
    return "检测到页面截图无变化，本轮不重复发送截图。";
  }

  return "";
}

async function hashValue(value) {
  const source = typeof value === "string" ? value : stableStringify(value);
  const bytes = new TextEncoder().encode(source);
  const digest = await crypto.subtle.digest("SHA-256", bytes);
  return Array.from(new Uint8Array(digest))
    .map((item) => item.toString(16).padStart(2, "0"))
    .join("");
}

function stableStringify(value) {
  return JSON.stringify(sortValue(value));
}

function sortValue(value) {
  if (Array.isArray(value)) {
    return value.map(sortValue);
  }

  if (!value || typeof value !== "object") {
    return value;
  }

  return Object.keys(value)
    .sort()
    .reduce((accumulator, key) => {
      accumulator[key] = sortValue(value[key]);
      return accumulator;
    }, {});
}
