const textWords = [
  { text: 'come', bbox: { x0: 40, x1: 60 } },
  { text: 'sei', bbox: { x0: 70, x1: 90 } }
];

const chordWords = [
  { text: 'la', bbox: { x0: 65, x1: 75 } },
  { text: 'mi', bbox: { x0: 95, x1: 105 } }
];

function mergeChordsAndLyrics(chordWords: any[], textWords: any[]): string {
  let result = '';
  const chordAssignments = new Map<any, any[]>();

  chordWords.forEach(chord => {
    const chordX = (chord.bbox.x0 + chord.bbox.x1) / 2;
    let closestWord: any = null;
    let minDistance = Infinity;

    textWords.forEach(textWord => {
      const wordXCenter = (textWord.bbox.x0 + textWord.bbox.x1) / 2;
      const dist = Math.abs(chordX - wordXCenter);
      if (dist < minDistance) {
        minDistance = dist;
        closestWord = textWord;
      }
    });

    if (closestWord) {
      if (!chordAssignments.has(closestWord)) {
        chordAssignments.set(closestWord, []);
      }
      chordAssignments.get(closestWord)!.push(chord);
    }
  });

  textWords.forEach((textWord, index) => {
    const assignedChords = chordAssignments.get(textWord) || [];
    
    // Split chords into before and after the word
    const chordsBefore = assignedChords.filter(c => (c.bbox.x0 + c.bbox.x1)/2 <= textWord.bbox.x1);
    const chordsAfter = assignedChords.filter(c => (c.bbox.x0 + c.bbox.x1)/2 > textWord.bbox.x1);

    chordsBefore.sort((a, b) => a.bbox.x0 - b.bbox.x0);
    chordsAfter.sort((a, b) => a.bbox.x0 - b.bbox.x0);

    chordsBefore.forEach(chord => {
      const cleanChord = chord.text.replace(/[\(\)\[\]]/g, '').toUpperCase();
      result += `[${cleanChord}]`;
    });

    result += textWord.text;

    chordsAfter.forEach(chord => {
      const cleanChord = chord.text.replace(/[\(\)\[\]]/g, '').toUpperCase();
      result += `[${cleanChord}]`;
    });

    if (index < textWords.length - 1) {
      result += ' ';
    }
  });

  return result;
}

console.log(mergeChordsAndLyrics(chordWords, textWords));
