var system = require("../../../system")
const http = require("http")
const querystring = require('querystring');
var settings = require("../../../../config/settings");

const CtlBase = require("../../ctl.base");
const axios = require("axios");
const jwt = require("jsonwebtoken");
const { appKey, appSecret } = settings.ydzKey();
const ydz_prefix = "ydz:";

class AuthCtl extends CtlBase {
    constructor() {
        super("auth", CtlBase.getServiceName(AuthCtl));
        this.redisClient = system.getObject("util.redisClient");
    }
    async saveAuths(pobj, query, req) {
        var auths = pobj.auths;
        var xrtn = await this.service.saveAuths(auths, pobj.app_id, pobj.company_id);
        return system.getResult(xrtn);
    }
    async findAuthsByRoles(pobj, query, req) {
        var roleids = pobj.roleids;
        var xrtn = await this.service.findAuthsByRole(roleids, pobj.app_id, pobj.company_id);
        return system.getResult(xrtn);
    }

    /**
     * 易代账获取应用凭证
     */
    async getAppCredentials() {
        const url = `${settings.ydzUrl()}/auth/appAuth/getAppAccessToken`;
        const { appTicket } = JSON.parse(await this.redisClient.get(`${ydz_prefix}APP_TICKET`)).bizContent;
        const headers = {
            "Content-Type": "application/json",
            appKey,
            appSecret
        };
        const creRes = await this.postRequest(url, { appTicket }, headers);
        const addRedisResult = await this.redisClient.setWithEx(`${ydz_prefix}appAccessToken`, JSON.stringify(creRes.result));
        return creRes.result;
    };

    /**
     * 易代账获取企业永久授权码
     */
    async getPermanentAuthCode() {
        const url = `${settings.ydzUrl()}/auth/orgAuth/getPermanentAuthCode`;
        const { appAccessToken } = JSON.parse(await this.redisClient.get(`${ydz_prefix}appAccessToken`)); //获取应用凭证
        const { tempAuthCode } = JSON.parse(await this.redisClient.get(`${ydz_prefix}TEMP_AUTH_CODE`)).bizContent; //获取企业临时授权码
        const params = {
            appAccessToken, //应用凭证
            tempAuthCode //企业临时授权码
        }
        const headers = {
            "Content-Type": "application/json",
            appKey,
            appSecret
        };
        const perResult = await this.postRequest(url, params, headers);
        if (perResult.code == 200) {
            return perResult.result;
        } else {
            console.log('--------------getPermanentAuthCode-----ERROR-----------------');
            console.log(perResult)
            return system.getResultFail(perResult);
        }
    }

    /**
     * 易代账获取企业凭证
     */
    async getOrgAccessToken() {
        const url = `${settings.ydzUrl()}/auth/orgAuth/getOrgAccessToken`;
        const { appAccessToken } = await this.getAppCredentials(); //获取应用凭证
        const permanentAuthCode = (await this.getPermanentAuthCode()).permanentAuthCode; //获取企业永久授权码
        const params = {
            appAccessToken, //应用凭证
            permanentAuthCode //企业永久授权码
        }
        const headers = {
            "Content-Type": "application/json",
            appKey,
            appSecret
        };
        const OrgResult = await this.postRequest(url, params, headers);
        const addRedisResult = await this.redisClient.setWithEx(`${ydz_prefix}orgAccessToken`, JSON.stringify(OrgResult.result), OrgResult.result.expireTime);
        return OrgResult.result;
    }

