$(function () {
    if (tableData.type === 'master-detail') {
        createMasterDetailTable()
    }
    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.columns, tableData.items)
}

function createTable(columns, items) {
    var run = true
    var table = $('#datatable').DataTable({
        autoWidth: false,
        paging: false,
        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>"
    }
}
