export default {
    data() {
        return {
            activeTasks: {},
            pollingTimeouts: {
                create: null,
                delete: {},
                restore: null,
                rollback: null
            },

            isCreating: false,
            isAnyDeleting: false,
            isAnyRestoring: false,
            isAnyRollingBack: false,

            taskProgress: {
                create: null,
                delete: {},
                restore: null,
                rollback: null
            }
        };
    },

    computed: {
        isAnyOperationRunning() {
            return this.activeTasks.hasAnyActiveTask || this.isCreating || this.isAnyDeleting || this.isAnyRestoring || this.isAnyRollingBack;
        }
    },

    methods: {
        isTaskActive(status) {
            return status === 'running' || status === 'pending' || status === 'queued';
        },

        async pollTaskStatus(taskId, operationType, resourceId = null) {
            if (!this.dCan || !this.dCan('tasks.show')) {
                return false;
            }

            try {
                const response = await axios.get(this.xhrUrl + 'getTask&taskId=' + taskId);
                const task = response.data;

                if (task && task.progress !== undefined && task.progress !== null) {
                    if (operationType === 'create') {
                        this.taskProgress.create = task.progress;
                    } else if (operationType === 'delete' && resourceId) {
                        this.$set(this.taskProgress.delete, resourceId, task.progress);
                    } else if (operationType === 'restore' && resourceId) {
                        this.taskProgress.restore = task.progress;
                    } else if (operationType === 'rollback' && resourceId) {
                        this.taskProgress.rollback = task.progress;
                    }
                }

                if (task && this.isTaskActive(task.status)) {
                    if (operationType === 'delete') {
                        this.pollingTimeouts.delete[taskId] = setTimeout(() => {
                            this.pollTaskStatus(taskId, operationType, resourceId);
                        }, 1000);
                    } else {
                        this.pollingTimeouts[operationType] = setTimeout(() => {
                            this.pollTaskStatus(taskId, operationType, resourceId);
                        }, 1000);
                    }
                } else {
                    try {
                        await this.refreshList();
                    } catch (refreshError) {
                        console.log('List refresh after task completion failed: ', refreshError);
                    }

                    this.cleanupTaskPolling(taskId, operationType);
                    this.resetTaskProgress(operationType, resourceId);
                }
            } catch (error) {
                this.cleanupTaskPolling(taskId, operationType);
                this.resetTaskProgress(operationType, resourceId);
            }
        },

        cleanupTaskPolling(taskId, operationType) {
            if (operationType === 'delete') {
                if (this.pollingTimeouts.delete[taskId]) {
                    clearTimeout(this.pollingTimeouts.delete[taskId]);
                    delete this.pollingTimeouts.delete[taskId];
                }
            } else {
                if (this.pollingTimeouts[operationType]) {
                    clearTimeout(this.pollingTimeouts[operationType]);
                    this.pollingTimeouts[operationType] = null;
                }
            }
        },

        resetTaskProgress(operationType, resourceId) {
            if (operationType === 'create') {
                this.taskProgress.create = null;
            } else if (operationType === 'delete' && resourceId) {
                this.$delete(this.taskProgress.delete, resourceId);
            } else if (operationType === 'restore') {
                this.taskProgress.restore = null;
            } else if (operationType === 'rollback') {
                this.taskProgress.rollback = null;
            }
        },

        getDeleteTaskProgress(resourceId) {
            return this.taskProgress.delete[resourceId] || 0;
        },

        getRestoreTaskProgress() {
            return this.taskProgress.restore || 0;
        },

        getRollbackTaskProgress() {
            return this.taskProgress.rollback || 0;
        },

        getCreateTaskProgress() {
            return this.taskProgress.create || 0;
        },

        refreshList(withoutLoadingState = false) {
            console.warn('refreshList() must be implemented in component');
        },
    },

    beforeDestroy() {
        if (this.pollingTimeouts.create) {
            clearTimeout(this.pollingTimeouts.create);
        }

        Object.keys(this.pollingTimeouts.delete).forEach(taskId => {
            clearTimeout(this.pollingTimeouts.delete[taskId]);
        });

        if (this.pollingTimeouts.restore) {
            clearTimeout(this.pollingTimeouts.restore);
        }

        if (this.pollingTimeouts.rollback) {
            clearTimeout(this.pollingTimeouts.rollback);
        }
    }
};