const HIGHLIGHT_STYLE_ID = 'mindspace-change-highlight-style';

export function stripHtmlForHighlight(value: string): string {
  return String(value ?? '')
    .replace(/<script[\s\S]*?<\/script>/gi, ' ')
    .replace(/<style[\s\S]*?<\/style>/gi, ' ')
    .replace(/<[^>]+>/g, ' ')
    .replace(/\s+/g, ' ')
    .trim();
}

export function findChangedTextSegment(before: string, after: string): string | null {
  const previous = stripHtmlForHighlight(before);
  const next = stripHtmlForHighlight(after);
  if (!next || previous === next) return null;

  let start = 0;
  while (start < previous.length && start < next.length && previous[start] === next[start]) {
    start += 1;
  }

  let endPrevious = previous.length;
  let endNext = next.length;
  while (
    endPrevious > start &&
    endNext > start &&
    previous[endPrevious - 1] === next[endNext - 1]
  ) {
    endPrevious -= 1;
    endNext -= 1;
  }

  const segment = next.slice(start, endNext).trim();
  if (segment.length < 2) return null;
  return segment.slice(0, 160);
}

function ensureHighlightStyles(doc: Document) {
  if (doc.getElementById(HIGHLIGHT_STYLE_ID)) return;
  const style = doc.createElement('style');
  style.id = HIGHLIGHT_STYLE_ID;
  style.textContent = `
    .mindspace-change-highlight {
      background: rgba(255, 214, 102, 0.58);
      box-shadow: 0 0 0 2px rgba(255, 170, 0, 0.42);
      border-radius: 4px;
      animation: mindspace-change-pulse 1.1s ease-in-out 2;
    }
    .mindspace-change-flash {
      animation: mindspace-page-flash 0.85s ease-in-out 2;
    }
    @keyframes mindspace-change-pulse {
      0%, 100% { filter: brightness(1); }
      50% { filter: brightness(1.08); }
    }
    @keyframes mindspace-page-flash {
      0%, 100% { box-shadow: inset 0 0 0 0 rgba(255, 190, 60, 0); }
      50% { box-shadow: inset 0 0 0 4px rgba(255, 190, 60, 0.35); }
    }
  `;
  doc.head?.appendChild(style);
}

function wrapFirstTextMatch(doc: Document, root: ParentNode, snippet: string): boolean {
  const needle = snippet.trim();
  if (!needle) return false;

  const candidates = [needle, needle.slice(0, 80), needle.slice(0, 40)].filter(
    (value, index, list) => value.length >= 2 && list.indexOf(value) === index,
  );

  const walker = doc.createTreeWalker(root, NodeFilter.SHOW_TEXT);
  let node = walker.nextNode() as Text | null;
  while (node) {
    const raw = node.textContent ?? '';
    for (const candidate of candidates) {
      const index = raw.indexOf(candidate);
      if (index === -1) continue;
      const mark = doc.createElement('mark');
      mark.className = 'mindspace-change-highlight';
      const range = doc.createRange();
      range.setStart(node, index);
      range.setEnd(node, index + candidate.length);
      range.surroundContents(mark);
      return true;
    }
    node = walker.nextNode() as Text | null;
  }

  return false;
}

function highlightTitleChange(doc: Document): boolean {
  const selectors = ['h1', 'header h1', '.page-title', '.hero-title', 'title'];
  for (const selector of selectors) {
    const element = doc.querySelector(selector);
    if (!element) continue;
    element.classList.add('mindspace-change-highlight');
    return true;
  }
  return false;
}

export function applyPageChangeHighlight(
  doc: Document,
  input: {
    previousTitle: string;
    nextTitle: string;
    previousContent: string;
    nextContent: string;
  },
): number {
  ensureHighlightStyles(doc);
  let count = 0;

  const titleChanged = input.previousTitle.trim() !== input.nextTitle.trim();
  const contentChanged = input.previousContent !== input.nextContent;

  if (titleChanged && highlightTitleChange(doc)) {
    count += 1;
  }

  if (contentChanged) {
    const segment = findChangedTextSegment(input.previousContent, input.nextContent);
    if (segment && doc.body && wrapFirstTextMatch(doc, doc.body, segment)) {
      count += 1;
    } else if (doc.body) {
      doc.body.classList.add('mindspace-change-flash');
      count += 1;
    }
  } else if (titleChanged && count === 0 && doc.body) {
    doc.body.classList.add('mindspace-change-flash');
    count += 1;
  }

  const first = doc.querySelector('.mindspace-change-highlight');
  first?.scrollIntoView({ behavior: 'smooth', block: 'center' });

  window.setTimeout(() => {
    doc.querySelectorAll('mark.mindspace-change-highlight').forEach((element) => {
      const parent = element.parentNode;
      if (!parent) return;
      while (element.firstChild) {
        parent.insertBefore(element.firstChild, element);
      }
      parent.removeChild(element);
    });
    doc.querySelectorAll('.mindspace-change-highlight').forEach((element) => {
      element.classList.remove('mindspace-change-highlight');
    });
    doc.body?.classList.remove('mindspace-change-flash');
  }, 3200);

  return count;
}
