/*
 * @description:工具函数
 * @Author: CP
 * @Date: 2020-09-03 10:08:52
 * @FilePath: \construction_management\web\utils\utils.go
 */
package utils

import (
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/kataras/iris/v12"
	"github.com/spf13/viper"
	"go.mod/comm"
	"go.mod/conf"
)

// 发送短信
func SendSMS() {

}

// 获得员工组
func GetAccountGroup() map[int]string {
	groupDate := map[int]string{
		1: "建设单位",
		2: "监理单位",
		3: "施工单位",
		4: "设计单位",

		5: "代建单位",
		6: "跟踪审计",
		8: "总包单位",
		9: "分包单位",
		7: "其他",
	}
	return groupDate
}

// 字符串转换MAP
func StringToMap(str string, split string) map[string]string {
	entries := strings.Split(str, split)
	strMap := make(map[string]string)

	for _, e := range entries {
		parts := strings.Split(e, ":")
		if len(parts) <= 1 {
			strMap["error"] = strings.Replace(parts[0], " ", "", -1)
		} else {
			strMap[strings.Replace(parts[0], " ", "", -1)] = strings.Replace(parts[1], " ", "", -1)
		}

	}
	return strMap
}

// 获得项目ID
func GetBackstageKey(ctx iris.Context, key string) (string, error) {
	//account := ctx.Values().Get("account").(*models.CmProjectAccount)
	// fmt.Println(account)
	value := ctx.Values().GetString(key)

	if value == "" {
		return "", errors.New("员工名称不存在")
	}
	return value, nil
}

// 获得项目ID
func GetProjectId(ctx iris.Context) (int, error) {
	//account := ctx.Values().Get("account").(*models.CmProjectAccount)
	// fmt.Println(account)
	projectId, err := ctx.Values().GetInt("projectId")
	if err != nil {
		return 0, errors.New("项目不存在")
	}
	return projectId, nil
}

// 获得项目账号ID
func GetProjectAccountId(ctx iris.Context) (int, error) {

	identityIdInt, err := ctx.Values().GetInt("accountId")
	if err != nil {
		return 0, errors.New("项目账号不存在")
	}
	return identityIdInt, nil
}

// 获得解密后的ID
func GetDecryptId(id string) (int, error) {
	if id == "" {
		return 0, errors.New("ID 解析错误")
	}
	id, err := comm.AesDecrypt(id, conf.SignSecret)
	if err != nil {
		return 0, errors.New("ID 解析错误")
	}
	idInt, err := strconv.Atoi(id)
	if err != nil {
		return 0, errors.New("ID 转换错误")
	}
	return idInt, nil
}

// 金额转字符串 保留2位小数
func PriceToStringFormat(price float64) string {
	// fmt.Println("price=========================")
	// fmt.Println(price)
	return fmt.Sprintf("%.2f", price)
	// return fmt.Sprintf("%g", price)
}

// 生成code
func CreateRuleCode(code int64, count int64, len int) string {
	// fmt.Println("rule", rule, "counts", count)
	// egRule := strings.Split(rule.Eg, "-")
	// for _, value := range egRule {
	// 	if strings.Contains(value, "_") {
	// 		// fmt.Println("rule", rule.Code, count)
	// 		code := fmt.Printf("%0*d", rule.Code, count+1)

	// 		strings.Replace(rule.Eg, )

	// 	}
	// }
	// fmt.Println("egRule:", egRule)
	// return "123"
	// var newCode string
	if code == 0 {
		a := fmt.Sprintf("%0*d", len, count)
		return a
	} else {
		b := fmt.Sprintf("%0*d", len, count+code)
		return b
	}
}

// 对计量请求token
func CreateJlToken(data jwt.MapClaims) (string, error) {
	var (
		tokenString string
		err         error
	)
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, data)
	if tokenString, err = token.SignedString([]byte(conf.JLSecretKey)); err != nil {
		return "", err
	}
	return tokenString, nil
}

