/*
 * @description:计量支付接口相关操作
 * @Author: CP
 * @Date: 2020-09-03 16:57:56
 * @FilePath: \construction_management\lib\jlzf.go
 */
package lib

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"time"

	"github.com/dgrijalva/jwt-go"
	"go.mod/conf"
	"go.mod/web/utils"
	"go.mod/web/viewmodels"
)

type Jlzf struct {
	AuthUrl string
	App     string
	Token   string
}

// 计量接口返回
type jlResult struct {
	Code int        `json:"code" `
	Data dataResult `json:"data" `
	Msg  string     `json:"msg" `
}
type dataResult struct {
	Account map[string]interface{} `json:"account,optional" `
	Project map[string]interface{} `json:"project,optional" `
}

type jlAccountResult struct {
	Code int                      `json:"code" `
	Data []map[string]interface{} `json:"Data" `
	Msg  string                   `json:"msg" `
}

// 创建项目用户service
func NewJlzf() *Jlzf {
	// 自动识别开发环境和生产环境
	debug := utils.GetEnvInfo("DEBUG")
	AuthUrl := "https://jl.smartcost.com.cn"
	if debug == "qa" {
		AuthUrl = "http://192.168.1.76:7002"
	} else if debug == "uat" {
		AuthUrl = "http://jluat.smartcost.com.cn"
	}
	return &Jlzf{
		AuthUrl: AuthUrl,
	}
}

// 生成请求token
func makeTokenString(claimsData jwt.MapClaims) (string, error) {
	var (
		tokenString string
		err         error
	)
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claimsData)
	if tokenString, err = token.SignedString([]byte(conf.JLSecretKey)); err != nil {
		return "", err
	}
	return tokenString, nil
}

// 按项目编号获得计量账号
func (j *Jlzf) GetAccountList(code string) ([]map[string]interface{}, error) {
	var (
		tokenString     string
		err             error
		resultByte      []byte
		jlAccountResult jlAccountResult
	)
	// 1.生成请求数据
	expirationTime := time.Now().Add(3 * time.Second)
	claimsData := jwt.MapClaims{
		"data": map[string]string{"code": code},
		"exp":  expirationTime.Unix(),
		"iat":  time.Now().Unix(),
	}
	// 1-1.生成token
	if tokenString, err = makeTokenString(claimsData); err != nil {
		return nil, errors.New("生成请求token错误")
	}

	// 1-2.发送请求
	if resultByte, err = utils.PullData("GET", j.AuthUrl+"/management/account/sync?auth="+tokenString, ""); err != nil {
		return nil, errors.New(fmt.Sprintf("计量错误，err= %s", err))
	}

	err = json.Unmarshal(resultByte, &jlAccountResult)
	if err != nil {
		log.Println("请求解析失败, error=", err)
		return nil, errors.New("解析数据错误")
	}
	if jlAccountResult.Code != 0 {
		return nil, errors.New(fmt.Sprintf("%s", jlAccountResult.Msg))
	}

	return jlAccountResult.Data, nil
}

// 拉取计量项目信息
func (j *Jlzf) GetProjectAndAccount(code string, account string) (map[string]interface{}, map[string]interface{}, error) {
	var (
		tokenString string
		err         error
		resultByte  []byte
		jlResult    jlResult
	)
	// 1.生成请求数据
	expirationTime := time.Now().Add(3 * time.Second)
	claimsData := jwt.MapClaims{
		"data": map[string]string{"code": code, "account": account},
		"exp":  expirationTime.Unix(),
		"iat":  time.Now().Unix(),
	}
	// 1-1.生成token
	if tokenString, err = makeTokenString(claimsData); err != nil {
		return nil, nil, errors.New("生成请求token错误")
	}
	fmt.Println(tokenString)
	// 1-2.发送请求
	if resultByte, err = utils.PullData("GET", j.AuthUrl+"/management/account?auth="+tokenString, ""); err != nil {
		return nil, nil, errors.New(fmt.Sprintf("计量错误，err= %s", err))
	}
	// fmt.Println(string(body))
	// result := map[string]interface{}{}
	err = json.Unmarshal(resultByte, &jlResult)
	if err != nil {
		log.Println("请求解析失败, error=", err)
		return nil, nil, errors.New("解析数据错误")
	}
	if jlResult.Code != 0 {
		return nil, nil, errors.New(fmt.Sprintf("%s", jlResult.Msg))
	}

	return jlResult.Data.Project, jlResult.Data.Account, nil
}

// 验证计量支付项目账号的登陆密码
func (j *Jlzf) LoginValid(loginData viewmodels.Login) error {
	var (
		tokenString string
		err         error
		resultByte  []byte
		jlResult    jlResult
	)

	// 1.生成请求数据
	expirationTime := time.Now().Add(3 * time.Second)
	claimsData := jwt.MapClaims{
		"data": map[string]string{"code": loginData.Code, "account": loginData.Account, "password": loginData.Password},
		"exp":  expirationTime.Unix(),
		"iat":  time.Now().Unix(),
	}
	// 1-1.生成token
	if tokenString, err = makeTokenString(claimsData); err != nil {
		return errors.New("生成请求token错误")
	}

	// 1-2.发送请求  验证计量密码接口
	if resultByte, err = utils.PullData("GET", j.AuthUrl+"/management/account/valid?auth="+tokenString, ""); err != nil {
		return errors.New(fmt.Sprintf("计量错误，err= %s", err))
	}
	err = json.Unmarshal(resultByte, &jlResult)

	if err != nil {
		log.Println("请求解析失败, error=", err)
		return errors.New("解析数据错误")
	}
	if jlResult.Code != 0 {
		return errors.New(fmt.Sprintf("%s", jlResult.Msg))
	}
	return nil
}
