(function (paw) {
    function TimeRecordsTableNormalization($root) {
        this.$root = $root;

        this.$ntable;
        this.$tableHeader;
        this.headerValues = [];
        this.$tableBody;
        this.columnConfig = {};
    }

    TimeRecordsTableNormalization.prototype.normalizeTable = function () {
        this.createNormalizedTable();
        this.populateNormalizedTable();
        return this.$ntable;
    };

    TimeRecordsTableNormalization.prototype.createNormalizedTable = function () {
        this.$ntable = $('<table style="width: 100%;"></table>');
        this.createHeader();
        this.$tableBody = $('<tbody></tbody>');
        this.$ntable.append(this.$tableBody);
    };

    TimeRecordsTableNormalization.prototype.createHeader = function () {
        var self = this;
        this.$tableHeader = $('<thead></thead>');
        var $headerRow = $('<tr></tr>');
        this.headerValues = ['']; // add first empty value
        var $firstRow = $($(this.$root.find('table.time-record-table').get(0)).find('tbody tr.time-record-row').get(0));
        $headerRow.append('<th></th>');

        var cols = $firstRow.find('td').length;

        this.columnConfig = {};
        $('.checkbox-menu-timerecords.show-hide-column input[type=checkbox]').each(function () {
            var $checkbox = $(this);
            var idParse = $checkbox.attr('id').split('-');
            var selector = idParse[0];
            self.columnConfig[selector] = {
                isVisible: $checkbox.is(':checked')
            };
        });

        $firstRow.find('td').each(function (celli) {
            // skip the last column (actions column)
            if (celli >= cols - 1) {
                return;
            }
            var $cell = $(this);

            if (!self.calcColumnVisibility($cell) || $cell.css('display') === 'none' || $cell.css('visibility') === 'hidden') {
                return;
            }

            var $headerCell = $('<th></th>');
            var label = $cell.attr('label');
            if (celli > 0) {
                $headerCell.text(label);
                self.headerValues.push(label);
            }

            $headerRow.append($headerCell);
        });
        this.$tableHeader.append($headerRow);
        this.$ntable.append(this.$tableHeader);
    };

    TimeRecordsTableNormalization.prototype.populateNormalizedTable = function () {
        var self = this;
        this.$root.find('table.time-record-table').each(function (tablei) {
            var $table = $(this);
            $table.find('> tbody > tr').each(function (rowi) {
                var $row = $(this);
                var $nrow = $('<tr></tr>');

                if ($row.hasClass('hidden')) {
                    return;
                }

                if ($row.hasClass('time-record-row')) {
                    $row.find('td').each(function (celli) {
                        var $cell = $(this);
                        if (!self.calcColumnVisibility($cell)) {
                            return;
                        }
                        self.appendCell($cell, celli, $nrow)
                    });
                    self.$tableBody.append($nrow);
                }

                // append planned record
                $nrow = $('<tr></tr>');
                var isRowHidden = true;
                $row.find('table > tbody > tr.time-record-row.planned-record > td').each(function (celli) {
                    var $cell = $(this);
                    if (!self.calcColumnVisibility($cell)) {
                        return;
                    }
                    self.appendCell($cell, celli, $nrow)
                    isRowHidden = false;
                });
                if (!isRowHidden) {
                    self.$tableBody.append($nrow);
                }
            });
        });
    };

    TimeRecordsTableNormalization.prototype.appendCell = function ($cell, celli, $nrow) {
        if (celli === 0) {
            var $firstcell = $('<td></td>');
            $firstcell.append($cell.attr('label'));
            $nrow.append($firstcell);
        }

        if ($cell.css('display') === 'none' || $cell.css('visibility') === 'hidden') {
            return;
        }

        var $ncell = $('<td></td>');
        var value = paw.utils.value.trimString(this.parseColumnValue($cell, celli));
        if (value !== this.headerValues[celli]) {
            $ncell.text(value);
        }
        $nrow.append($ncell);
    };

    TimeRecordsTableNormalization.prototype.parseColumnValue = function ($cell, coli) {
        var self = this;
        switch (coli) {
            // first one
            case 0: {
                return self.parseValueFromSelect2($cell, function () {
                    return $cell.find('.time-record-selects > span').text();
                });
            }
            // Opomba
            case 1:
                return $cell.find('.AcNote .timerecord-note').text();
            // Oddelek
            // Str. nos
            case 2:
            case 3: {
                return self.parseValueFromSelect2($cell);
            }
            // some menu
            // Opozorilo
            case 4:
            case 5:
                return undefined;
            // Zacetek
            // Konec
            case 6:
            case 7: {
                return self.parseValueFromTimepicker($cell);
            }
            // Dejansko
            case 8:
            case 9: {
                var $a = $cell.find('div div');
                if ($a.length === 0) {
                    return $cell.find('div').text();
                }
                return $a.text();
            }
        }
    };

    TimeRecordsTableNormalization.prototype.parseValueFromSelect2 = function ($cell, fn) {
        var $holder = $cell.find('span.select2-selection__rendered');
        if ($holder.length > 0) {
            return $holder.contents().filter(function () {
                return this.nodeType === 3; // Filter out text nodes
            }).text().trim();
        }
        if (paw.utils.value.isFunction(fn)) {
            return fn($cell);
        }
        return $holder.text();
    };

    TimeRecordsTableNormalization.prototype.parseValueFromTimepicker = function ($cell) {
        var $input = $cell.find('input[type=time]');
        if ($input.length > 0) {
            return $input.val();
        }
        return $cell.find('span').text();
    };

    TimeRecordsTableNormalization.prototype.calcColumnVisibility = function ($cell) {
        var isVisible = true;
        paw.utils.iterable.get(this.columnConfig, function (item, key) {
            if ($cell.find('.' + key).length > 0) {
                isVisible = item.isVisible;
            }
        });
        return isVisible;
    };

    function TimeRecordsExporter($root, features) {
        this.$root = $root;
        this.features = features;
        this.ntable = new TimeRecordsTableNormalization(this.$root);
    }

    TimeRecordsExporter.create = function ($root, features) {
        var exporter = new TimeRecordsExporter($root, features);
        exporter.init();
    };

    TimeRecordsExporter.prototype.init = function (features) {
        var self = this;
        if (paw.utils.value.isSet(features)) {
            this.features = features;
        }
        if (paw.utils.value.notSet(this.features) || this.features.length === 0) {
            return;
        }

        var $exportFeatures = $('<div style="padding-left: 15px; padding-right: 15px;"></div>');
        this.$root.prepend($exportFeatures);

        if (this.features.indexOf('excel') > -1) {
            var $exportBtn = $('<button style="padding: .5em 1em; margin-right: .167em; margin-bottom: .333em; margin-top: .333em">Excel</button>');
            $exportFeatures.append($exportBtn);
            $exportBtn.on('click', function () {
                self.exportExcel();
            });
        }
    };

    TimeRecordsExporter.prototype.compileNormalizedTable = function () {
        return this.ntable.normalizeTable();
    };

    TimeRecordsExporter.prototype.exportExcel = function () {
        this.compileNormalizedTable();
        paw.mod.excel.Excel.exportFromHTMLTable(this.ntable.$ntable);
    };

    paw.view.workhours.TimeRecordsExporter = TimeRecordsExporter;
})(paw);