/**
 * Storage — Persistencia via chrome.storage.local.
 *
 * Substitui SQLite do backend Python.
 * Gerencia configuracoes, historico de geracoes, prompts customizados e preferencias.
 *
 * Chaves usadas:
 *   automattus_light_config   — Credenciais (attus, minutaia, api keys)
 *   light_generate_request    — Mailbox content -> sidepanel
 *   light_draft_types         — Prompts customizados por tipo
 *   light_preferences         — Preferencias de geracao (effort, verbosity)
 *   light_geracoes            — Historico de geracoes (array)
 *   light_geracoes_seq        — Sequence ID para geracoes
 */

// ── Helpers ──────────────────────────────────────────────────────────────

function storageGet(keys) {
  return new Promise((resolve) => {
    chrome.storage.local.get(keys, resolve);
  });
}

function storageSet(data) {
  return new Promise((resolve) => {
    chrome.storage.local.set(data, resolve);
  });
}

function storageRemove(keys) {
  return new Promise((resolve) => {
    chrome.storage.local.remove(keys, resolve);
  });
}

// ── Configuracoes ───────────────────────────────────────────────────────

/**
 * Retorna configuracao completa.
 * @returns {Promise<object>}
 */
export async function getConfig() {
  const result = await storageGet("automattus_light_config");
  return result.automattus_light_config || {};
}

/**
 * Salva configuracao (merge parcial).
 * @param {object} partial — Campos a atualizar
 */
export async function setConfig(partial) {
  const current = await getConfig();
  const merged = { ...current, ...partial };
  await storageSet({ automattus_light_config: merged });
  return merged;
}

/**
 * Retorna credenciais MinutaIA.
 * @returns {Promise<{email:string, password:string}>}
 */
export async function getMinutaiaCredentials() {
  const cfg = await getConfig();
  return {
    email: cfg.minutaia_email || "",
    password: cfg.minutaia_password || "",
  };
}

/**
 * Limpa credenciais MinutaIA (apaga os campos mas preserva o resto da config).
 * Nao invalida a sessao ativa — chame minutaia-client para isso.
 */
export async function clearMinutaiaCredentials() {
  const cfg = await getConfig();
  delete cfg.minutaia_email;
  delete cfg.minutaia_password;
  await storageSet({ automattus_light_config: cfg });
}

/**
 * Retorna API keys.
 * @returns {Promise<{anthropic:string, openai:string}>}
 */
export async function getApiKeys() {
  const cfg = await getConfig();
  return {
    anthropic: cfg.key_anthropic || "",
    openai: cfg.key_openai || "",
  };
}

// ── Preferencias ────────────────────────────────────────────────────────

const DEFAULT_PREFERENCES = {
  effort: 4,
  verbosity: "long",
  mode: "minuta",
  rigoroso: true,
  jurisprudencia: true,
  legislacao: true,
  contadoria: false,
  geracaoParalela: false,
  contextoInteligente: false,
};

/**
 * Retorna preferencias de geracao.
 * @returns {Promise<object>}
 */
export async function getPreferences() {
  const result = await storageGet("light_preferences");
  return { ...DEFAULT_PREFERENCES, ...(result.light_preferences || {}) };
}

/**
 * Salva preferencias (merge parcial).
 * @param {object} partial
 */
export async function setPreferences(partial) {
  const current = await getPreferences();
  const merged = { ...current, ...partial };
  await storageSet({ light_preferences: merged });
  return merged;
}

// ── Mailbox (content script -> sidepanel) ───────────────────────────────

/**
 * Le e consome o request pendente do content script.
 * @returns {Promise<object|null>}
 */
export async function consumeGenerateRequest() {
  const result = await storageGet("light_generate_request");
  const req = result.light_generate_request;
  if (req) {
    await storageRemove("light_generate_request");
    return req;
  }
  return null;
}

/**
 * Grava request para o sidepanel processar.
 * Chamado pelo service worker ao receber mensagem do content script.
 * @param {object} data
 */
export async function setGenerateRequest(data) {
  data.timestamp = Date.now();
  await storageSet({ light_generate_request: data });
}

/**
 * Observa mudancas no storage (para o sidepanel detectar novos requests).
 * @param {function} callback — Recebe o request quando disponivel
 * @returns {function} Funcao para parar de observar
 */
export function onGenerateRequest(callback) {
  const listener = (changes) => {
    if (changes.light_generate_request && changes.light_generate_request.newValue) {
      callback(changes.light_generate_request.newValue);
    }
  };
  chrome.storage.onChanged.addListener(listener);
  return () => chrome.storage.onChanged.removeListener(listener);
}

// ── Historico de Geracoes ───────────────────────────────────────────────

const MAX_GERACOES = 200;

/**
 * Retorna proximo ID sequencial para geracoes.
 */
async function nextGeracaoId() {
  const result = await storageGet("light_geracoes_seq");
  const seq = (result.light_geracoes_seq || 0) + 1;
  await storageSet({ light_geracoes_seq: seq });
  return seq;
}

