<!DOCTYPE html>
<html>
  <head>
    <title>Library</title>
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
    />
    <link rel="stylesheet" href="style.css" />
    <link rel="icon" href="favicon.ico" type="image/x-icon" />
    <link
      href="https://fonts.googleapis.com/css?family=Libre+Baskerville:400,700&display=swap"
      as="style"
      rel="stylesheet preload prefetch"
    />
    <script type="text/javascript">
      var sortState = {
        sortBy: "sortAuthor",
        sortOrder: "asc",
      };

      function init() {
        fetch("/api")
          .then((response) => response.json())
          .then((books) => {
            // prepare response
            books.forEach((book) => {
              book.sortTitle = titleCleaner(book.title);
              if (!book["isbn-10"] && book["isbn-13"]) {
                book["isbn-10"] = ISBNfromEAN(book["isbn-13"]);
              }
              if (!book.coverurl && book["isbn-10"]) {
                book.coverurl =
                  `https://images-na.ssl-images-amazon.com/images/P/` +
                  book["isbn-10"] +
                  `.01.LZZ.jpg`;
              }
            });
            return books;
          })
          .then((books) => {
            document.getElementById("search").addEventListener("input", (e) => {
              search(books, e.target.value);
            });
            return books;
          })
          .then(renderTable);
      }

      function search(books, searchBy) {
        searchBy = searchCleaner(searchBy);
        if (searchBy !== "") {
          books = books.filter(
            ({ title, authors, genre, publisher, series, year }) => {
              return Object.values({
                title,
                authors: authors.join(" "),
                genre,
                publisher,
                series,
                year,
              }).find((field) => searchCleaner(field).indexOf(searchBy) !== -1);
            }
          );
        }
        renderTable(books);
      }

      function renderTable(books, sortField) {
        if (sortField) {
          if (sortState.sortBy === sortField && sortState.sortOrder === "asc") {
            sortState.sortOrder = "desc";
          } else {
            sortState.sortOrder = "asc";
          }
          sortState.sortBy = sortField;
        }
        books.sort((one, two) =>
          (one[sortState.sortBy] + one["sortTitle"]).localeCompare(
            two[sortState.sortBy] + two["sortTitle"]
          )
        );
        if (sortState.sortOrder === "desc") {
          books.reverse();
        }
        books.forEach((e, i) => (e.rowNumber = i)); // re-key

        // rendering
        var bookElement = document.getElementById("books");
        bookElement.innerHTML = TableTemplate(books);

        // add listeners for selecting book to view
        Array.from(bookElement.querySelectorAll("tbody tr"))
          .slice(1) // remove header from Array
          .forEach((row) => {
            row.addEventListener("click", (e) => {
              // add listener to swap current book
              document.getElementById("current").innerHTML = BookTemplate(
                books[e.currentTarget.id]
              );
            });
          });
        // add sorting callbacks
        Array.from(
          bookElement.querySelectorAll("tbody tr th[data-sort-by]")
        ).forEach((row) => {
          row.addEventListener("click", function (e) {
            renderTable(books, e.target.dataset.sortBy); // only add callback when there's a sortBy attribute
          });
        });
        // mark currently active column
        bookElement
          .querySelector("tbody tr th[data-sort-by=" + sortState.sortBy + "]")
          .classList.add(sortState.sortOrder);
      }

      function titleCleaner(title) {
        return title
          .replace('"', "")
          .replace(":", "")
          .replace(/^(An?|The)\s/i, "");
      }

      function searchCleaner(str) {
        return str
          .toLowerCase()
          .replaceAll('"', "")
          .replaceAll(":", "")
          .replaceAll("'", "")
          .replaceAll(" ", "");
      }

      function ISBNfromEAN(EAN) {
        ISBN = EAN.slice(3, 12);
        var checkdigit =
          (11 -
            (ISBN.split("").reduce((s, n, k) => s + n * (10 - k), 0) % 11)) %
          11;
        return ISBN + (checkdigit === 10 ? "X" : checkdigit);
      }

      function BookTemplate({
        "isbn-13": isbn13,
        authors,
        coverurl,
        description,
        format,
        notes,
        onLoan,
        publisher,
        series,
        signed,
        title,
        volume,
        year,
      }) {
        return `${coverurl ? `<img src="${coverurl}"/>` : ""}
        <h1 ${onLoan ? "class='onLoan' " : ""}>${title}</h1>
        <h2>${authors}</h2>
        <span>${isbn13}</span><br/>
        <span>${publisher}, ${year}</span><br/>
        ${
          series
            ? `<span>${series}${volume ? `, Volume ${volume}` : ""}</span><br/>`
            : ""
        }
        ${signed ? "<span>Signed by the author ✒</span><br/>" : ""}
        <span>${format}</span>
        ${onLoan ? `<h2 class="onLoan">On loan to ${onLoan}</h2>` : ""}
        <div class="description">
          <p>${description}</p>
          ${notes ? `<span>Notes:</span><p>${notes}</p>` : ""}
        </div>`;
      }

      function TableRowTemplate({
        "isbn-13": isbn13,
        authors,
        onLoan,
        publisher,
        rowNumber,
        signed,
        title,
        year,
      }) {
        return `<tr class="tRow ${onLoan ? "onLoan" : ""}" id="${rowNumber}">
          <td class="title">
            ${title} ${
          signed
            ? '<span class="signed" title="Signed by the author" >✒</span>︎'
            : ""
        }
          </td>
          <td class="author">${authors}</td>
          <td class="publisher">${publisher}</td>
          <td class="year">${year}</td>
          <td class="isbn">${isbn13}</td>
        </tr>`;
      }

      function TableTemplate(books) {
        return `<table class="bookTable">
          <tr>
            <th data-sort-by="sortTitle" class="tHeader title">Title</th>
            <th data-sort-by="sortAuthor" class="tHeader author">Author</th>
            <th data-sort-by="publisher" class="tHeader publisher">Publisher</th>
            <th data-sort-by="year" class="tHeader year">Year</th>
            <th class="tHeader isbn">ISBN</th>
          </tr>${books.reduce((acc, book) => {
            return acc.concat(TableRowTemplate(book));
          }, "")} </table>`;
      }

      window.addEventListener("DOMContentLoaded", () => {
        init();
      });
    </script>
  </head>
  <body>
    <div class="wrapper">
      <div id="header">
        <h1>Library</h1>
        <a
          target="_blank"
          rel="noreferrer"
          href="https://git.yetaga.in/alazyreader/library"
          >git</a
        >
        <div id="searchBox">
          <input
            id="search"
            type="text"
            name="search"
            placeholder="Search..."
          />
        </div>
      </div>
      <div id="current">No Book Selected</div>
      <div id="books"></div>
      <!-- Table goes here -->
    </div>
  </body>
</html>