var sortState = {
  sortBy: "sortArtist",
  sortOrder: "asc",
};

function init() {
  fetch("/api/records")
    .then((response) => response.json())
    .then((records) => {
      // prepare response
      records.forEach(apiResponseParsing);
      document.getElementById("search").addEventListener("input", (e) => {
        renderTable(search(records, e.target.value));
      });
      renderTable(records);
    });
}

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

  // rendering
  var recordElement = document.getElementById("records");
  recordElement.innerHTML = TableTemplate(records);

  var recordCount = document.getElementById("recordCount");
  recordCount.innerHTML = `${records.length} records`;

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

function apiResponseParsing(record) {
  record.sortName = titleCleaner(record.name);
  record.artists = record.artists.map((artist) => {
    return artist.replace(/ \([0-9]+\)$/, "");
  });
  record.label = record.label.replace(/ \([0-9]+\)$/, "");
  record.sortArtist = record.artists.reduce((acc, curr) => {
    return (
      acc +
      curr
        .replace(/^(An?|The)\s/i, "")
        .toLowerCase()
        .replaceAll('"', "")
        .replaceAll(":", "")
        .replaceAll("'", "")
        .replaceAll(" ", "")
    );
  }, "");
  return record;
}

function search(records, searchBy) {
  searchBy = searchCleaner(searchBy);
  if (searchBy !== "") {
    records = records.filter(({ name, artists, genre, label, year }) => {
      return Object.values({
        name,
        artists: artists.join(" "),
        genre,
        label,
        year,
      }).find((field) => searchCleaner(field).indexOf(searchBy) !== -1);
    });
  }
  return records;
}

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

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

function RecordTemplate({
  name,
  artists,
  coverURL,
  format,
  genre,
  identifier,
  label,
  year,
  discogsURL,
}) {
  return `${coverURL ? `<img src="${coverURL}" loading="lazy"/>` : ""}
  <h1>${name}</h1>
  <h2>${artists.join(", ")}</h2>
  <span>${identifier}</span><br/>
  <span>${genre}, ${label}, ${year}</span><br/>
  <span>${format}</span><br/>
  <span>
    <a 
      target="_blank"
      href="${discogsURL}"
    >
      Data provided by Discogs.
    </a>
  </span>`;
}

function TableRowTemplate({ name, coverURL, discogsURL }) {
  return `<div class="record">
    <img class="cover" src="${coverURL}" loading="lazy"/>
    <span class="name">${name}</span>
    <a 
      target="_blank"
      href="${discogsURL}"
      class="discogsLink"
    >
      Data provided by Discogs.
    </a>
  </div>`;
}

function TableTemplate(records) {
  return `<div class="flow">${records.reduce((acc, record) => {
    return acc.concat(TableRowTemplate(record));
  }, "")} </div>`;
}