/**
 * Salva nova geracao no historico.
 * @param {object} geracao
 * @returns {Promise<number>} ID da geracao
 */
export async function salvarGeracao(geracao) {
  const id = await nextGeracaoId();
  const result = await storageGet("light_geracoes");
  const geracoes = result.light_geracoes || [];

  const entry = {
    id,
    ...geracao,
    created_at: new Date().toISOString(),
    status: geracao.status || "completed",
  };

  geracoes.unshift(entry); // Mais recente primeiro

  // Limitar tamanho
  if (geracoes.length > MAX_GERACOES) {
    geracoes.length = MAX_GERACOES;
  }

  await storageSet({ light_geracoes: geracoes });
  return id;
}

/**
 * Lista geracoes, opcionalmente filtrado por demandaId.
 * @param {object} [opts]
 * @param {string} [opts.demandaId]
 * @param {number} [opts.limit=50]
 * @returns {Promise<Array>}
 */
export async function listarGeracoes(opts = {}) {
  const { demandaId, limit = 50 } = opts;
  const result = await storageGet("light_geracoes");
  let geracoes = result.light_geracoes || [];

  if (demandaId) {
    geracoes = geracoes.filter(g => g.demanda_id === demandaId);
  }

  return geracoes.slice(0, limit);
}

/**
 * Busca geracao por ID.
 * @param {number} id
 * @returns {Promise<object|null>}
 */
export async function buscarGeracao(id) {
  const result = await storageGet("light_geracoes");
  const geracoes = result.light_geracoes || [];
  return geracoes.find(g => g.id === id) || null;
}

/**
 * Atualiza geracao existente (merge parcial).
 * @param {number} id
 * @param {object} partial
 */
export async function atualizarGeracao(id, partial) {
  const result = await storageGet("light_geracoes");
  const geracoes = result.light_geracoes || [];
  const idx = geracoes.findIndex(g => g.id === id);
  if (idx >= 0) {
    geracoes[idx] = { ...geracoes[idx], ...partial, updated_at: new Date().toISOString() };
    await storageSet({ light_geracoes: geracoes });
  }
}

/**
 * Remove geracao por ID.
 * @param {number} id
 */
export async function removerGeracao(id) {
  const result = await storageGet("light_geracoes");
  const geracoes = (result.light_geracoes || []).filter(g => g.id !== id);
  await storageSet({ light_geracoes: geracoes });
}

/**
 * Lista geracoes pendentes (status=generating).
 * @returns {Promise<Array>}
 */
export async function geracoesPendentes() {
  const result = await storageGet("light_geracoes");
  const geracoes = result.light_geracoes || [];
  return geracoes.filter(g => g.status === "generating");
}

// ── Prompts Customizados ────────────────────────────────────────────────

/**
 * Lista todos os prompts customizados.
 * @returns {Promise<Array>}
 */
export async function listarPrompts() {
  const result = await storageGet("light_draft_types");
  return result.light_draft_types || [];
}

/**
 * Busca prompt customizado por tipo.
 * @param {string} tipoNome
 * @returns {Promise<object|null>}
 */
export async function buscarPrompt(tipoNome) {
  const prompts = await listarPrompts();
  return prompts.find(p =>
    p.tipo_documento_nome === tipoNome || p.id === tipoNome
  ) || null;
}

/**
 * Salva ou atualiza prompt customizado.
 * @param {object} prompt — {tipo_documento_nome, tipo_documento_id?, prompt, isDefault?}
 */
export async function salvarPrompt(prompt) {
  const prompts = await listarPrompts();
  const idx = prompts.findIndex(p => p.tipo_documento_nome === prompt.tipo_documento_nome);

  const entry = {
    ...prompt,
    updated_at: new Date().toISOString(),
  };

  if (idx >= 0) {
    prompts[idx] = { ...prompts[idx], ...entry };
  } else {
    prompts.push(entry);
  }

  await storageSet({ light_draft_types: prompts });
}

/**
 * Remove prompt customizado.
 * @param {string} tipoNome
 */
export async function removerPrompt(tipoNome) {
  const prompts = (await listarPrompts()).filter(p => p.tipo_documento_nome !== tipoNome);
  await storageSet({ light_draft_types: prompts });
}

// ── Export para debug ───────────────────────────────────────────────────

/**
 * Exporta todo o storage para debug/backup.
 * @returns {Promise<object>}
 */
export async function exportAll() {
  return new Promise((resolve) => {
    chrome.storage.local.get(null, resolve);
  });
}

/**
 * Limpa todo o storage da extensao.
 */
export async function clearAll() {
  const keys = [
    "automattus_light_config",
    "light_generate_request",
    "light_draft_types",
    "light_preferences",
    "light_geracoes",
    "light_geracoes_seq",
  ];
  await storageRemove(keys);
}
