package rpc

import (
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/gtrace"
	"strings"

	. "bp.jydev.jianyu360.cn/BaseService/gateway/common/gatecode"
	"bp.jydev.jianyu360.cn/BaseService/resourceCenter/rpc/pb"
	"bp.jydev.jianyu360.cn/BaseService/resourceCenter/rpc/resource"
	"github.com/gogf/gf/v2/os/gcfg"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/zeromicro/go-zero/core/discov"
	"github.com/zeromicro/go-zero/zrpc"
)

var ResourceCenterRpc resource.Resource

func initResourceCenterRpc() {
	ResourceCenterRpc = resource.NewResource(zrpc.MustNewClient(zrpc.RpcClientConf{
		Etcd: discov.EtcdConf{
			Key:   gcfg.Instance().MustGet(gctx.New(), "etcd.baseserver.resourceCenter.key", nil).String(),
			Hosts: gcfg.Instance().MustGet(gctx.New(), "etcd.baseserver.resourceCenter.address", nil).Strings(),
		},
	}))
}

// CheckResourcePower 校验账户是否有对应权益
// accountId 账户id
// entAccountId 企业账户id
// entId 企业id
// entUserId 企业员工id
// funcCode 业务代码
// reqFuncCode 	 通用结构&&需要校验权限则先判断此接口是否有此functionCode的方法
// appid 平台标识
func CheckResourcePower(ctx gctx.Ctx, accountId, entAccountId, entId, entUserId int64, funcCodeRule, reqFuncCode, Appid string) (UseCount, SurplusCount int64, err error) {
	ctx, span := gtrace.NewSpan(ctx, "CheckResourcePower")
	defer span.End()

	funcCode := funcCodeRule
	funcCodeArr := strings.Split(funcCodeRule, ",")
	if reqFuncCode != "" || len(funcCodeArr) > 1 {
		var checkPass bool
		for _, tFunc := range funcCodeArr {
			if reqFuncCode == tFunc {
				checkPass = true
				break
			}
		}
		if !checkPass {
			err = NewErrorWithCode(GLOBAL_ERR_RESOURCE_POWERCODE_ERR, fmt.Sprintf("账户 accountId：%d entAccountId：%d entId：%d entUserId：%d 无效funccode:%s req：%s权限", accountId, entAccountId, entId, entUserId, funcCodeRule, reqFuncCode))
			return
		}
		funcCode = reqFuncCode
	}

	res, err := ResourceCenterRpc.CheckPower(ctx, &pb.CheckPowerReq{
		Appid:        Appid,
		FunctionCode: funcCode,
		AccountId:    accountId,
		EntAccountId: entAccountId,
		EntId:        entId,
		EntUserId:    entUserId,
	})

	if err != nil {
		err = NewErrorWithCode(GATEWAY_RPC_RESOURCECENTER_ERR, err.Error())
		return
	}
	//0：失败 1：成功 -1：不在有效期内 -2：数量不足 -3：没有授权
	switch res.Status {
	case 0:
		err = NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_FAIL, fmt.Sprintf("账户 accountId：%d entAccountId：%d entId：%d entUserId：%d 无业务%s权限", accountId, entAccountId, entId, entUserId, funcCode))
		return
	case -1:
		err = NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_EXPIRED, fmt.Sprintf("账户 accountId：%d entAccountId：%d entId：%d entUserId：%d 业务%s权限已过期", accountId, entAccountId, entId, entUserId, funcCode))
		return
	case -2:
		err = NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_NOTENOUGH, fmt.Sprintf("账户 accountId：%d entAccountId：%d entId：%d entUserId：%d 业务%s权限余额不足", accountId, entAccountId, entId, entUserId, funcCode))
		return
	case -3:
		err = NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_NOTHAS, fmt.Sprintf("账户 accountId：%d entAccountId：%d entId：%d entUserId：%d 业务%s权限无授权", accountId, entAccountId, entId, entUserId, funcCode))
		return
	}
	return res.UseCount, res.SurplusCount, nil
}

