import axios from "axios";
import Config from "../config";
import {getItem, setItem} from "../ui/util/storageHelper";
import wfc from "../wfc/client/wfc";
import OrganizationServerError from "./organizationServerError";
import UserInfo from "../wfc/model/userInfo";

export class OrganizationServerApi {
    isServiceAvailable = true;
    serviceUnavailbelError = new OrganizationServerError(-1, '未登录或服务不可用');

    constructor() {
        // do nothing
    }

    login() {
        return new Promise((resolve, reject) => {
            //        int ApplicationType_Robot = 0;
//        int ApplicationType_Channel = 1;
//        int ApplicationType_Admin = 2;
            if (!Config.ORGANIZATION_SERVER) {
                reject(this.serviceUnavailbelError)
                return
            }
            wfc.getAuthCode('admin', 2, '', code => {
                let path = '/api/user_login';
                this._post(path, {
                    authCode: code
                }, true)
                    .then(response => {
                        if (response.data.code === 0) {
                            let appAuthToken = response.headers['authtoken'];
                            if (!appAuthToken) {
                                appAuthToken = response.headers['authToken'];
                            }

                            if (appAuthToken) {
                                setItem('authToken-' + new URL(response.config.url).host, appAuthToken);
                            }
                            this.isServiceAvailable = true;
                            resolve(response.data.result);
                        } else {
                            reject(new OrganizationServerError(response.data.code, response.data.message));
                        }
                    })

            }, error => {
                console.error('getAuthCode error', error);
                reject(this.serviceUnavailbelError)

            })
        })
    }

    getRootOrganization() {
        return this._post('/api/organization/root');
    }

    getRelationShip(employeeId) {
        return this._post('/api/relationship/employee', {employeeId});
    }

    getOrganizationEx(orgId) {
        return this._post('/api/organization/query_ex', {id: orgId});
    }

    getOrganizations(orgIds) {
        return this._post('/api/organization/query_list', {ids: orgIds});
    }

    async getOrganizationEmployees(orgIds) {
        let employeeIds = await this._post('/api/organization/batch_employees', {ids: orgIds});
        return this.getEmployeeList(employeeIds);
    }

    getOrgEmployees(orgId) {
        return this._post('/api/organization/employees', {ids: orgId});
    }

    getEmployee(employeeId) {
        return this._post('/api/employee/query', {employeeId});
    }

    getEmployeeEx(employeeId) {
        return this._post('/api/employee/query_ex', {employeeId});
    }

    getEmployeeList(employeeIds) {
        return this._post('/api/employee/query_list', {employeeIds: employeeIds})
    }

    searchEmployee(orgId, keyword) {
        return this._post('/api/employee/search', {organizationId: orgId, keyword: keyword});
    }

    async getOrganizationPath(organizationId) {
        let pathList = [];
        let org = await this._getOrganizationSync(organizationId);
        if (org) {
            pathList.push(org)
            if (org.parentId) {
                pathList.push(...await this.getOrganizationPath(org.parentId));
            }
        }
        return pathList;
    }

    employeeToUserInfo(employee) {
        let userInfo = new UserInfo();
        userInfo.uid = employee.employeeId;
        userInfo.name = employee.name;
        userInfo.displayName = employee.name;
        userInfo.portrait = employee.portrait ? employee.portrait : Config.DEFAULT_PORTRAIT_URL;
        userInfo.gender = employee.gender;
        userInfo.mobile = employee.mobile;
        userInfo.email = employee.email;
        userInfo.updateDt = employee.updateDt;
        //0 normal; 1 robot; 2 thing;
        userInfo.type = 1;
        userInfo.deleted = 0;
        return userInfo;
    }

    async _getOrganizationSync(orgId) {
        let orgs = await this.getOrganizations([orgId])
        return orgs && orgs.length > 0 ? orgs[0] : null;
    }

    /**
     *
     * @param path
     * @param data
     * @param rawResponse
     * @param rawResponseData
     * @return {Promise<string | AxiosResponse<any>|*|T>}
     * @private
     */
    async _post(path, data = {}, rawResponse = false, rawResponseData = false) {
        let response;
        path = Config.ORGANIZATION_SERVER + path;
        response = await axios.post(path, data, {
            transformResponse: rawResponseData ? [data => data] : axios.defaults.transformResponse, headers: {
                'authToken': getItem('authToken-' + new URL(path).host),
            }, withCredentials: true,
        })
        if (rawResponse) {
            return response;
        }
        if (response.data) {
            if (rawResponseData) {
                return response.data;
            }
            if (response.data.code === 0) {
                return response.data.result
            } else {
                throw new OrganizationServerError(response.data.code, response.data.message)
            }
        } else {
            throw new Error('request error, status code: ' + response.status)
        }
    }
}

const organizationServerApi = new OrganizationServerApi();
export default organizationServerApi;
