package utils

import (
	"database/sql"
	"fmt"
	"git.i2edu.net/i2/i2-bill-erp/transform"
	"hash/crc32"
	"reflect"
	"strconv"
	"strings"
	"time"

	uuid "github.com/satori/go.uuid"
)

func GetUUID() string {
	return uuid.NewV4().String()
}

//the result likes 1423361979
func GetTimestamp() int64 {
	return time.Now().Unix()
}

func Int2String(val int64) string {
	return strconv.Itoa(int(val))
}

func ValidTime(t time.Time) bool {
	t1970, _ := time.Parse("2006-01-02", "1970-01-01")
	return t.After(t1970)
}

func String2Int64(str string) int64 {
	number, _ := strconv.ParseInt(str, 10, 64)
	return number
}

func HashCode(s string) int {
	v := int(crc32.ChecksumIEEE([]byte(s)))
	if v >= 0 {
		return v
	}
	if -v >= 0 {
		return -v
	}
	return 0
}

func GetTimeYmd() time.Time {
	timeNow := time.Now()
	return time.Date(timeNow.Year(), timeNow.Month(), timeNow.Day(), 0, 0, 0, 0, time.Local)
}

//剔除sqlx.NullTime等model数据结构
func UnmarshalMysqlRows(row interface{}) []map[string]interface{} {
	tyR := reflect.TypeOf(row)
	if tyR.Kind() != reflect.Slice {
		panic("row must slice")
	}
	vR := reflect.ValueOf(row)

	var rows []map[string]interface{}
	for i := 0; i < vR.Len(); i++ {
		value := vR.Index(i).Interface()
		r := UnmarshalMysqlRow(value)
		rows = append(rows, r)
	}
	return rows
}

func UnmarshalMysqlRow(row interface{}) map[string]interface{} {
	tyR := reflect.TypeOf(row)
	if tyR.Kind() != reflect.Struct {
		panic("row must struct")
	}
	tyV := reflect.ValueOf(row)
	var Row = make(map[string]interface{})
	for i := 0; i < tyR.NumField(); i++ {
		tag := tyR.Field(i).Tag.Get("db")
		if tag == "" {
			tag = tyR.Field(i).Name
		}
		tyF := reflect.TypeOf(tyV.Field(i).Interface())
		switch tyF.Kind() {
		case reflect.Struct:
			switch tyV.Field(i).Type().String() {
			case "sql.NullTime":
				reStruct := tyV.Field(i).Interface().(sql.NullTime)
				if !reStruct.Time.Equal(time.Time{}) && reStruct.Time.Unix() != 0 {
					Row[tag] = reStruct.Time
				} else {
					Row[tag] = ""
				}

			case "sql.NullBool":
				reStruct := tyV.Field(i).Interface().(sql.NullBool)
				Row[tag] = reStruct.Bool
			case "sql.NullFloat64":
				reStruct := tyV.Field(i).Interface().(sql.NullFloat64)
				Row[tag] = reStruct.Float64
			case "sql.NullInt32":
				reStruct := tyV.Field(i).Interface().(sql.NullInt32)
				Row[tag] = reStruct.Int32
			case "sql.NullInt64":
				reStruct := tyV.Field(i).Interface().(sql.NullInt64)
				Row[tag] = reStruct.Int64
			case "sql.NullString":
				reStruct := tyV.Field(i).Interface().(sql.NullString)
				Row[tag] = reStruct.String
			case "time.Time":
				reStruct := tyV.Field(i).Interface().(time.Time)
				if !reStruct.Equal(time.Time{}) && reStruct.Unix() != 0 {
					Row[tag] = tyV.Field(i).Interface().(time.Time)
				} else {
					Row[tag] = ""
				}
			}
		case reflect.Bool, reflect.Int,
			reflect.Int8, reflect.Int16,
			reflect.Int32, reflect.Int64,
			reflect.Complex128, reflect.Uint,
			reflect.Uint8, reflect.Uint16,
			reflect.Uint32, reflect.Uint64,
			reflect.Uintptr, reflect.Float32,
			reflect.String, reflect.Float64, reflect.Complex64:
			Row[tag] = tyV.Field(i).Interface()
		}

	}
	return Row
}

//返回对应tree的路径id,name
func TreePath(nodes []*transform.TreeNode, tagId int64, idPath, namePath *string) bool {
	for _, node := range nodes {
		if node.Id == tagId {
			*idPath = strings.TrimLeft(*idPath+","+fmt.Sprintf("%d", node.Id), ",")
			*namePath = strings.TrimLeft(*namePath+","+node.Text, ",")
			return true
		}
		if node.Nodes != nil {
			if ok := TreePath(node.Nodes, tagId, idPath, namePath); ok {
				*idPath = fmt.Sprintf("%d", node.Id) + "," + *idPath
				*namePath = node.Text + "," + *namePath
				return ok
			}
		}
	}
	return false
}

//活动id对应的name
func GetErpActiveName(activeId int64, actives []*transform.Active) string {
	for _, a := range actives {
		if a.ActiveId == activeId {
			return a.MaName
		}
	}
	return ""
}

//校区对应的id
func GetErpSchoolName(schId int64, schools []*transform.OrganSchool) string {
	for _, sch := range schools {
		if sch.Id == schId {
			return sch.Name
		}
	}
	return ""
}
