const COMPOSER_DRAFT_STORAGE_PREFIX = "code-remote-manager.composer-draft:";
const COMPOSER_DRAFT_COMMIT_DELAY_MS = 300;

export function createComposerDraftCommitter(onCommit, {
  delay = COMPOSER_DRAFT_COMMIT_DELAY_MS,
  setTimer = globalThis.setTimeout,
  clearTimer = globalThis.clearTimeout
} = {}) {
  let context;
  let dirty = false;
  let timer = null;
  let value = "";

  function cancelTimer() {
    if (timer === null) return;
    clearTimer(timer);
    timer = null;
  }

  function commit() {
    if (!dirty) return;
    cancelTimer();
    dirty = false;
    onCommit(value, context);
  }

  return {
    schedule(nextValue, nextContext) {
      value = nextValue;
      context = nextContext;
      dirty = true;
      cancelTimer();
      timer = setTimer(() => {
        timer = null;
        if (!dirty) return;
        dirty = false;
        onCommit(value, context);
      }, delay);
    },
    flush: commit,
    replace(nextValue, nextContext) {
      cancelTimer();
      value = nextValue;
      context = nextContext;
      dirty = false;
    }
  };
}

export function loadComposerDraft(storage, sessionId) {
  if (!sessionId) return "";
  try {
    return storage?.getItem(draftKey(sessionId)) ?? "";
  } catch {
    return "";
  }
}

export function saveComposerDraft(storage, sessionId, message) {
  if (!sessionId) return;
  try {
    if (message) storage?.setItem(draftKey(sessionId), message);
    else storage?.removeItem(draftKey(sessionId));
  } catch {
    // Storage may be unavailable in private or restricted browsing contexts.
  }
}

export function clearComposerDraft(storage, sessionId) {
  if (!sessionId) return;
  try {
    storage?.removeItem(draftKey(sessionId));
  } catch {
    // Storage may be unavailable in private or restricted browsing contexts.
  }
}

function draftKey(sessionId) {
  return `${COMPOSER_DRAFT_STORAGE_PREFIX}${encodeURIComponent(sessionId)}`;
}
