<h3 style="display: flex; align-items: baseline; justify-content: space-between;">
    <div>
        {{ header }}
        <el-switch v-model="this.logEnabled" @change="changeLogEnabled" style="margin-left: 5px"></el-switch>
    </div>
    <div style="display: flex; gap: 10px; margin-right: 30px;">
        <el-button :disabled="!this.logEnabled" type="primary" plain style="padding: 6px" icon="el-icon-refresh" @click="onRefresh"> {{ labels.Refresh }}
        </el-button>
        <el-checkbox :disabled="!this.logEnabled" border v-model="autoRefresh" @change="onAutoRefresh" :label="labels.AutoRefresh"
                     style="padding: 4px 10px; border-radius: 6px; height: 30.4px;"></el-checkbox>

        <el-input-number v-if="autoRefresh"
                         v-model="speedOfRefresh"
                         :precision="1" :step="0.1" controls-position="right" size="small"
                         :min="0.3" :max="10" style="width: 95px; height: 30.4px;">
        </el-input-number>
    </div>
</h3>

<el-table
        :data="tableData"
        class="infinite-loading__table"
        row-key="id"
        style="height: 100%; width: 100%"
        :row-style="tableRowStyle"
        @cell-mouse-enter="onHoveringRow"
        :cell-style="tableCellStyle"
        fit
        height="calc(100% - 75px)">
    <el-table-column
            :label="labels.Timestamp"
            prop="Timestamp"
            :formatter="getFormatDate"
            :width="(260 + 20*maxLevel)+'px'">
    </el-table-column>
    <el-table-column
            :label="labels.Message"
            prop="Message">
        <template slot-scope="scope">
            <div style="white-space:nowrap">
                <el-popover
                        placement="bottom"
                        trigger="hover">
                    <el-row
                            style="width: 560px"
                            v-for="(key) in Object.keys(scope.row.Properties).filter(function(x) {if (scope.row.Properties[x]) return x;})">
                        <el-col :span="12">{{ key }}</el-col>
                        <el-col :span="12">{{ scope.row.Properties[key] || labels.Empty }}</el-col>
                    </el-row>

                    <span slot="reference">
                        <i class="el-icon-info"></i>
                    </span>
                </el-popover>
                {{ scope.row.Message}}
            </div>
        </template>
    </el-table-column>
    <el-table-column
            :label="labels.Exception"
            width="90">
        <template slot-scope="scope">
            <el-button v-if="scope.row.Exception != null" size="mini" type="danger"
                       @click="handleDialogOpen(scope.row.Exception)">{{labels.Show}}
            </el-button>
        </template>
    </el-table-column>
    <infinite-loading
            slot="append"
            @infinite="infiniteHandler"
            force-use-infinite-wrapper=".el-table__body-wrapper">
        <div slot="no-results"></div>
    </infinite-loading>
</el-table>
<el-dialog
        :title="labels.ExceptionInfo"
        :visible.sync="dialog.visible"
        :modal=false
        top="40vh"
        width="500px">
    <p>{{ dialog.data.ClassName }}</p>
    <p v-if="dialog.data.Message">{{ dialog.data.Message }}</p>
    <el-button type="text" @click="dialog.showDetails = !dialog.showDetails">
        {{ dialog.showDetails ? labels.HideDetails : labels.ShowDetails }}
    </el-button>
    <pre class="CodeBlock" v-if="dialog.showDetails"><code>{{ dialog.data }}</code></pre>
    <el-button slot="footer" type="primary" @click="dialog.visible = false">{{ButtonTextOk}}</el-button>
</el-dialog>

