<!-- The default language selector.  This is moved into the datatables toolbar during setup. -->
<select id="defaultLanguageSelect" class="dataTables_filter" title="Default language">
  {% for lang_choice in language_choices %}
    <option value="{{ lang_choice[0] }}">{{ lang_choice[1] }}</option>
  {% endfor %}
</select>

<table id="booktable" class="table dataTable stripe">
  <thead>
    <tr>
      <th style="text-align: left">Title</th>
      <th style="text-align: left">Language</th>
      <th style="text-align: left">Tags</th>
      <th style="text-align: left">Word count</th>
      <th style="text-align: left">Statuses
        <a href="/refresh_all_stats" class="refresh" title="Refresh stats for all books"></a>
      </th>
      <th style="text-align: left">Actions</th>
    </tr>
  </thead>
</table>

<!-- the config widget for datatables.  Moved into the datatables table footer during setup. -->
<div id="datatables_config_widget">
  <img
    src="{{ url_for('static', filename='icn/settings-gear-icon.svg') }}"
    title="configuration"
    id="datatables_config_toggle"
    style="width: 1rem"
    />
</div>

<div id="datatables_config_items" style="display: none;"></div>

{# Hidden form for archive, unarchive, delete. #}
<form id="actionposter" method="post" action="">
</form>

<script>

  /* The book listing. */
  var book_listing_table;

  let setup_book_datatable = function(initial_search) {
    book_listing_table = $('#booktable').DataTable({
      layout: {
        topStart: 'pageLength',
        topEnd: [
          function() {
            return $('#defaultLanguageSelect');
          },
          'search'
        ],
        bottomStart: [
          function() {
            return $('#datatables_config_widget');
          },
          {
            info: {
              callback: function (s, start, end, max, total, result) {
                return `${start} to ${end} of ${max}`;
              }
            }
          },
          'buttons'
        ],
        bottomEnd: 'paging'
      },
      buttons: [
        {
          extend: 'colvis',
          columns: '.colVisToggled'
        }
      ],
      {% if status != 'Archived' %}
      "language": {
            "emptyTable": "No books available. <a href='/book/new'>Create one?</a>"
      },
      {% endif %}
      responsive: true,
      select: false,
      lengthMenu: [ 10, 25, 50 ],
      pageLength: 25,
      paging: true,
      info: true,
      searching: true,
      processing: true,
      serverSide: true,
      stateSave: true,
      search: { search: initial_search },
      columnDefs: [
        { "name": "BkTitle", "targets": 0, "width": "40%", "render": render_book_title, className: "colVisToggled" },
        { "name": "LgName", "targets": 1, "width": "10%", className: "colVisToggled" },
        { "name": "TagList", "targets": 2, "width": "10%", className: "colVisToggled" },
        { "name": "WordCount", "targets": 3, "width": "10%", className: "colVisToggled" },
        { "name": "UnknownPercent", "targets": 4, "data": null, "searchable": true, "orderable": true, "render": render_book_stats_graph, className: "colVisToggled" },
        { "targets": 5, "data": null, "width": "8%", "searchable": false, "orderable": false, "render": render_book_actions, className: "colVisToggled" },

        /* Extra data that is returned in the row for rendering, but not shown, not changed by colvis. */
        { "name": "BkID", "targets": 6, "data": null, "visible": false },
        { "name": "BkArchived", "targets": 7, "data": null, "visible": false },
        { "name": "PageCount", "targets": 8, "data": null, "visible": false },
        { "name": "PageNum", "targets": 9, "data": null, "visible": false },
        { "name": "IsCompleted", "targets": 10, "data": null, "visible": false },
        { "name": "StatusDistribution", "targets": 11, "data": null, "visible": false },
      ],

      // Ajax call
      ajax: {
        url: "/book/datatables/{{ status or 'active' }}",
        // Additional filters.  func calls are required to get the
        // current filter field values.  These are included in the
        // data sent to the controller.
        data: {
          filtLanguage: () => $("#defaultLanguageSelect").val(),
        },

        type: "POST",
        dataType: "json"
      },

    });

    // var dropdown = $('#defaultLanguageSelect');
    // $('div.toolbar').append(dropdown);
  } // end setup_book_datatable


  let setup_language_filter = function(current_language_id = 0) {
    const dropdown = $('#defaultLanguageSelect');
    dropdown.val(current_language_id);
    const lang_count = $("#defaultLanguageSelect option").length;
    if (lang_count == 1) {
      dropdown.css("display", "none");
    }

    dropdown.on('change', function() {
      const langid = $(this).val();
      $.post(`/settings/set/current_language_id/${langid}`);
      $('#booktable').DataTable().draw();
    });
  };


  let move_datatables_controls_to_config_widget = function() {
    const widget = $('#datatables_config_items');
    const append_children = [ '.dt-buttons', '.dt-length' ];
    for (let c of append_children) {
      const el = $(`div${c}`);
      el.css({ padding: '0.2rem', margin: '0rem', display: 'inline' });
      widget.append(el);
    }
  }

  $(document).ready(function () {
    const current_language_id = {{ current_language_id }};
    // Language filter is set up first, because its value
    // is used during the initial datatable draw.
    setup_language_filter(current_language_id);
    setup_book_datatable("{{ initial_search or '' }}");

    move_datatables_controls_to_config_widget();

    $("#datatables_config_toggle").click(function() {
      $("#datatables_config_items").toggle();
    });
  });


  function do_action_post(action, bookid) {
    let f = $('#actionposter');
    f.attr('action', `/book/${action}/${bookid}`);
    f.submit();
  }

  function confirm_archive(el) {
    const booktitle = decodeURIComponent($(el).data('bktitle'));
    const bookid = $(el).data('bkid');
    if (!confirm(`Archiving "${booktitle}".  Click OK to proceed, or Cancel.`)) {
      return;
    }
    do_action_post('archive', bookid);
  }

  function confirm_unarchive(el) {
    const bookid = $(el).data('bkid');
    do_action_post('unarchive', bookid);
  }

  //  function confirm_reparse(bookid) {
  //    if (!confirm(`Reparse the book using parsing rules defined for its language.  This will also reset you to the first page of the book.  Click OK to proceed, or Cancel.`)) {
  //      return;
  //    }
  //    do_action_post('reparse', bookid);
  //  }

  function edit_book(el) {
    const bookid = $(el).data('bkid');
    document.location = `/book/edit/${bookid}`;
  }

  function confirm_delete(el) {
    const booktitle = decodeURIComponent($(el).data('bktitle'));
    const bookid = $(el).data('bkid');
    if (!confirm(`Deleting "${booktitle}".  Click OK to proceed, or Cancel.`)) {
      return;
    }
    do_action_post('delete', bookid);
  }

  let render_book_title = function ( data, type, row, meta ) {
    const bkid = parseInt(row[5]);
    const pgnum = parseInt(row[8]);
    const pgcount = parseInt(row[7]);
    let pgfraction = '';

    const completed = (parseInt(row[9]) == 1);
    let book_title_classes = ['book-title'];
    if (completed) {
      book_title_classes.push('completed_book');
    }
    else if (pgnum > 1) {
      pgfraction = ` (${pgnum}/${pgcount})`;
    }

    return `<a class="${book_title_classes.join(' ')}" href="/read/${bkid}">${row[0]}${pgfraction}</a>`;
  };


  let render_book_stats_graph = function(data, type, row, meta) {
    const empty_stats = `<div title="Please open the book to calculate stats">&nbsp;</div>`;
    let statuscounts = row[10];
    if ((statuscounts ?? '')== '') {
      return empty_stats;
    }
    try {
      statuscounts = JSON.parse(statuscounts);
    }
    catch(err) {
      console.log(`Invalid json: ${statuscounts}`);
      return empty_stats;
    }

    statuscounts["99"] = statuscounts["98"] + statuscounts["99"];
    delete statuscounts['98'];
    const totalcount = Object.values(statuscounts).reduce((acc, val) => acc + val, 0);
    if (totalcount == 0) {
      return empty_stats;
    }
    const statuspct = {};
    Object.entries(statuscounts).forEach(([key, value]) => {
      let pct = (value * 100.0) / totalcount;
      statuspct[key] = pct.toFixed(0);
    });
    // return JSON.stringify(statuspct);

    let make_bar = function(stid, title) {
      const p = statuspct[stid];
      const msg = `${p}% (${statuscounts[stid]} words)`;
      const smallestP = window.matchMedia("(max-width: 980px)").matches ? 2 : 1;
      let display = "inline-flex"
      if (p < smallestP)
        display = "none";
      return `<div
        class="status-bar${stid} status-bar"
        title="${title}: ${msg}"
        style="flex: ${p}; display: ${display}"
        ></div>`;
    };

    const bar_titles = {
      "0": "Unknown",
      "1": 1, "2": 2, "3": 3, "4": 4, "5": 5,
      "99": "Well Known or Ignored"
    };
    ret = `<div class="status-bar-container">`;
    Object.entries(bar_titles).forEach(([key, title]) => {
      ret += make_bar(key, title);
    });
    ret += `</div>`;
    return ret;
  };


  let render_book_actions = function ( data, type, row, meta ) {
    // TODO zzfuture fix: security - add CSRF token
    const bkid = row[5];
    const bktitle = encodeURIComponent(row[0]);
    const is_active = (row[6] == 0);

    const links = [];
    const make_link = function(label, func) {
      const s = `<a href="#" data-bkid="${bkid}" data-bktitle="${bktitle}" onclick="${func}(this)">${label}</a>`;
      links.push(s);
    };

    make_link('Edit', "edit_book");
    if (is_active) {
      make_link('Archive', "confirm_archive");
    }
    else {
      make_link('Unarchive', "confirm_unarchive");
    }
    make_link('Delete', "confirm_delete");

    return `<div class="book-action-dropdown"><span>&hellip;</span>
      <div class="book-action-dropdown-content">${links.join('')}</div>
    </div>`;
  };

  // added class is used for changing static image to rotating arrow animation
  document.querySelector(".refresh").addEventListener("click", function(e) {
    e.target.classList.add("refreshed");
    e.stopPropagation();
  });

  /**
   * Clearing the state is required for acceptance tests,
   * because otherwise state is accidentally applied to
   * following tests, messing up test results.
   * I tried various things such as setting and clearing
   * the filter input box, but this was the only method
   * that worked reliably.
   * This is called from the lute_test_client.py.
   */
  function clear_datatable_state() {
    book_listing_table.state.clear();
  }
</script>
