Ext.define('PBS.node.Tasks', {
    extend: 'Ext.grid.GridPanel',

    alias: 'widget.pbsNodeTasks',

    stateful: true,
    stateId: 'pbs-grid-node-tasks',

    loadMask: true,
    sortableColumns: false,

    controller: {
	xclass: 'Ext.app.ViewController',

	showTaskLog: function() {
	    let me = this;
	    let selection = me.getView().getSelection();
	    if (selection.length < 1) {
		return;
	    }

	    let rec = selection[0];

	    Ext.create('Proxmox.window.TaskViewer', {
		upid: rec.data.upid,
		endtime: rec.data.endtime,
	    }).show();
	},

	updateLayout: function() {
	    let me = this;
	    // we want to update the scrollbar on every store load
	    // since the total count might be different
	    // the buffered grid plugin does this only on scrolling itself
	    // and even reduces the scrollheight again when scrolling up
	    me.getView().updateLayout();
	},

	sinceChange: function(field, newval) {
	    let me = this;
	    let vm = me.getViewModel();

	    vm.set('since', newval);
	},

	untilChange: function(field, newval, oldval) {
	    let me = this;
	    let vm = me.getViewModel();

	    vm.set('until', newval);
	},

	reload: function() {
	    let me = this;
	    let view = me.getView();
	    view.getStore().load();
	},

	showFilter: function(btn, pressed) {
	    let me = this;
	    let vm = me.getViewModel();
	    vm.set('showFilter', pressed);
	},

	init: function(view) {
	    let me = this;
	    Proxmox.Utils.monStoreErrors(view, view.getStore(), true);
	},
    },


    listeners: {
	itemdblclick: 'showTaskLog',
    },

    viewModel: {
	data: {
	    typefilter: '',
	    statusfilter: '',
	    datastore: '',
	    showFilter: false,
	    since: null,
	    until: null,
	},

	formulas: {
	    filterIcon: (get) => 'fa fa-filter' + (get('showFilter') ? ' info-blue' : ''),
	    extraParams: function(get) {
		let me = this;
		let params = {};
		if (get('typefilter')) {
		    params.typefilter = get('typefilter');
		}
		if (get('statusfilter')) {
		    params.statusfilter = get('statusfilter');
		}
		if (get('datastore')) {
		    params.store = get('datastore');
		}

		if (get('since')) {
		    params.since = get('since').valueOf()/1000;
		}

		if (get('until')) {
		    let until = new Date(get('until').getTime()); // copy object
		    until.setDate(until.getDate() + 1); // end of the day
		    params.until = until.valueOf()/1000;
		}

		me.getView().getStore().load();

		return params;
	    },
	},

	stores: {
	    bufferedstore: {
		type: 'buffered',
		pageSize: 500,
		autoLoad: true,
		remoteFilter: true,
		model: 'proxmox-tasks',
		proxy: {
		    type: 'proxmox',
		    startParam: 'start',
		    limitParam: 'limit',
		    extraParams: '{extraParams}',
		    url: "/api2/json/nodes/localhost/tasks",
		},
		listeners: {
		    prefetch: 'updateLayout',
		},
	    },
	},
    },

    bind: {
	store: '{bufferedstore}',
    },

    dockedItems: [
	{
	    xtype: 'toolbar',
	    items: [
		{
		    xtype: 'proxmoxButton',
		    text: gettext('View'),
		    iconCls: 'fa fa-window-restore',
		    disabled: true,
		    handler: 'showTaskLog',
		},
		{
		    xtype: 'button',
		    text: gettext('Reload'),
		    iconCls: 'fa fa-refresh',
		    handler: 'reload',
		},
		'->',
		{
		    xtype: 'button',
		    enableToggle: true,
		    bind: {
			iconCls: '{filterIcon}',
		    },
		    text: gettext('Filter'),
		    stateful: true,
		    stateId: 'task-showfilter',
		    stateEvents: ['toggle'],
		    applyState: function(state) {
			if (state.pressed !== undefined) {
			    this.setPressed(state.pressed);
			}
		    },
		    getState: function() {
			return {
			    pressed: this.pressed,
			};
		    },
		    listeners: {
			toggle: 'showFilter',
		    },
		},
	    ],
	},
	{
	    xtype: 'toolbar',
	    dock: 'top',
	    layout: {
		type: 'hbox',
		align: 'top',
	    },
	    bind: {
		hidden: '{!showFilter}',
	    },
	    items: [
		{
		    xtype: 'container',
		    padding: 10,
		    layout: {
			type: 'vbox',
			align: 'stretch',
		    },
		    defaults: {
			labelWidth: 80,
		    },
		    // cannot bind the values directly, as it then changes also
		    // on blur, causing wrong reloads of the store
		    items: [
			{
			    xtype: 'datefield',
			    fieldLabel: gettext('Since'),
			    format: 'Y-m-d',
			    bind: {
				maxValue: '{until}',
			    },
			    listeners: {
				change: 'sinceChange',
			    },
			},
			{
			    xtype: 'datefield',
			    fieldLabel: gettext('Until'),
			    format: 'Y-m-d',
			    bind: {
				minValue: '{since}',
			    },
			    listeners: {
				change: 'untilChange',
			    },
			},
		    ],
		},
		{
		    xtype: 'container',
		    padding: 10,
		    layout: {
			type: 'vbox',
			align: 'stretch',
		    },
		    defaults: {
			labelWidth: 80,
		    },
		    items: [
			{
			    xtype: 'pmxTaskTypeSelector',
			    fieldLabel: gettext('Task Type'),
			    emptyText: gettext('All'),
			    bind: {
				value: '{typefilter}',
			    },
			},
			{
			    xtype: 'combobox',
			    fieldLabel: gettext('Task Result'),
			    emptyText: gettext('All'),
			    multiSelect: true,
			    store: [
				['ok', gettext('OK')],
				['unknown', Proxmox.Utils.unknownText],
				['warning', gettext('Warnings')],
				['error', gettext('Errors')],
			    ],
			    bind: {
				value: '{statusfilter}',
			    },
			},
		    ],
		},
		{
		    xtype: 'container',
		    padding: 10,
		    layout: {
			type: 'vbox',
			align: 'stretch',
		    },
		    defaults: {
			labelWidth: 80,
		    },
		    items: [
			{
			    xtype: 'pbsDataStoreSelector',
			    fieldLabel: gettext('Datastore'),
			    emptyText: gettext('All'),
			    bind: {
				value: '{datastore}',
			    },
			    allowBlank: true,
			},
		    ],
		},
	    ],
	},
    ],

    viewConfig: {
	trackOver: false,
	stripeRows: false, // does not work with getRowClass()
	emptyText: gettext('No Tasks found'),

	getRowClass: function(record, index) {
	    let status = record.get('status');

	    if (status) {
		let parsed = Proxmox.Utils.parse_task_status(status);
		if (parsed === 'error') {
		    return "proxmox-invalid-row";
		} else if (parsed === 'warning') {
		    return "proxmox-warning-row";
		}
	    }
	    return '';
	},
    },

    columns: [
	{
	    header: gettext("Start Time"),
	    dataIndex: 'starttime',
	    width: 130,
	    renderer: function(value) {
		return Ext.Date.format(value, "M d H:i:s");
	    },
	},
	{
	    header: gettext("End Time"),
	    dataIndex: 'endtime',
	    width: 130,
	    renderer: function(value, metaData, record) {
		if (!value) {
		    metaData.tdCls = "x-grid-row-loading";
		    return '';
		}
		return Ext.Date.format(value, "M d H:i:s");
	    },
	},
	{
	    header: gettext("Duration"),
	    hidden: true,
	    width: 80,
	    renderer: function(value, metaData, record) {
		let start = record.data.starttime;
		if (start) {
		    let end = record.data.endtime || Date.now();
		    let duration = end - start;
		    if (duration > 0) {
			duration /= 1000;
		    }
		    return Proxmox.Utils.format_duration_human(duration);
		}
		return Proxmox.Utils.unknownText;
	    },
	},
	{
	    header: gettext("User name"),
	    dataIndex: 'user',
	    width: 150,
	},
	{
	    header: gettext("Description"),
	    dataIndex: 'upid',
	    flex: 1,
	    renderer: Proxmox.Utils.render_upid,
	},
	{
	    header: gettext("Status"),
	    dataIndex: 'status',
	    width: 200,
	    renderer: function(value, metaData, record) {
		if (value === undefined && !record.data.endtime) {
		    metaData.tdCls = "x-grid-row-loading";
		    return '';
		}

		let parsed = Proxmox.Utils.parse_task_status(value);
		switch (parsed) {
		    case 'unknown': return Proxmox.Utils.unknownText;
		    case 'error': return Proxmox.Utils.errorText + ': ' + value;
		    case 'ok': // fall-through
		    case 'warning': // fall-through
		    default: return value;
		}
	    },
	},
    ],
});