<script type="application/javascript">

    function logs_Init(me) {
        this.designer = me.graph.designer;
        me.VueConfig.data = Object.assign(me.VueConfig.data, {
            labels: WorkflowDesignerConstants.Logs,
            ButtonTextOk :WorkflowDesignerConstants.ButtonTextOk,
            header: WorkflowDesignerConstants.Logs.Label,
            designer: me.graph.designer,
            count: 20,
            items: [],
            tableDataSource:[],
            tableData: [],
            loading: true,
            autoRefresh: false,
            speedOfRefresh: 1,
            logEnabled: false,
            maxLevel: 0,
            dialog: {
                visible: false,
                data: {},
                showDetails: false
            },
            folder: me.graph.Settings.templatefolder
        });
        me.VueConfig.methods = {
            onAutoRefresh: function () {
                if (this.autoRefresh) {
                    this.onRefresh();
                    setTimeout(this.onAutoRefresh, this.speedOfRefresh * 1000);
                }
            },
            changeLogEnabled: function () {
                this.logEnabled = Boolean(this.designer.changelogenabled());
                if (!this.logEnabled) {
                    this.autoRefresh = false;
                }
            },
            handleDialogOpen: function (data) {
                this.dialog.data = data;
                this.dialog.visible = true;
            },

            tableCellStyle: function (data) {
                let row = data.row;
                let cellStyle = {};
                if (row["Properties"] && row["Properties"]["EventType"] != "EndExecution" && data.columnIndex == 0 && row.level ==0 ) {
                    cellStyle.paddingLeft = "22px"
                }
                else {
                    if(row["Properties"] && row["Properties"]["EventType"] == "EndExecution" && row.level !=0){
                        cellStyle.paddingLeft = ((row.level)*22)+"px"
                    }
                    else if(row["Properties"] && row["Properties"]["EventType"] != "EndExecution" && row.level !=0){
                        cellStyle.paddingLeft = ((row.level)*24)+"px"
                    }
                }

                return cellStyle;
            },

            tableRowStyle: function (data) {
                let row = data.row;
                let rowStyle = {};

                if (row["isNew"]) {
                    rowStyle.background = 'rgba(64,158,255,0.1)';
                } else if (row["Exception"] != null) {
                    rowStyle.background = 'rgba(245,108,108,0.1)';
                }

                if (row["Properties"] && ["StartExecution", "EndExecution"].includes(row["Properties"]["EventType"])) {
                    rowStyle.fontWeight = 'bold';
                    rowStyle.fontSize = '15px';
                }

                return rowStyle;
            },
            onHoveringRow: function (row) {
                if (row.isNew) {
                    row.isNew = false;
                }
            },
            onRefresh: function () {
                var additionalLogs = this.designer.getprocesslogs({suboperation: "Last", count: this.count});
                if (additionalLogs.length) {
                    this.tableDataSource = additionalLogs;
                    this.tableData = this.sortTableData(JSON.parse(JSON.stringify(this.tableDataSource)));
                }
            },
            infiniteHandler: function ($state) {
                if (this.tableData.length === 0) {
                    $state.loaded();
                    $state.complete();
                    return;
                }
                var dateTime = this.findMinDateTime(this.tableDataSource);
                var additionalLogs = this.designer.getprocesslogs({
                    suboperation: "Early",
                    dateTime: dateTime,
                    count: this.count
                });

                var lastSourceItem = JSON.stringify(this.tableDataSource[this.tableDataSource.length - 1]);
                var lastNewItem = JSON.stringify(additionalLogs[additionalLogs.length - 1]);
                var isEqualLastItems = lastSourceItem === lastNewItem;

                if (additionalLogs.length && !isEqualLastItems) {
                    this.tableDataSource = this.tableDataSource.concat(additionalLogs)
                    this.tableData = this.sortTableData(JSON.parse(JSON.stringify(this.tableDataSource)));
                    if (additionalLogs.length < this.count)
                        $state.complete();
                    else
                        $state.loaded();
                } else {
                    $state.complete();
                }
            },
            findMinDateTime: function (arr) {
                var len = arr.length, min = arr[0]["CreatedOn"];
                while (len--) {
                    if (arr[len]["CreatedOn"] < min) {
                        min = arr[len]["CreatedOn"];
                    }
                }
                return min;
            },
            findMaxDateTime: function (arr) {
                var len = arr.length, max = arr[0]["CreatedOn"];
                while (len--) {
                    if (arr[len]["CreatedOn"] > max) {
                        max = arr[len]["CreatedOn"];
                    }
                }
                return max;
            },
            getFormatDate: function (a, b, stringDate, d) {
                let date = new Date(stringDate);
                return date.toLocaleString() + ". " + date.getMilliseconds()
            },
            sortTableData: function (data) {
                return data.sort(function (a, b) {
                    return me.VueConfig.methods.compareDatesWithMicroseconds(a.Timestamp, b.Timestamp)
                })
            },
            compareDatesWithMicroseconds: function (a, b) {
                var dateA = new Date(a).getTime();
                var dateB = new Date(b).getTime();
                if (dateA < dateB) return 1;
                else if (dateA > dateB) return -1;
                else {
                    var microSecondsA = me.VueConfig.methods.getMicroseconds(a);
                    var microSecondsB = me.VueConfig.methods.getMicroseconds(b);

                    if (microSecondsA < microSecondsB) return 1;
                    else if (microSecondsA > microSecondsB) return -1;
                    return 0;
                };
            },
            getMicroseconds (timeString)
            {
                if (timeString.lastIndexOf("+") > -1)
                {
                    return parseFloat(timeString.substring(timeString.lastIndexOf("."), timeString.lastIndexOf("+")));
                }

                return parseFloat(timeString.substring(timeString.lastIndexOf(".")));
            }
        }

        me.VueConfig.created = function () {
            var dataSource = this.designer.getprocesslogs({suboperation: "Last", count: this.count});
            this.tableDataSource = dataSource;
            this.tableData = this.sortTableData(JSON.parse(JSON.stringify(dataSource)));
            this.logEnabled = Boolean(this.designer.getlogenabledstate());
        }
    }

</script>