function escapeMetaAttribute(value) {
  return String(value ?? '')
    .replaceAll('&', '&amp;')
    .replaceAll('"', '&quot;')
    .replaceAll('<', '&lt;');
}

export function parseMindspaceCoverMeta(html) {
  const tag = String(html).match(/<meta[^>]*name=["']mindspace-cover["'][^>]*>/i)?.[0];
  if (!tag) return null;
  const contentMatch =
    tag.match(/content=(["'])([\s\S]*?)\1/i) ?? tag.match(/content=["']([^"']+)["']/i);
  const raw = contentMatch?.[2] ?? contentMatch?.[1];
  if (!raw) return null;
  try {
    return JSON.parse(raw.replaceAll('&quot;', '"'));
  } catch {
    return null;
  }
}

export function upsertMindspaceCoverMeta(html, coverMeta) {
  const payload = { ...(parseMindspaceCoverMeta(html) ?? {}), ...coverMeta };
  const metaTag = `<meta name="mindspace-cover" content="${escapeMetaAttribute(JSON.stringify(payload))}">`;
  const source = String(html ?? '');

  if (/<meta[^>]*name=["']mindspace-cover["'][^>]*>/i.test(source)) {
    return source.replace(/<meta[^>]*name=["']mindspace-cover["'][^>]*>/i, metaTag);
  }
  if (/<head[^>]*>/i.test(source)) {
    return source.replace(/<head([^>]*)>/i, `<head$1>\n  ${metaTag}`);
  }
  if (/<html[^>]*>/i.test(source)) {
    return source.replace(/<html([^>]*)>/i, `<html$1><head>${metaTag}</head>`);
  }
  return `<!doctype html><html lang="zh-CN"><head>${metaTag}</head><body>${source}</body></html>`;
}

export function normalizeCoverMetaSuggestion(raw) {
  const payload = raw && typeof raw === 'object' ? raw : {};
  const next = {};
  if (payload.tag != null) next.tag = String(payload.tag).trim().slice(0, 12);
  if (payload.emoji != null) next.emoji = String(payload.emoji).trim().slice(0, 4);
  if (payload.accent != null) next.accent = String(payload.accent).trim();
  if (payload.accent2 != null) next.accent2 = String(payload.accent2).trim();
  if (payload.subtitle != null) next.subtitle = String(payload.subtitle).trim().slice(0, 80);
  if (payload.cover != null) next.cover = String(payload.cover).trim().slice(0, 512);
  if (payload.image != null && !next.cover) next.cover = String(payload.image).trim().slice(0, 512);
  if (payload.mood != null) next.mood = String(payload.mood).trim().slice(0, 24);
  return next;
}