// 验证并解析JWT
func ValidateJwt(tokenStr string) (map[string]interface{}, error) {
	// 0.测试时使用
	// 在这里声明令牌的到期时间，我们将其保留为5分钟
	tokenString, _ := CreateJlToken(jwt.MapClaims{
		"data": map[string]string{"code": "P0401", "account": "linqiang-2", "newAccount": "linqiang-3"},
		"exp":  time.Now().Add(24 * time.Hour).Unix(),
	})
	log.Println("JWT 5分钟过期-开发使用,=", tokenString)

	// 1.验证并解析JWT
	parseAuth, err := jwt.Parse(tokenStr, func(*jwt.Token) (interface{}, error) {
		return []byte(conf.JLSecretKey), nil
	})
	if err != nil {
		log.Println("JWT异常, error=", err)
		return nil, err
	}
	if !parseAuth.Valid {
		if ve, ok := err.(*jwt.ValidationError); ok {
			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				return nil, errors.New("无效签名")
			} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
				return nil, errors.New("过期签名")
			} else {
				return nil, errors.New("无效签名")
			}
		}
		return nil, errors.New("无效签名")
	}

	// 1-2.转换为map
	claims := parseAuth.Claims.(jwt.MapClaims)

	data, ok := claims["data"].(map[string]interface{})
	if !ok {
		return nil, errors.New("解析data失败")
	}
	// jlRequest := jlRequest{}
	// err = json.Unmarshal(claims, &jlRequest)
	// if err != nil {
	// 	log.Println("请求移除, error=", err)
	// 	return errors.New("解析数据错误")
	// }
	// if err := json.Unmarshal(tokData, &claims); err != nil {
	// 	return nil, err
	// }

	return data, nil
}

// 验证并解析JWT
func ValidateJwtBB(tokenStr string) error {

	// 1.验证并解析JWT
	parseAuth, err := jwt.Parse(tokenStr, func(*jwt.Token) (interface{}, error) {
		return []byte(conf.JLBBSecretKey), nil
	})
	if err != nil {
		log.Println("JWT异常, error=", err)
		return err
	}
	if !parseAuth.Valid {
		if ve, ok := err.(*jwt.ValidationError); ok {
			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				return errors.New("无效签名")
			} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
				return errors.New("过期签名")
			} else {
				return errors.New("无效签名")
			}
		}
		return errors.New("无效签名")
	}

	return nil
}

func GetEnvInfo(env string) string {
	viper.AutomaticEnv()
	return viper.GetString(env)
}

type jlRequest struct {
	Data map[string]interface{} `json:"data" `
}

func PullData(method string, authUrl string, tokenString string) ([]byte, error) {

	var (
		err    error
		reqest *http.Request
	)
	client := &http.Client{}
	if method == "POST" || method == "post" {
		// 1.构建请求体
		data := url.Values{}
		data.Set("auth", tokenString)
		parameter := strings.NewReader(data.Encode())
		// 2.开始请求准备
		reqest, err = http.NewRequest(method, authUrl, parameter)
		reqest.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	} else if method == "GET" || method == "get" {
		reqest, err = http.NewRequest(method, authUrl, nil)
		reqest.Header.Add("Content-Type", "application/json; charset=utf-8")
	}
	if err != nil {
		log.Println("请求移除, error=", err)
		return nil, errors.New("网络出现问题")
	}

	// 3.发送请求
	response, err := client.Do(reqest)
	if err != nil {
		log.Println("请求移除, error=", err)
		return nil, errors.New("网络出现问题")
	}
	if response.StatusCode != 200 {
		return nil, errors.New("请求发送错误")
	}

	// 4.结构化返回数据
	body, _ := ioutil.ReadAll(response.Body)
	return body, nil
	// fmt.Println(string(body))
	// result := map[string]interface{}{}
	// err = json.Unmarshal(body, &result)
	// if err != nil {
	// 	log.Println("请求移除, error=", err)
	// 	return nil, errors.New("解析数据错误")
	// }

	// if result["code"].(float64) != 0 {
	// 	return nil, errors.New(fmt.Sprintf("%s", result["msg"]))
	// }

	// return result, nil
}

// // 获得项目ID
// func GetProjectId(ctx iris.Context) (int, error) {
// 	jwtInfo := ctx.Values().Get("jwt").(*jwt.Token)
// 	project := jwtInfo.Claims.(jwt.MapClaims)["project"].(string)
// 	projectId, err := comm.AesDecrypt(project, conf.CookieSecret)
// 	if err != nil {
// 		return 0, errors.New("项目不存在")
// 	}
// 	projectIdInt, err := strconv.Atoi(projectId)
// 	if err != nil {
// 		return 0, errors.New("项目不存在")
// 	}
// 	return projectIdInt, nil
// }

// // 获得项目账号ID
// func GetProjectAccountId(ctx iris.Context) (int, error) {
// 	jwtInfo := ctx.Values().Get("jwt").(*jwt.Token)
// 	identity := jwtInfo.Claims.(jwt.MapClaims)["identity"].(string)
// 	identityId, err := comm.AesDecrypt(identity, conf.CookieSecret)
// 	if err != nil {
// 		return 0, errors.New("项目账号不存在")
// 	}
// 	identityIdInt, err := strconv.Atoi(identityId)
// 	if err != nil {
// 		return 0, errors.New("项目账号不存在")
// 	}
// 	return identityIdInt, nil
// }
