$(function () {
  if (tableData.type === "master-detail") {
    createMasterDetailTable();
  } else if (tableData.type === "show-when-filtered") {
    // Create the table for later use
    createStandardTable();

    // We hide it in the beginning
    $("#datatable").hide();
    $(".text-filter").hide();
  } else {
    createStandardTable();
  }
});

function createMasterDetailTable() {
  var lookup = {};
  var allGeneratedColumns = [];
  var columnProperty = tableData.columns.find(function (x) {
    return x.type === "column";
  });
  var rowProperties = tableData.columns.filter(function (x) {
    return x.type === "item";
  });

  $.each(tableData.items, function (index, item) {
    if (!lookup[item.id]) {
      lookup[item.id] = {
        id: item.id,
        title: item.title,
        generatedColumns: [],
        defaultContent: "",
      };
    }

    var columnName = item[columnProperty.name].content[0];

    if (allGeneratedColumns.indexOf(columnName) === -1) {
      allGeneratedColumns.push(columnName);
    }

    var generatedColumn = {
      rows: [],
    };
    $.each(rowProperties, function (i, prop) {
      generatedColumn.rows.push(item[prop.name].content);

      generatedColumn[prop.name] = [];
      $.each(item[prop.name].content, function (i, x) {
        generatedColumn[prop.name].push(x);
      });
    });

    lookup[item.id][columnName] = generatedColumn;

    lookup[item.id].generatedColumns.push(columnName);
  });

  var items = [];
  for (var prop in lookup) {
    var item = lookup[prop];
    items.push(item);
  }

  var columns = [];
  $.each(tableData.columns, function (i1, column) {
    if (column.type === "title") {
      columns.push(column);

      $.each(allGeneratedColumns, function (i2, generatedColumn) {
        columns.push({
          name: generatedColumn,
          data: generatedColumn + ".rows",
          type: "generated",
          title: generatedColumn,
        });
      });
    }
  });

  var table = createTable(columns, items);

  $("#datatable").addClass("master-detail");

  createMasterDetailFilters(table, tableData.columns, items);

  setTimeout(resizeRows, 500);

  table.on("draw", resizeRows);
  table.on("column-visibility", resizeRows);

  function resizeRows() {
    $("#datatable>tbody>tr").each(function () {
      $(this)
        .find(".inner-table")
        .each(function () {
          $(this)
            .find("tr")
            .each(function (i) {
              this.style.height = "";
            });
        });

      var maxHeights = [];
      $(this)
        .find(".inner-table")
        .each(function () {
          $(this)
            .find("tr")
            .each(function (i) {
              if (!maxHeights[i] || maxHeights[1] < this.clientHeight) {
                maxHeights[i] = this.clientHeight;
              }
            });
        });

      $(this)
        .find(".inner-table")
        .each(function () {
          $(this)
            .find("tr")
            .each(function (i) {
              this.style.height = "" + maxHeights[i] + "px";
            });
        });
    });
  }
}

function createStandardTable() {
  var columnProperties = tableData.columns.filter(function (x) {
    return x.type === "column";
  });

  var allGeneratedColumns = {};
  var lexiconLinks = {};
  $.each(tableData.items, function (i1, item) {
    $.each(columnProperties, function (i2, columnProperty) {
      allGeneratedColumns[columnProperty.name] =
        allGeneratedColumns[columnProperty.name] || [];
      $.each(item[columnProperty.name].content, function (i, columnName) {
        if (
          allGeneratedColumns[columnProperty.name].indexOf(columnName) === -1
        ) {
          allGeneratedColumns[columnProperty.name].push(columnName);
        }

        if (!lexiconLinks[columnName]) {
          lexiconLinks[columnName] = (
            item[columnProperty.name].lexiconLinks || []
          ).find(function (x) {
            return x.linkText === columnName;
          });
        }

        item[columnName] = columnName;
      });
    });
  });

  var columns = [];
  $.each(tableData.columns, function (i1, column) {
    columns.push(column);
    if (column.type === "column") {
      column.visible = false;

      $.each(allGeneratedColumns[column.name], function (i2, generatedColumn) {
        columns.push({
          name: generatedColumn,
          data: generatedColumn,
          defaultContent: "",
          type: "generated",
          title: generatedColumn,
          lexiconLink: lexiconLinks[generatedColumn],
        });
      });
    }
  });

  var table = createTable(columns, tableData.items);

  createStandardFilters(table, tableData.type, tableData.columns, tableData.items);
}

function createTable(columns, items) {
  var run = true;
  var table = $("#datatable").DataTable({
    autoWidth: false,
    paging: false,
    order: [],
    data: items,
    columns: columns.map(function (c) {
      if (c.name === "title") {
        c.fnCreatedCell = function (nTd, sData, oData, iRow, iCol) {
          $(nTd).html('<a href="' + oData.id + '.html">' + sData + "</a>");
          $(nTd).addClass("title-column");
        };
      } else if (c.type === "generated") {
        c.fnCreatedCell = function (nTd, sData, oData, iRow, iCol) {
          if (oData[c.name] && oData[c.name].rows) {
            $(nTd).html(
              "<table class='inner-table'>" +
                oData[c.name].rows.map(createRow).join("") +
                "</table>"
            );
            $(nTd).addClass("generated-cell");
          } else if (oData[c.name]) {
            $(nTd).html(
              '<i class="fas fa-check" style="padding-left: 0.5rem"></i>'
            );
          }
        };
      }

      return c;
    }),
  });

  $.each(columns, function (index, column) {
    var columnHeader = table.column(column.name + ":name").header();
    var lexiconLink = column.lexiconLink;
    if (lexiconLink) {
      var popoverOptions = {
        container: "body",
        placement: "top",
        trigger: "focus",
        content:
          "<div>" +
          lexiconLink.content +
          "</div>" +
          ' <a href="' +
          lexiconLink.href +
          '">' +
          "<div>" +
          lexiconLink.lexiconTitle +
          "</div>" +
          "</a>",
        title: lexiconLink.title,
        html: true,
      };
      $(columnHeader).html(
        '<a class="lexiconlink" tabindex="0">' + columns[index].title + "</a>"
      );
      $(columnHeader).find(".lexiconlink").popover(popoverOptions);
      $(columnHeader)
        .find(".lexiconlink")
        .click(function (e) {
          e.stopPropagation();
        });
    }
  });

  
  table.on("draw", function () {
    var body = $(table.table().body());

    body.unhighlight();

    if (table.rows({ filter: "applied" }).data().length) {
      body.highlight(table.search());

      for (var key in filterTerms) {
        var nodes = table.column(key + ":name").nodes();
        if (nodes) {
          nodes.to$().highlight(filterTerms[key]);
        } else {
          body.highlight(filterTerms[key]);
        }
      }
    }
  });

  return table;

  function createRow(r) {
    return "<tr><td>" + r.join(", ") + "</td></tr>";
  }
}
