(function () {


function parse_query (q) {
  return (
    q
    .slice(1)
    .split('&')
    .map((part) => (
      part.split('=')
    ))
    .filter(x => x.length == 2)
    .reduce((obj, keyValue) => (Object.assign({}, obj, {
      [keyValue[0]]: decodeURIComponent(keyValue[1]),
    })), {})
  )
}


function index_bundle (list, index) {
  if (!list.length) {return []}
  let bundles = []
  let offset = 0
  let value = list[0].item[index]
  for (var i = 0; i < list.length; i++) {
    if (list[i].item[index] != value) {
      offset++
      value = list[i].item[index]
    }
    if (offset > bundles.length - 1) {
      bundles[offset] = []
    }
    bundles[offset].push(list[i])
  }
  return bundles
}


const indexed_sections = [];
let last_sticky_index = -1;

function handle_whats_on_scroll () {
  if (!indexed_sections.length) {
    return;
  }

  let idx = -1;

  for (let i=0; i<indexed_sections.length; i++) {
    if (indexed_sections[i].getBoundingClientRect().top < 0) {
      idx = i;
    }
  }

  if (idx != last_sticky_index) {
    if (last_sticky_index != -1 && last_sticky_index < indexed_sections.length) {
      indexed_sections[last_sticky_index].classList.remove('active');
      indexed_sections[last_sticky_index].sticky_index_el.style.transform = '';
    }

    if (idx != -1) {
      indexed_sections[idx].classList.add('active');
    }

    last_sticky_index = idx;
  }

  if (last_sticky_index != -1 && last_sticky_index+1 < indexed_sections.length) {
    const rect = indexed_sections[last_sticky_index+1].getBoundingClientRect();
    if (rect.top < rect.height) {
      indexed_sections[last_sticky_index].transformed = true;
      indexed_sections[last_sticky_index].sticky_index_el.style.transform = 'translateY('+(rect.top - rect.height)+'px)';
    }
    else if (indexed_sections[last_sticky_index].transformed) {
      indexed_sections[last_sticky_index].transformed = false;
      indexed_sections[last_sticky_index].sticky_index_el.style.transform = '';
    }
  }

}


/*
 * State
 */


const state = {
  events: [],
  passThru: null,
  is_sticky_filter_visible: false,
  valid_dates: null,
}


/*
 * DOM
 */


const whats_on_page = document.createElement('div');
const loader_cont = document.createElement('div');
const events_cont = document.createElement('div');
const filters_cont = document.createElement('div');
const sticky_filter_cont = document.createElement('div');



/*
 * Loader
 */


function render_loader () {
  loader_cont.style.display = 'none';
  loader_cont.className = 'whats_on_loader_cont';
  whats_on_page.appendChild(loader_cont);

  const loader_inner = document.createElement('div');
  loader_inner.className = 'whats_on_loader_inner';
  loader_cont.appendChild(loader_inner);
}


/*
 * Events
 */


function render_events () {
  whats_on_page.appendChild(events_cont);
}


function update_events () {
  events_cont.innerHTML = '';

  if (!state.events.length) {
    const no_results_el = document.createElement('div');
    no_results_el.className = 'no_results selecta_h5';
    no_results_el.innerText = 'No results';
    events_cont.appendChild(no_results_el);
  }

  const bundled_events = index_bundle(state.events, 'index');
  indexed_sections.splice(0, indexed_sections.length);
  for (let i=0; i<bundled_events.length; i++) {
    const index_html = bundled_events[i].length ? bundled_events[i][0].item.index : '';

    const section_cont = document.createElement('div');
    events_cont.appendChild(section_cont);

    const index_cont = document.createElement('div');
    index_cont.className = 'whats_on_index_cont selecta_h5';
    section_cont.appendChild(index_cont);

    indexed_sections.push(index_cont);

    const index_el = document.createElement('div');
    index_el.className = 'whats_on_index';
    index_el.innerHTML = index_html;
    index_cont.appendChild(index_el);

    const sticky_index_el = document.createElement('div');
    sticky_index_el.className = 'whats_on_index whats_on_sticky_index';
    sticky_index_el.innerHTML = index_html;
    index_cont.appendChild(sticky_index_el);

    index_cont.sticky_index_el = sticky_index_el;

    window.render_discovery_stream(section_cont, {items: [bundled_events[i]], mobile2Col: true});
  }
}


/*
 * Filters
 */


const filter_conts = [];


function create_filter () {
  return {
    label: null,
    value: null,
    options: null,
    sticky_dom: {
      filter_cont: null,
      dropdown_el: null,
      label_el: null,
    }
  }
}


const who_filter = create_filter();
const what_filter = create_filter();
const when_filter = create_filter();

who_filter.fetch_results = fetch_results;
what_filter.fetch_results = fetch_results;
when_filter.fetch_results = fetch_results;


function render_filters (root_el) {
  filters_cont.className = 'filters_cont selecta_h5';
  filters_cont.style.display = 'none';
  root_el.appendChild(filters_cont);

  sticky_filter_cont.className = 'sticky_filter_cont';
  filters_cont.appendChild(sticky_filter_cont);

  const filters_toggle = document.createElement('div');
  filters_toggle.className = 'filters_toggle';
  filters_toggle.innerText = 'Filters';
  filters_cont.appendChild(filters_toggle);
  
  filters_toggle.addEventListener('click', function () {
    filters_cont.classList.toggle('active');
    for (let i=0; i<filter_conts.length; i++) {
      filter_conts[i].classList.remove('active');
    }
  });

  window.render_filter(sticky_filter_cont, what_filter.sticky_dom, 'Show', filter_conts);
  window.render_filter(sticky_filter_cont, when_filter.sticky_dom, 'events on', filter_conts);
  window.render_filter(sticky_filter_cont, who_filter.sticky_dom, 'for', filter_conts);
}


const sticky_calendar = {
  dom: when_filter.sticky_dom,
  month: (new Date()).getMonth(),
  year: (new Date()).getFullYear(),
  state: state,
  filter: when_filter,
  filter_conts: filter_conts,
};


/*
 * Fetch
 */


function fetch_results () {

  window.scrollTo(0,0);

  for (let i=0; i<filter_conts.length; i++) {
    filter_conts[i].classList.remove('active');
  }

  filters_cont.classList.remove('active');
  loader_cont.style.display = '';
  events_cont.style.display = 'none';

  let params = Object.assign({}, state.passThru, {
    'show': what_filter.value || '',
    'on': when_filter.value || '',
    'for': who_filter.value || '',
  })

  fetch('/api/query-whats-on/?' + (new URLSearchParams(params)).toString())
  .then(response => response.json())
  .then(data => {
    handle_results_load(data);
  })
}


function handle_results_load ({events, filters}) {
  window.scrollTo(0,0);

  loader_cont.style.display = 'none';
  filters_cont.style.display = '';
  events_cont.style.display = '';

  // Filters
  who_filter.value = filters.for.active.value;
  who_filter.label = filters.for.active.display;
  who_filter.options = filters.for.menu;

  what_filter.value = filters.show.active.value;
  what_filter.label = filters.show.active.display;
  what_filter.options = filters.show.menu;

  when_filter.value = filters.on.active.value;
  when_filter.label = filters.on.active.display;
  when_filter.options = filters.on.menu;

  state.valid_dates = filters.on.valid_dates;

  update_url(what_filter.value, when_filter.value, who_filter.value);


  window.update_filter(who_filter, who_filter.sticky_dom);
  window.update_filter(what_filter, what_filter.sticky_dom);
  window.update_filter(when_filter, when_filter.sticky_dom);
  window.render_calendar(sticky_calendar);



  // Events
  state.events = events.map(event => ({
    type: 'event',
    item: event,
  }));

  update_events();
}


function update_url (what, when, who) {
  let params = Object.assign({}, state.passThru, {
    'show': what,
    'on': when,
    'for': who
  })
  var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' + (new URLSearchParams(params)).toString()

  window.history.pushState({path:newurl},'',newurl)
}



function render_whats_on_page (root_el) {
  window.addEventListener('scroll', handle_whats_on_scroll);

  const q = parse_query(window.location.search);

  what_filter.value = q.show || '';
  when_filter.value = q.on || '';
  who_filter.value = q.for || '';

  delete q.show;
  delete q.on;
  delete q.for;

  state.passThru = q;


  whats_on_page.innerHTML = '';
  whats_on_page.className = 'whats_on_page';
  root_el.appendChild(whats_on_page);


  // Render title and filters
  {
    const row = document.createElement('div');
    row.className = 'row';
    whats_on_page.appendChild(row);

    const col = document.createElement('div');
    col.className = 'col_10 sm_col_11';
    row.appendChild(col);

    const title_cont = document.createElement('div');
    title_cont.className = 'whats_on_title selecta_h1';
    col.appendChild(title_cont);

    const h1 = document.createElement('h1');
    h1.innerHTML = 'Upcoming';
    title_cont.appendChild(h1);

    const breadcrumb_cont = document.createElement('div');
    breadcrumb_cont.className = 'whats_on_page__breadcrumb_cont selecta_h6';
    title_cont.appendChild(breadcrumb_cont);

    const breadcrumb_link_0 = document.createElement('a');
    breadcrumb_link_0.className = 'whats_on_page__breadcrumb_link';
    breadcrumb_link_0.href = '/';
    breadcrumb_link_0.innerText = 'Home';
    breadcrumb_cont.appendChild(breadcrumb_link_0);

    const breadcrumb_sep = document.createElement('div');
    breadcrumb_sep.className = 'whats_on_page__breadcrumb_sep';
    breadcrumb_sep.innerHTML = '&sdot;';
    breadcrumb_cont.appendChild(breadcrumb_sep);

    const breadcrumb_link_1 = document.createElement('a');
    breadcrumb_link_1.className = 'whats_on_page__breadcrumb_link';
    breadcrumb_link_1.href = '/events-programs';
    breadcrumb_link_1.innerText = 'Events & programs';
    breadcrumb_cont.appendChild(breadcrumb_link_1);


    render_filters(col);
  }

  render_loader();
  render_events();

  fetch_results();
}


window.render_whats_on_page = render_whats_on_page;

})();
