function mergeChecklistConflict({ baseBody, localBody, remoteBody, operations = [] }) {
  const taskPattern = /^(\s*[-*+]\s+\[)([ xX])(\]\s+)(.*)$/;

  function tasks(body) {
    const entries = [];
    String(body || '').split('\n').forEach((line, lineIndex) => {
      const match = line.match(taskPattern);
      if (!match) return;
      const label = match[4].trim();
      const key = label.replace(/\s+/g, ' ').toLocaleLowerCase();
      if (!key) return;
      entries.push({ key, label, checked: match[2].toLowerCase() === 'x', lineIndex, match });
    });
    return entries;
  }

  function grouped(entries) {
    const result = new Map();
    entries.forEach(entry => result.set(entry.key, [...(result.get(entry.key) || []), entry]));
    return result;
  }

  function replayOperations(body, requested, reportChanges) {
    let lines = String(body || '').split('\n');
    const visibleTasks = value => tasks(value).filter(entry => /^[-*+]/.test(entry.match[1]));
    const logical = visibleTasks(baseBody).map(entry => ({ key:entry.key, label:entry.label }));
    const replayed = [];
    for (const operation of requested) {
      const index = Number(operation?.index);
      const target = logical[index];
      if (!target) return { body:null, changes:replayed, conflict:{ label:'Checklist step', reason:'missing' } };
      let entries = visibleTasks(lines.join('\n'));
      const matches = entries.filter(entry => entry.key === target.key);
      if (matches.length !== 1) {
        return { body:null, changes:replayed, conflict:{
          label:target.label, reason:matches.length ? 'ambiguous' : 'missing',
        } };
      }
      const match = matches[0];
      if (operation.action === 'rename') {
        const label = String(operation.label || '').trim().replace(/\s+/g, ' ');
        const key = label.toLocaleLowerCase();
        if (!label || entries.some(entry => entry.key === key && entry.lineIndex !== match.lineIndex)) {
          return { body:null, changes:replayed, conflict:{ label:target.label, reason:'ambiguous' } };
        }
        lines[match.lineIndex] = match.match[1] + match.match[2] + match.match[3] + label;
        if (reportChanges) replayed.push({ label:target.label, renamed:label });
        target.label = label;
        target.key = key;
      } else if (operation.action === 'remove') {
        lines.splice(match.lineIndex, 1);
        logical.splice(index, 1);
        if (reportChanges) replayed.push({ label:target.label, removed:true });
      } else if (operation.action === 'move-earlier' || operation.action === 'move-later') {
        const neighborIndex = operation.action === 'move-earlier' ? index - 1 : index + 1;
        const neighbor = logical[neighborIndex];
        const neighborMatches = neighbor ? entries.filter(entry => entry.key === neighbor.key) : [];
        if (neighborMatches.length !== 1 || Math.abs(neighborMatches[0].lineIndex - match.lineIndex) !== 1) {
          return { body:null, changes:replayed, conflict:{ label:target.label, reason:'order-changed' } };
        }
        const neighborLine = neighborMatches[0].lineIndex;
        [lines[match.lineIndex], lines[neighborLine]] = [lines[neighborLine], lines[match.lineIndex]];
        [logical[index], logical[neighborIndex]] = [logical[neighborIndex], logical[index]];
        if (reportChanges) replayed.push({
          label:target.label, moved:operation.action === 'move-earlier' ? 'earlier' : 'later',
        });
      }
    }
    return { body:lines.join('\n'), changes:replayed, conflict:null };
  }

  if (Array.isArray(operations) && operations.length) {
    const baseReplay = replayOperations(baseBody, operations, false);
    const remoteReplay = replayOperations(remoteBody, operations, true);
    const conflict = baseReplay.conflict || remoteReplay.conflict;
    if (conflict) return { body:null, changes:remoteReplay.changes || [], conflicts:[conflict] };
    const residual = mergeChecklistConflict({
      baseBody:baseReplay.body, localBody, remoteBody:remoteReplay.body,
    });
    return {
      body:residual.body,
      changes:[...remoteReplay.changes, ...residual.changes],
      conflicts:residual.conflicts,
    };
  }

  const base = grouped(tasks(baseBody));
  const local = grouped(tasks(localBody));
  const remoteEntries = tasks(remoteBody);
  const remote = grouped(remoteEntries);
  const changes = [];
  const conflicts = [];

  for (const [key, baseMatches] of base) {
    const localMatches = local.get(key) || [];
    if (baseMatches.length !== 1 || localMatches.length !== 1) continue;
    if (baseMatches[0].checked === localMatches[0].checked) continue;
    const remoteMatches = remote.get(key) || [];
    if (remoteMatches.length !== 1) {
      conflicts.push({
        label: baseMatches[0].label,
        reason: remoteMatches.length ? 'ambiguous' : 'missing',
      });
      continue;
    }
    changes.push({ label: remoteMatches[0].label, checked: localMatches[0].checked });
  }

  for (const [key, localMatches] of local) {
    if (base.has(key)) continue;
    if (localMatches.length !== 1) {
      conflicts.push({ label:localMatches[0].label, reason:'ambiguous' });
      continue;
    }
    const remoteMatches = remote.get(key) || [];
    if (remoteMatches.length > 1) {
      conflicts.push({ label: localMatches[0].label, reason: 'ambiguous' });
      continue;
    }
    if (remoteMatches.length === 0) {
      changes.push({ label: localMatches[0].label, checked:localMatches[0].checked, added:true });
    }
  }

  if (conflicts.length) return { body: null, changes, conflicts };
  const desired = new Map(changes.map(change => [
    change.label.replace(/\s+/g, ' ').toLocaleLowerCase(), change.checked,
  ]));
  const lines = String(remoteBody || '').split('\n');
  remoteEntries.forEach(entry => {
    if (!desired.has(entry.key)) return;
    const marker = desired.get(entry.key) ? 'x' : ' ';
    lines[entry.lineIndex] = entry.match[1] + marker + entry.match[3] + entry.match[4];
  });
  changes.filter(change => change.added).forEach(change => {
    lines.push('- [' + (change.checked ? 'x' : ' ') + '] ' + change.label);
  });
  return { body: lines.join('\n'), changes, conflicts: [] };
}

if (typeof module !== 'undefined') module.exports = mergeChecklistConflict;
