package utils

import (
	"fmt"
	"github.com/syyongx/php2go"
	"reflect"
	"sort"
	"strings"
)

func Implode(glue string, args ...interface{}) string {
	data := make([]string, len(args))
	for i, s := range args {
		data[i] = fmt.Sprint(s)
	}
	return strings.Join(data, glue)
}

//字符串是否在数组里
func InArr(target string, str_array []string) bool {
	for _, element := range str_array {
		if target == element {
			return true
		}
	}
	return false
}

//把数组的值放到key里
func ArrayColumn(array interface{}, key string) (result map[string]interface{}, err error) {
	result = make(map[string]interface{})
	t := reflect.TypeOf(array)
	v := reflect.ValueOf(array)
	if t.Kind() != reflect.Slice {
		return nil, nil
	}
	if v.Len() == 0 {
		return nil, nil
	}
	for i := 0; i < v.Len(); i++ {
		indexv := v.Index(i)
		if indexv.Type().Kind() != reflect.Struct {
			return nil, nil
		}
		mapKeyInterface := indexv.FieldByName(key)
		if mapKeyInterface.Kind() == reflect.Invalid {
			return nil, nil
		}
		mapKeyString, err := InterfaceToString(mapKeyInterface.Interface())
		if err != nil {
			return nil, err
		}
		result[mapKeyString] = indexv.Interface()
	}
	return result, err
}

//转string
func InterfaceToString(v interface{}) (result string, err error) {
	switch reflect.TypeOf(v).Kind() {
	case reflect.Int64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
		result = fmt.Sprintf("%v", v)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		result = fmt.Sprintf("%v", v)
	case reflect.String:
		result = v.(string)
	default:
		err = nil
	}
	return result, err
}

func HideTrueName(name string) string {
	res := "**"
	if name != "" {
		runs := []rune(name)
		leng := len(runs)
		if leng <= 3 {
			res = string(runs[0:1]) + res
		} else if leng < 5 {
			res = string(runs[0:2]) + res
		} else if leng < 10 {
			res = string(runs[0:2]) + "***" + string(runs[leng-2:leng])
		} else if leng < 16 {
			res = string(runs[0:3]) + "****" + string(runs[leng-3:leng])
		} else {
			res = string(runs[0:4]) + "*****" + string(runs[leng-4:leng])
		}
	}
	return res
}
func GetQueryParam(uri string) map[string]string {
	//根据问号分割路由还是query参数
	uriList := strings.Split(uri, "?")
	var query = make(map[string]string, 0)
	//有参数才处理
	if len(uriList) == 2 {
		//分割query参数
		var queryList = strings.Split(uriList[1], "&")
		if len(queryList) > 0 {
			//key value 分别赋值
			for _, v := range queryList {
				var valueList = strings.Split(v, "=")
				if len(valueList) == 2 {
					value, _ := php2go.URLDecode(valueList[1])
					if value == "" {
						value = valueList[1]
					}
					query[valueList[0]] = value
				}
			}
		}
	}
	return query
}

//JoinStringsInASCII 按照规则,参数名ASCII码从小到大排序后拼接
//data 待拼接的数据
//sep 连接符
//onlyValues 是否只包含参数值,true则不包含参数名,否则参数名和参数值均有
//includeEmpty 是否包含空值,true则包含空值,否则不包含,注意此参数不影响参数名的存在
//exceptKeys 被排除的参数名,不参与排序及拼接
func JoinStringsInASCII(data map[string]string, sep string, onlyValues, includeEmpty bool, exceptKeys ...string) string {
	var list []string
	var keyList []string
	m := make(map[string]int)
	if len(exceptKeys) > 0 {
		for _, except := range exceptKeys {
			m[except] = 1
		}
	}
	for k := range data {
		if _, ok := m[k]; ok {
			continue
		}
		value := data[k]
		if !includeEmpty && value == "" {
			continue
		}
		if onlyValues {
			keyList = append(keyList, k)
		} else {
			list = append(list, fmt.Sprintf("%s=%s", k, value))
		}
	}
	if onlyValues {
		sort.Strings(keyList)
		for _, v := range keyList {
			list = append(list, AnyToString(data[v]))
		}
	} else {
		sort.Strings(list)
	}
	return strings.Join(list, sep)
}

// 合并数组
func MergeArr(a, b []int64) []int64 {
	var arr []int64
	for _, i := range a {
		arr = append(arr, i)
	}
	for _, j := range b {
		arr = append(arr, j)
	}
	return arr
}

// 去重
func UniqueArr(m []int64) []int64 {
	d := make([]int64, 0)
	tempMap := make(map[int64]bool, len(m))
	for _, v := range m { // 以值作为键名
		if tempMap[v] == false {
			tempMap[v] = true
			d = append(d, v)
		}
	}
	return d
}