import request from 'superagent'

export default class JiraService {

    constructor( config ) {
        this.request = request;
        this.config = config;
    }

    getDate() {
        const date = new Date();

        let dateStr = (date.getDate());
        dateStr += '/';
        dateStr += date.getMonth()+1;
        dateStr += '/';
        dateStr += date.getFullYear().toString().substring(2, 4);

        return dateStr;
    };

    async getProjectId() {
        try {
            let response = await this.request
            .get( this.config.baseUrl + '/rest/api/latest/project/' + this.config.projectKey )
            .auth(this.config.username, this.config.password);
            if (response.body.id) {
                return response.body.id;
            } else {
                console.error('Project ID not found.');
                return null;
            }
        } catch (error) {
            console.error('Unable to get jira project id, error: ' + error);
            return null;
        }
    };

    async getActiveSprintId() {
        try {
            let response = await this.request
            .get( this.config.baseUrl + '/rest/agile/latest/board/' + this.config.boardId + '/sprint?state=active')
            .auth(this.config.username, this.config.password);
            if (response.body.values[0]) {
                return response.body.values[0].id;
            } else {
                console.error('Active sprint ID not found.');
                return null;
            }
        } catch (error) {
            console.error('Unable to get jira Active sprint id, error: ' + error);
            return null;
        }
    };

    async getVersions() {
        try {
            let versions = new Array()
            let isLast = false;
            let startAt = 0;
            while (!isLast){
                let response = await this.request
                .get( this.config.baseUrl + '/rest/agile/latest/board/' + this.config.boardId + '/version?startAt=' + startAt)
                .auth(this.config.username, this.config.password);
                isLast = response.body.isLast;
                startAt = startAt + 50;
                if (response.body.values) {
                    response.body.values.forEach(version => {
                        versions.push(version);
                    });
                }
            }
            return versions;
        } catch (error) {
            console.error('Unable to get jira versions , error: ' + error);
            return null;
        }
    };

    async getVersionId(version, createIfNotExist=true) {
        try {
            let response;
            let isLast = false;
            let startAt = 0;
            while (!isLast){
                response = await this.request
                .get( this.config.baseUrl + '/rest/agile/latest/board/' + this.config.boardId + '/version?startAt=' + startAt)
                .auth(this.config.username, this.config.password);
                isLast = response.body.isLast;
                startAt = startAt + 50;
                if (response.body.values) {
                    let index = response.body.values.findIndex((ver) => ver.name.toLowerCase() === version.toLowerCase());
                    if (index !== -1) {
                        return response.body.values[index].id;
                    }
                }
            }
            if (createIfNotExist) {
                let body = {
                    "description": '',
                    "name": version,
                    "userStartDate": this.getDate(),
                    "archived": false,
                    "released": false,
                    "project": this.config.projectKey
                };

                response = await this.request
                .post(this.config.baseUrl + '/rest/api/latest/version')
                .auth(this.config.username, this.config.password)
                .type('json')
                .send(body);
                if (response.body.id){
                    return Number(response.body.id);
                } else {
                    console.error('Version ID not found for version ' + version + ' and creation failed');
                    return null;
                }
            } else {
                return null;
            }
        } catch (error) {
            console.error('Unable to get jira Version id for version ' + version + ', error: ' + error);
            return null;
        }
    };

    async deleteVersion(versionId) {
        let body = {};
        try {
            let response = await this.request
            .post(this.config.baseUrl + '/rest/api/latest/version/' + versionId + '/removeAndSwap')
            .auth(this.config.username, this.config.password)
            .type('json')
            .send(body);
            return response.body;
        } catch (error) {
            console.error('Unable to delete version: ' + versionId + ', ERROR: ' + error);
            return null;
        }
    };

    async getIssueId(issueKey) {
        try {
            let response = await this.request
            .get( this.config.baseUrl + '/rest/api/latest/issue/' + issueKey)
            .auth(this.config.username, this.config.password);
            if (response.body.id) {
                return response.body.id;
            } else {
                console.error('Issue ID not found.');
                return null;
            }
        } catch (error) {
            console.error('Unable to get jira issue id for ' + issueKey + ', error: ' + error);
            return null;
        }
    };

    async postComment(issueKey, comment) {
        try {
            let response = await this.request
            .post(this.config.baseUrl + '/rest/api/latest/issue/' + issueKey + '/comment')
            .auth(this.config.username, this.config.password)
            .type('json')
            .send({
                "body": comment
            });
            // return execution id
            return response.body;
        } catch (error) {
            console.error('Unable to post comment on jira issue, error: ' + error);
            return null;
        }
    };

}