    /**
     * 易代账获取初始化token
     * @param {*} code 企业授权码
     */
    async getOpenToken(body) {
        if (body.code) { //临时授权码
            const url = `${settings.ydzUrl()}/auth/getToken`;
            return await this.publicTokenFun(url, "authorization_code", appKey, body.code, "code");
        } else { //用户永久授权码
            const url = `${settings.ydzUrl()}/auth/token/getTokenByPermanentCode`;
            const { user_auth_permanent_code } = JSON.parse(await this.redisClient.get(`${ydz_prefix}ydzToken`)); //用户永久授权码
            console.log(user_auth_permanent_code);
            const { orgAccessToken } = JSON.parse(await this.redisClient.get(`${ydz_prefix}orgAccessToken`));
            if (!orgAccessToken) {
                orgAccessToken = (await this.getOrgAccessToken()).orgAccessToken; //获取企业凭证
            }
            const params = {
                orgAccessToken, //企业凭证
                userAuthPermanentCode: user_auth_permanent_code //企业永久授权码
            }
            const headers = {
                "Content-Type": "application/json",
                appKey,
                appSecret
            };
            const perToTokenResult = await this.postRequest(url, params, headers);
            if (perToTokenResult.code == 200) {
                const addRedisResult = await this.setRedisValue(`${ydz_prefix}ydzToken`, perToTokenResult.result);
                return system.getResultSuccess(perToTokenResult)
            } else {
                return system.getResultFail(perToTokenResult);
            }

        }
    }

    /**
     * 刷新opentoken(access_token)
     */
    async refreshToken() {
        const url = `${settings.ydzUrl()}/auth/refreshToken`;
        const getRedisResult = JSON.parse(await this.redisClient.get(`${ydz_prefix}ydzToken`)).refresh_token;
        return await this.publicTokenFun(url, "refresh_token", appKey, getRedisResult, "refreshToken")
    };

    async publicTokenFun(url, grantType, appKey, data, specialKey) {
        let params = {
            grantType,
            appKey
        }
        params[specialKey] = data;
        const res = await this.getRequest(url, params);
        if (res.data.code == 200) {
            const addRedisResult = await this.setRedisValue(`${ydz_prefix}ydzToken`, res.data.result);
            return system.getResultSuccess(res.data);
        } else {
            return system.getResultFail(201, res.data.message);
        }
    };

    async setRedisValue(key, data) {
        const ydzToken = {
            access_token: data.access_token,
            refresh_token: data.refresh_token,
            user_auth_permanent_code: data.user_auth_permanent_code
        }
        const deTokenExp = Number((jwt.decode(data.access_token).exp));
        const timestamp = Math.round(new Date() / 1000);
        const addRedisResult = await this.redisClient.setWithEx(key, JSON.stringify(ydzToken), Number(deTokenExp - timestamp));
        // const getRedisResult = await this.redisClient.get('ydzToken');
        console.log('------------------------------addRedisResult-----------------------');
        console.log(`Request: ${JSON.stringify(data)}`);
        console.log(`addRedisResult: ${addRedisResult}`);
        return addRedisResult;
    }

    /**
     * 公用get请求
     * @param {*} url 
     * @param {*} data 
     */
    async getRequest(url, params = {}) {
        try {
            console.log(` ${url} : 请求信息 ------- `);
            console.log(JSON.stringify(params));
            const res = await axios.get(url, {
                params,
                headers: {
                    "Content-Type": "application/json",
                }
            });
            return res;
        } catch (err) {
            console.log(` ${url} : 返回错误信息 ------- `);
            console.log(err)
            throw (err)
        }
    };
    /**
     * 
     * @param {string} url 
     * @param {object} params 
     */
    async postRequest(url, params, headers) {
        try {
            console.log(` ${url} : 请求信息 ------- `);
            console.log(`headers: ${JSON.stringify(headers)}`)
            console.log(`params: ${JSON.stringify(params)}`);
            let result = await axios.post(`${url}`, params, {
                headers: {
                    ...headers
                }
            });
            result = result.data;
            console.log(` ${url} : 返回信息 ------- `);
            console.log(result);
            return result;
        } catch (err) {
            console.log(` ${url} : 返回错误信息 ------- `);
            console.log(err);
            throw (err)
        }
    }
}
module.exports = AuthCtl;