export const initialComposerOptions = {
  model: "",
  effort: "",
  serviceTier: "",
  permissionProfile: ":workspace",
  approvalPolicy: "on-request",
  personality: "",
  planMode: false
};

const COMPOSER_PERMISSION_STORAGE_KEY = "code-remote-manager.composer-permissions";
const COMPOSER_RECENT_MODEL_STORAGE_KEY = "code-remote-manager.composer-recent-model";
const COMPOSER_CHAT_STORAGE_PREFIX = "code-remote-manager.composer-chat.";
const APPROVAL_POLICIES = new Set(["untrusted", "on-failure", "on-request", "never"]);
const PROFILES = new Set([":read-only", ":workspace", ":danger-full-access"]);
const LEGACY_PROFILE_BY_SANDBOX = {
  "read-only": ":read-only",
  "workspace-write": ":workspace",
  "danger-full-access": ":danger-full-access"
};

export function loadComposerOptions(storage, chatId) {
  try {
    const saved = JSON.parse(storage?.getItem(COMPOSER_PERMISSION_STORAGE_KEY) ?? "null");
    const approvalPolicy = APPROVAL_POLICIES.has(saved?.approvalPolicy)
      ? saved.approvalPolicy
      : initialComposerOptions.approvalPolicy;
    const permissionProfile = PROFILES.has(saved?.permissionProfile)
      ? saved.permissionProfile
      : LEGACY_PROFILE_BY_SANDBOX[saved?.sandbox] ?? initialComposerOptions.permissionProfile;
    const chat = chatId
      ? JSON.parse(storage?.getItem(chatStorageKey(chatId)) ?? "null")
      : null;
    const recent = JSON.parse(storage?.getItem(COMPOSER_RECENT_MODEL_STORAGE_KEY) ?? "null");
    const chatModel = cleanStoredSelection(chat?.model);
    const chatEffort = cleanStoredSelection(chat?.effort);
    if (chatId && chatModel === cleanStoredSelection(recent?.model) && !cleanStoredSelection(recent?.effort) && chatEffort) {
      saveRecentModelOptions(storage, { model: chatModel, effort: chatEffort });
    }
    return {
      ...initialComposerOptions,
      permissionProfile,
      approvalPolicy,
      model: chatId ? chatModel : cleanStoredSelection(recent?.model),
      effort: chatId ? chatEffort : cleanStoredSelection(recent?.effort)
    };
  } catch {
    return initialComposerOptions;
  }
}

export function saveComposerOptions(storage, options, chatId) {
  try {
    storage?.setItem(COMPOSER_PERMISSION_STORAGE_KEY, JSON.stringify({
      approvalPolicy: options.approvalPolicy,
      permissionProfile: options.permissionProfile
    }));
    if (chatId) {
      storage?.setItem(chatStorageKey(chatId), JSON.stringify({
        model: cleanStoredSelection(options.model),
        effort: cleanStoredSelection(options.effort)
      }));
    }
  } catch {
    // Storage may be unavailable in private or restricted browsing contexts.
  }
}

export function buildComposerPayload({ message, executionAccountId, options, attachments, selectedSkills }) {
  return compactObject({
    text: message,
    executionAccountId,
    options: compactObject({
      model: options.model,
      effort: options.effort,
      serviceTier: options.serviceTier,
      permissionProfile: options.permissionProfile,
      approvalPolicy: options.approvalPolicy,
      personality: options.personality,
      planMode: Boolean(options.planMode)
    }),
    attachments: (attachments ?? []).map((item) => ({ id: item.id })),
    skills: (selectedSkills ?? []).map((item) => compactObject({ name: item.name }))
  });
}

export function updateComposerOption(options, key, value, storage, chatId) {
  const updated = { ...options, [key]: key === "planMode" ? Boolean(value) : value };
  if (["permissionProfile", "approvalPolicy", "model", "effort"].includes(key)) {
    saveComposerOptions(storage, updated, chatId);
  }
  if (["model", "effort"].includes(key)) saveRecentModelOptions(storage, updated);
  return updated;
}

export function normalizeComposerModel(options, models = []) {
  if (!options.model || models.length === 0) return options;
  const model = models.find((item) => item.model === options.model || item.id === options.model);
  if (!model) return { ...options, model: "", effort: "" };
  if (options.effort && !(model.reasoningEfforts ?? []).some((item) => item.id === options.effort)) {
    return { ...options, effort: "" };
  }
  return options;
}

function chatStorageKey(chatId) {
  return `${COMPOSER_CHAT_STORAGE_PREFIX}${encodeURIComponent(chatId)}`;
}

function cleanStoredSelection(value) {
  return typeof value === "string" && value.trim() ? value.trim() : "";
}

function saveRecentModelOptions(storage, options) {
  const model = cleanStoredSelection(options.model);
  const effort = cleanStoredSelection(options.effort);
  if (!model && !effort) return;
  try {
    storage?.setItem(COMPOSER_RECENT_MODEL_STORAGE_KEY, JSON.stringify({ model, effort }));
  } catch {
    // Storage may be unavailable in private or restricted browsing contexts.
  }
}

function compactObject(value) {
  return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined && item !== null && item !== ""));
}
