var bookletNames = [
  'nadal2020joves',
  'nadal2020nens',
];

var interval = null;
var isBookletShown = false;

function showSection(section) {
  document.querySelectorAll('section').forEach(el => {
    if (el.id === section)
      el.removeAttribute('hidden');
    else
      el.setAttribute('hidden', '');
  });
}

function songElement(song) {
  var div = document.createElement('div');
  div.classList.add('song');

  var title = document.createElement('h3');
  title.classList.add('song-title');
  title.textContent = song.title;

  var author = document.createElement('div');
  author.classList.add('song-author');
  author.textContent = song.author;

  var performers = document.createElement('div');
  performers.classList.add('performers');

  song.performers.forEach(performer => {
    var item = document.createElement('div');
    item.classList.add('performers-item');

    var span = document.createElement('span');
    span.classList.add('instrument');
    span.textContent = performer.instrument;

    var people = document.createTextNode(': ' + performer.names.join(', '));

    item.append(span, people);
    performers.append(item);
  });

  div.append(title, author, performers);
  return div;
}

function loadBooklet(booklet, showBackButton = false) {
  console.info('Booklet: ', booklet);

  document.getElementById('concert-title').textContent = booklet.title;
  document.getElementById('concert-subtitle').textContent = booklet.subtitle;

  var bookletContent = document.getElementById('booklet-content');
  bookletContent.textContent = '';
  booklet.songs.forEach(song => {
    var songEl = songElement(song);
    bookletContent.append(songEl);
  });

  showSection('booklet');
  if (showBackButton)
    document.getElementById('previous-concerts-btn').removeAttribute('hidden');
}

function loadPreviousBookletsList(booklets) {
  var now = Date.now();
  var list = document.getElementById('previous-concerts-list');

  var existsPreviousConcert = false;
  booklets.forEach(booklet => {
    if (booklet.ends * 1000 <= now) {
      existsPreviousConcert = true;

      var el = document.createElement('div');
      el.classList.add('concert');

      var title = document.createElement('div');
      title.classList.add('concert-title');
      title.textContent = booklet.title;

      var subtitle = document.createElement('div');
      subtitle.classList.add('concert-subtitle');
      subtitle.textContent = booklet.subtitle;

      var view = document.createElement('button');
      view.classList.add('concert-btn', 'linkify');
      view.textContent = 'Obre el programa';

      el.append(title, subtitle, view);

      el.addEventListener('click', _ => {
        loadBooklet(booklet, true);
      });

      list.append(el);
    }
  });

  if (existsPreviousConcert)
    document.getElementById('previous-concerts-btn').removeAttribute('hidden');
}

function checkBooklets(booklets) {
  if (isBookletShown)
    return;

  var now = Date.now();
  var latest = null;
  booklets.forEach(booklet => {
    if (booklet['begins'] * 1000 <= now && booklet['ends'] * 1000 >= now &&
        (latest === null || latest['begins'] < booklet['begins']))
      latest = booklet;
  });

  if (latest !== null) {
    document.getElementById('previous-concerts-btn').setAttribute('hidden', '');
    loadBooklet(latest);
    window.clearInterval(interval);
    isBookletShown = true;
  }
}

function showUpdateFooter() {
  document.getElementById('update-available').removeAttribute('hidden');
}

window.addEventListener('load', _ => {
  document.getElementById('previous-concerts-btn')
      .addEventListener('click', e => {
        showSection('previous-concerts');
        document.getElementById('previous-concerts-btn')
            .setAttribute('hidden', '');
      });

  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js')
        .then(reg => {
          reg.addEventListener('updatefound', _ => {
            showUpdateFooter();
          });

          var promises = [];
          bookletNames.forEach(name => {
            var p = fetch('concerts/' + name + '.json').then(res => res.json());
            promises.push(p);
          });

          Promise.all(promises).then(booklets => {
            showSection('wait-screen');
            loadPreviousBookletsList(booklets);
            checkBooklets(booklets);
            interval = window.setInterval(_ => {
              checkBooklets(booklets);
            }, 15 * 1000);
          });
        })
        .catch(err => {
          showSection('cant-install');
          console.error('The service worker failed to be registered.');
        });
  } else {
    showSection('no-service-worker');
  }
});
