{% extends "qommon/forms/widget.html" %}
{% load qommon i18n %}
{% block widget-control %}

<select
  id="form_{{widget.name}}"
  name="{{widget.name}}"
  {% for attr in widget.attrs.items %}{{attr.0}}="{{attr.1}}"{% endfor %}
  style="display: none"
>
  <option value="">---</option>
  {% for option in widget.get_options %}
    {% with datetime=option.options.date|parse_datetime %}
    <option
        {% for attr in option.attrs.items %} {{attr.0}}="{{attr.1}}"{% endfor %}
        data-weeknumber="{{ option.options.date_weeknumber }}"
        data-daynumber="{{ option.options.date_number }}"
        data-weekdayindex="{{ option.options.date_weekdayindex }}"
        data-month="{{ option.options.date_month }}"
        data-status="{{ option.options.status }}"
      >
        {{ option.description }}
      </option>
    {% endwith %}
  {% endfor %}
</select>
<div id="form_{{widget.name}}_calendar" class="ens-calendar is-hidden">
</div>

<script>
$(function() {
  const prefix = "ens-calendar--";
  const WEEKDAYS = ["{% trans "Monday" %}", "{% trans "Tuesday" %}",
                    "{% trans "Wednesday" %}", "{% trans "Thursday" %}",
                    "{% trans "Friday" %}", "{% trans "Saturday" %}",
                    "{% trans "Sunday" %}", ];



  const $select = $('#form_{{widget.name}}');
  let $options = $select.find('option');
  const $calendar = $('#form_{{widget.name}}_calendar');
  const $prev_btn = $('<button class="'  + prefix + 'prev" role="button">←</button>');
  const $next_btn = $('<button class="'  + prefix + 'next" role="button">→</button>');
  const activated_day_class = "on";

  let calendar_days;
  let $month_calendars;
  let $day_btns;
  let active_index = 0;

  // map available data
  // if static, data = $options
  // if live, data = json
  const define_calendar_days = function(data) {
    const is$ = data instanceof $;
    let days = data;
    if (is$) {
      days = $.makeArray($options);
    }
    const json_datas = days.map(function(day, idx){
      const date = {};
      date.value = (is$) ? day.value : day.id;
      date.label = (is$) ? day.text : day.details;
      date.number = (is$) ? day.dataset.daynumber : day.date_number ;
      date.weekdayindex = parseInt((is$) ? day.dataset.weekdayindex : day.date_weekdayindex);
      // French weekdayindex : sunday == 7 instead 0
      date.weekdayindex = (date.weekdayindex == 0) ? 7 : date.weekdayindex;
      date.weeknumber = (is$) ? day.dataset.weeknumber : day.date_weeknumber;
      date.month = (is$) ? day.dataset.month : day.date_month;
      date.idx = (is$) ? idx : idx + 1;
      date.status = (is$) ? day.dataset.status : day.status;
      return date;
    }).filter(function(date){
      return date.value;
    });
    return json_datas;
  };

  // render Calendar
  const calendar_layout = function() {
    // Return array of uniq key
    const list_of = function (arr, key) {
      return arr
        .map(function(day){
          return day[key];
        })
        .filter(function(day, idx, days) {
          return days.indexOf(day) === idx;
        });
    }

    const months = list_of(calendar_days, 'month');

    // Generate thead markup of month table
    const days_headers_tpl = function() {
      let days = '';
      const day = WEEKDAYS.forEach(function(el) {
        days += ('<th class="' + prefix + 'weekday">' + el.slice(0, 3) + '</th>');
      });
      return '<thead>'+
                '<tr class="' + prefix + 'weekdays">' + days + '</tr>' +
              '</thead>';
    };

    // Generate tbody markup of month table
    const days_body_tpl = function(month) {

      const day_tpl = function(day) {
        let day_markup = "";
        if (day) {
          const disabled = (day.status === "close") ? 'disabled' : "";
          let selectedClass = "";
          if ($options[day.idx].selected) {
            selectedClass = activated_day_class;
            // Change active_index to display correct month
            active_index = months.indexOf(month);
          }
          day_markup += '<td class="' + prefix + 'day">' +
                          '<button ' +
                            'role="button"'+
                            'title="' + day.label + '"' +
                            'class="' + prefix + 'day-btn ' + selectedClass +'"' +
                            'data-option-idx="' + day.idx + '"' +
                            'data-status="' + day.status + '"' +
                            disabled + '>' +
                            day.number +
                          '</button>' +
                        '</td>';
        } else {
          day_markup += '<td class="' + prefix +'day is-empty"></td>'
        }
        return day_markup;
      };

      const days_of_month = calendar_days.filter(function(day) {
          return day.month === month;
      });
      const weeks_of_month = list_of(days_of_month, "weeknumber");

      let weeks_markup = '';

      weeks_of_month.forEach(function(weeknumber) {
        let days_markup = "";
        const days_of_week = days_of_month.filter(function(day) {
          return day.weeknumber === weeknumber;
        });
        // empty days before
        const first_position = days_of_week[0].weekdayindex;
        for (let i = 1; i < first_position; i++) {
          days_markup += day_tpl();
        }
        // days of week
        days_of_week.forEach(function(day) {
          days_markup += day_tpl(day);
        });
        // empty days after
        const last_position = days_of_week[days_of_week.length - 1].weekdayindex;
        for (let i = last_position; i < 7; i++) {
          days_markup += day_tpl();
        }
        // week raw
        weeks_markup += '<tr class="' + prefix + 'week">' + days_markup + '</tr>';
      });
      return '<tbody>' + weeks_markup +'</tbody>';
    };

    // render month
    const $month_tpl = function (month) {
      const $month_calendar = $('<div class="ens-calendar--month is-hidden">' +
          '<strong class="ens-calendar--head">' + month + '</strong>' +
          '<table>' +
            days_headers_tpl() +
            days_body_tpl(month) +
          '</table>' +
        '</div>');

      $month_calendars = $month_calendars.add($month_calendar);
      $month_day_btns = $month_calendar.find('.' + prefix + 'day-btn');
      $day_btns = $day_btns.add($month_day_btns);

      return $month_calendar;
    };

    // render calendar
    const render_calendar = function() {
      $calendar.empty();
      months.forEach(function(month){
        $month_tpl(month).appendTo($calendar);
        $prev_btn.add($next_btn).appendTo($calendar);
      });
    };

    return render_calendar();
  };

  // Go to
  const goto = function(index) {
    $month_calendars.addClass('is-hidden');
    $prev_btn.add($next_btn).prop('disabled', null);
    max = $month_calendars.length - 1;

    switch (index) {
      case 0:
        $prev_btn.prop('disabled', true); break;
      case max :
        $next_btn.prop('disabled', true); break;
    }

    $month_calendars.eq(index).removeClass('is-hidden');
    active_index = index;
  };

  const init = function() {
    $calendar.addClass('is-hidden');
    $month_calendars = $();
    $day_btns = $();
    calendar_layout();
    goto(active_index);
    $calendar.removeClass('is-hidden');
    // events
    $prev_btn.click(function(e){
      e.preventDefault();
      goto(active_index - 1);
    });

    $next_btn.click(function(e){
      e.preventDefault();
      goto(active_index + 1);
    });

    $day_btns.click(function(e){
      e.preventDefault();
      $day_btns.removeClass(activated_day_class);
      $options.eq(this.dataset.optionIdx).prop('selected', true);
      $select.trigger('wcs:change');
      $(this).addClass(activated_day_class);
    });
  };

  // if Static
  if ($options.length > 1) {
    calendar_days = define_calendar_days($options);
    init();
  }

  // if $select is filled live
  $select.on('wcs:options-change', function(ev, data) {
    if (!data) return;
    calendar_days = define_calendar_days(data.items);
    $('<option value=""></option>').prependTo($select);
    $options = $select.find('option');
    init();
    $select.trigger('wcs:change');
  });

});
</script>
{% if request.quixote_request.is_in_backoffice %}
<style>
.ens-calendar.is-hidden,
.ens-calendar--month.is-hidden {
  display: none !important;
}
.ens-calendar {
  position: relative;
  width: 350px;
}
.ens-calendar--head {
  text-align: center;
  display: block;
  height: 3em;
  padding-left: 3em;
  padding-right: 3em;
}
.ens-calendar--day-btn[data-status=open] {
  color: green;
}
.ens-calendar--day-btn[data-status=open]:hover,
.ens-calendar--day-btn[data-status=open].on {
  background-color: green;
  color: white;
}
.ens-calendar--day-btn[data-status=partially-open] {
  color: orange;
}
.ens-calendar--day-btn[data-status=partially-open]:hover,
.ens-calendar--day-btn[data-status=partially-open].on {
  background-color: orange;
  color: white;
}
.ens-calendar--day-btn[data-status=close] {
  color: red;
}
.ens-calendar--day-btn[data-status=close]:hover,
.ens-calendar--day-btn[data-status=close].on {
  background-color: red;
  color: white;
}

.ens-calendar--next, .ens-calendar--prev {
  position: absolute;
  top: 0;
  margin: 0;
}
.ens-calendar--next {
  right: 0;
}
.ens-calendar--prev {
  left: 0;
}
</style>
{% endif %}
{% endblock %}

{% block widget-hint %}
{% if widget.hint %}<div class="hint">{{widget.hint}}</div>{% endif %}
{% endblock %}