// ResourcePowerDeduct 资源中心消费
// accountId 账户id
// entAccountId 企业账户id
// funcCode 业务代码
// deductNum 扣除数量
// ids 扣除详情id;例如数据导出信息id等数据
func ResourcePowerDeduct(ctx g.Ctx, accountId, entAccountId int64, funcCode, appId string, deductNum int64, ids []string) error {
	ctx, span := gtrace.NewSpan(ctx, "ResourcePowerDeduct")
	defer span.End()
	res, err := ResourceCenterRpc.Deduction(ctx, &pb.DeductionReq{
		Appid:        appId,
		AccountId:    accountId,
		EntAccountId: entAccountId,
		FunctionCode: funcCode,
		Count:        deductNum,
		Ids:          ids,
	})
	if err != nil {
		return NewErrorWithCode(GATEWAY_RPC_RESOURCECENTER_ERR, err.Error())
	}
	//0：失败 1：成功 -1：不在有效期内 -2：数量不足 -3：没有授权
	switch res.Status {
	case 0:
		return NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_FAIL, fmt.Sprintf("账户 accountId：%d entAccountId：%d 扣除业务%s权限失败", accountId, entAccountId, funcCode))
	case -1:
		return NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_EXPIRED, fmt.Sprintf("账户 accountId：%d entAccountId：%d 扣除业务%s权限失败,权限已过期", accountId, entAccountId, funcCode))
	case -2:
		return NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_NOTENOUGH, fmt.Sprintf("账户 accountId：%d entAccountId：%d 扣除业务%s权限失败,余额不足", accountId, entAccountId, funcCode))
	case -3:
		return NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_NOTHAS, fmt.Sprintf("账户 accountId：%d entAccountId：%d 扣除业务%s权限失败", accountId, entAccountId, funcCode))
	}
	return nil
}

// ResourcePowerRecharge 资源中心充值
// accountId 账户id
// entAccountId 企业账户id
// funcCode 业务代码
// deductNum 扣除数量
// ids 扣除详情id;例如数据导出信息id等数据
func ResourcePowerRecharge(ctx g.Ctx, accountId, entAccountId int64, funcCode, appId string, deductNum int64, ids []string) error {
	ctx, span := gtrace.NewSpan(ctx, "ResourcePowerRecharge")
	defer span.End()

	res, err := ResourceCenterRpc.Recharge(ctx, &pb.RechargeReq{
		Appid:        appId,
		AccountId:    accountId,
		EntAccountId: entAccountId,
		FunctionCode: funcCode,
		Count:        deductNum,
		Ids:          ids,
	})
	if err != nil {
		return NewErrorWithCode(GATEWAY_RPC_RESOURCECENTER_ERR, err.Error())
	}
	switch res.Status {
	case 0:
		return NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_FAIL, fmt.Sprintf("账户 accountId：%d entAccountId：%d 充值业务%s权限失败", accountId, entAccountId, funcCode))
	case -1:
		return NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_EXPIRED, fmt.Sprintf("账户 accountId：%d entAccountId：%d 充值业务%s权限失败,权限已过期", accountId, entAccountId, funcCode))
	case -2:
		return NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_NOTENOUGH, fmt.Sprintf("账户 accountId：%d entAccountId：%d 充值业务%s权限失败,余额不足", accountId, entAccountId, funcCode))
	case -3:
		return NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_NOTHAS, fmt.Sprintf("账户 accountId：%d entAccountId：%d 充值业务%s权限失败", accountId, entAccountId, funcCode))
	case -4: //超出可拥有最大限额
		return NewErrorWithCode(GLOBAL_ERR_RESOURCE_PORWE_RECHARGE_FULL, fmt.Sprintf("账户 accountId：%d entAccountId：%d 充值业务%s权限失败", accountId, entAccountId, funcCode))
	}

	return nil
}
