import { captureContextFromActiveTab, getActivePageInfo } from "./page-context.js";
import { parseStoredSessionRecord, stripTransportFields } from "../../shared/schema.js";
import { createEmptyAttachmentCache, normalizeAttachmentCache } from "./attachment-dedupe.js";
import { truncateText } from "../utils.js";

export const SESSION_KEY_PREFIX = "sensaBasicSession:";
const LEGACY_SESSION_KEY_PREFIX = "sensaSession:";
const persistChains = new Map();

export async function hydratePageSession(state) {
  const pageInfo = await getActivePageInfo();
  state.currentPageKey = makePageKey(pageInfo.url);
  state.currentPageTitle = pageInfo.title || "";
  state.currentPageUrl = pageInfo.url || "";
  state.turnAttachments = null;

  const stored = await chrome.storage.local.get([state.currentPageKey, makeLegacyPageKey(pageInfo.url)]);
  const session =
    parseStoredSessionRecord(stored[state.currentPageKey]) ||
    parseStoredSessionRecord(stored[makeLegacyPageKey(pageInfo.url)]);

  if (session) {
    state.chatSession = session.chatSession || createEmptyChatSession();
    state.pageSnapshot = session.pageSnapshot || null;
  }

  await primePageSnapshot(state);
}

export async function ensurePageSession(state) {
  const pageInfo = await getActivePageInfo();
  const nextKey = makePageKey(pageInfo.url);
  if (nextKey === state.currentPageKey) {
    state.currentPageTitle = pageInfo.title || state.currentPageTitle;
    state.currentPageUrl = pageInfo.url || state.currentPageUrl;
    return false;
  }

  state.currentPageKey = nextKey;
  state.currentPageTitle = pageInfo.title || "";
  state.currentPageUrl = pageInfo.url || "";
  state.chatSession = createEmptyChatSession();
  state.pageSnapshot = null;
  state.turnAttachments = null;

  const stored = await chrome.storage.local.get([state.currentPageKey, makeLegacyPageKey(pageInfo.url)]);
  const session =
    parseStoredSessionRecord(stored[state.currentPageKey]) ||
    parseStoredSessionRecord(stored[makeLegacyPageKey(pageInfo.url)]);

  if (session) {
    state.chatSession = session.chatSession || createEmptyChatSession();
    state.pageSnapshot = session.pageSnapshot || null;
  }

  await primePageSnapshot(state);
  return true;
}

export async function persistCurrentSession(state) {
  if (!state.currentPageKey) {
    return;
  }

  await persistSessionByKey(state.currentPageKey, state.chatSession, state.pageSnapshot);
}

export async function persistSessionByKey(pageKey, chatSession, pageSnapshot) {
  if (!pageKey) {
    return;
  }

  const record = buildPersistedSessionFromData(chatSession, pageSnapshot);
  const previous = persistChains.get(pageKey) || Promise.resolve();
  const task = previous
    .catch(() => {})
    .then(() =>
      chrome.storage.local.set({
        [pageKey]: record
      })
    );

  persistChains.set(pageKey, task);

  try {
    await task;
  } finally {
    if (persistChains.get(pageKey) === task) {
      persistChains.delete(pageKey);
    }
  }
}

export async function clearAllStoredHistories() {
  const allStored = await chrome.storage.local.get(null);
  const historyKeys = Object.keys(allStored).filter(isHistoryKey);
  if (historyKeys.length) {
    await chrome.storage.local.remove(historyKeys);
  }
}

export function isHistoryKey(key) {
  return key.startsWith(SESSION_KEY_PREFIX) || key.startsWith(LEGACY_SESSION_KEY_PREFIX);
}

export function createEmptyChatSession() {
  return {
    messages: [],
    attachmentCache: createEmptyAttachmentCache()
  };
}

async function primePageSnapshot(state) {
  const snapshotUrl = String(state.pageSnapshot?.page?.url || "").trim();
  const currentUrl = String(state.currentPageUrl || "").trim();

  if (state.chatSession.messages.length || !currentUrl || snapshotUrl === currentUrl) {
    return;
  }

  try {
    state.pageSnapshot = stripTransportFields(await captureContextFromActiveTab(false, "viewport"));
  } catch (error) {
    state.pageSnapshot = null;
  }
}

function makePageKey(url) {
  return `${SESSION_KEY_PREFIX}${url || "unknown"}`;
}

function makeLegacyPageKey(url) {
  return `${LEGACY_SESSION_KEY_PREFIX}${url || "unknown"}`;
}

function buildPersistedSessionFromData(chatSession, pageSnapshot) {
  return {
    chatSession: {
      messages: sanitizeMessagesForStorage(chatSession?.messages),
      attachmentCache: normalizeAttachmentCache(chatSession?.attachmentCache)
    },
    pageSnapshot: sanitizePageSnapshotForStorage(pageSnapshot),
    savedAt: new Date().toISOString()
  };
}

function sanitizeMessagesForStorage(messages) {
  return (Array.isArray(messages) ? messages : []).slice(-24).map((message) => ({
    role: message.role === "assistant" ? "assistant" : "user",
    text: truncateText(message.text || "", 8000),
    meta: truncateText(message.meta || "", 200),
    details: message.details
      ? {
          contextPreview: truncateText(message.details.contextPreview || "", 12000),
          screenshotDataUrl: "",
          note: message.details.screenshotDataUrl ? "[screenshot omitted from storage]" : ""
        }
      : null
  }));
}

function sanitizePageSnapshotForStorage(pageSnapshot) {
  if (!pageSnapshot || typeof pageSnapshot !== "object") {
    return null;
  }
  const clone = stripTransportFields(pageSnapshot);
  clone.visibleTextExcerpt = truncateText(clone.visibleTextExcerpt || "", 12000);
  return clone;
}
