import axios, { AxiosRequestConfig } from 'axios';
import { CachingService } from ".";
import { EntityWorkflow, WorkflowVersion, StoredTypeDefinition, WorkflowEventHandler } from '../Models/WorkflowManager';

export class WorkflowService {
    private baseUrl: string = '';
    private _axiosRequestConfig: AxiosRequestConfig;
    private config: any = require('../config.json');
    constructor() {
        let cachingService: CachingService = new CachingService();
        this._axiosRequestConfig = {
            headers: {
                'Content-Type': 'application/json',
                'TenantId': cachingService.read('TenantId'),
                'Language': cachingService.readPersistant('Language'),
                'Authorization': 'Bearer ' + cachingService.read('Token'),
                'UserId': cachingService.read('UserId')
            }
        };
        this.baseUrl = this.config.baseUrl;
    }

    getAllWorkflows(): Promise<EntityWorkflow[]> {
        return new Promise((resolve, reject) => {
            axios.get(this.baseUrl + '/api/WorkflowManager/GetAllWorkflows', this._axiosRequestConfig).then((response) => {
                resolve(response.data as EntityWorkflow[]);
            }, (err) => {
                reject(err);
            });
        });
    }

    getWorkflowVesrions(workflowId: number): Promise<WorkflowVersion[]> {
        return new Promise((resolve, reject) => {
            axios.get(this.baseUrl + '/api/WorkflowManager/GetWorkflowVesrions?id=' + workflowId, this._axiosRequestConfig).then((response) => {
                resolve(response.data as WorkflowVersion[]);
            }, (err) => {
                reject(err);
            });
        });
    }
    getWorkflowVersion(workflowVersionId: number): Promise<WorkflowVersion> {
        return new Promise((resolve, reject) => {
            axios.get(this.baseUrl + '/api/WorkflowManager/GetWorkflowVersion?id=' + workflowVersionId, this._axiosRequestConfig).then((response) => {
                resolve(response.data as WorkflowVersion);
            }, (err) => {
                reject(err);
            });
        });
    }

    getWorkflowActions(entityId: string, entityType: number, recordId: string): Promise<any> {
        return new Promise((resolve, reject) => {
            axios.get(this.baseUrl + '/api/BusinessLogicClient/GetActions?entityId=' + entityId + '&entityType=' + entityType +
                '&recordId=' + recordId, this._axiosRequestConfig).then((response) => {
                    resolve(response.data as any);
                }, (err) => {
                    reject(err);
                });
        });
    }

    executeAction(executeActionInputDto:any): Promise<any> {
        return new Promise((resolve, reject) => {
            axios.post(this.baseUrl + '/api/BusinessLogicClient/ExecuteAction',executeActionInputDto, this._axiosRequestConfig).then((response) => {
                    resolve(response.data as any);
                }, (err) => {
                    reject(err);
                });
        });
    }

    getAllWorkflowEntities(): Promise<StoredTypeDefinition[]> {
        return new Promise((resolve, reject) => {
            axios.get(this.baseUrl + '/api/WorkflowManager/GetAllWorkflowEntities', this._axiosRequestConfig).then((response) => {
                resolve(response.data as StoredTypeDefinition[]);
            }, (err) => {
                reject(err);
            });
        });
    }
    createEntityWorkflow(entityWorkflow: EntityWorkflow): Promise<any> {
        return new Promise((resolve, reject) => {
            axios.post(this.baseUrl + '/api/WorkflowManager/CreateEntityWorkflow', entityWorkflow, this._axiosRequestConfig).then((response) => {
                resolve(response.data);
            }, (err) => {
                reject(err);
            });
        });
    }
    createEntityWorkflowVersion(workflowVersion: WorkflowVersion): Promise<any> {
        return new Promise((resolve, reject) => {
            axios.post(this.baseUrl + '/api/WorkflowManager/CreateEntityWorkflowVersion', workflowVersion, this._axiosRequestConfig).then((response) => {
                resolve(response.data);
            }, (err) => {
                reject(err);
            });
        });
    }
    setWorkflowVersionAsFinalVersion(workflowVersionId: number): Promise<any> {
        return new Promise((resolve, reject) => {
            axios.post(this.baseUrl + '/api/WorkflowManager/SetWorkflowVersionAsFinalVersion?id=' + workflowVersionId, this._axiosRequestConfig).then((response) => {
                resolve(response.data);
            }, (err) => {
                reject(err);
            });
        });
    }
    saveEntityWorkflowVersion(workflowVersion: WorkflowVersion): Promise<any> {
        return new Promise((resolve, reject) => {
            axios.post(this.baseUrl + '/api/WorkflowManager/SaveEntityWorkflowVersion', workflowVersion, this._axiosRequestConfig).then((response) => {
                resolve(response.data);
            }, (err) => {
                reject(err);
            });
        });
    }
    defineType(storedTypeDefinition: StoredTypeDefinition): Promise<StoredTypeDefinition> {
        return new Promise((resolve, reject) => {
            axios.post(this.baseUrl + '/api/WorkflowManager/DefineType', storedTypeDefinition, this._axiosRequestConfig).then((response) => {
                resolve(response.data);
            }, (err) => {
                reject(err);
            });
        });
    }
    getAllHandlers(): Promise<WorkflowEventHandler[]> {
        return new Promise((resolve, reject) => {
            axios.get(this.baseUrl + '/api/WorkflowManager/GetAllHandlers', this._axiosRequestConfig).then((response) => {
                resolve(response.data as WorkflowEventHandler[]);
            }, (err) => {
                reject(err);
            });
        });
    }
    getWorkflowByFQN(fqn: string): Promise<EntityWorkflow | null> {
        return new Promise((resolve, reject) => {
            axios.get(this.baseUrl + '/api/WorkflowManager/GetWorkflowByFQN?fqn=' + fqn, this._axiosRequestConfig).then((response) => {
                resolve(response.data as EntityWorkflow | null);
            }, (err) => {
                reject(err);
            });
        });
    }
}