// tonumber
package main

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"
)

var contentUnit *regexp.Regexp          //全文检索单位：万元
var regOperator *regexp.Regexp          //运算符号
var regNumFloat *regexp.Regexp          //提取整数或浮点数
var moneyRegChar *regexp.Regexp         //提取中文数字
var regStrUnit *regexp.Regexp           //提取单位
var moneyChar = map[string]interface{}{ //"〇": "0", "零": "0",
	"一": float64(1), "壹": float64(1), "二": float64(2), "贰": float64(2), "三": float64(3), "叁": float64(3), "四": float64(4), "肆": float64(4), "五": float64(5), "伍": float64(5),
	"六": float64(6), "陆": float64(6), "七": float64(7), "柒": float64(7), "八": float64(8), "捌": float64(8), "九": float64(9), "玖": float64(9), "十": float64(10), "拾": float64(10),
	"百": float64(100), "佰": float64(100), "千": float64(1000), "仟": float64(1000), "万": float64(10000), "亿": float64(100000000), "億": float64(100000000),
	"零": float64(0), "点": ".", "角": float64(0.1), "分": float64(0.01),
}
var moneyUnit = map[string]float64{
	"元": float64(1), "万": float64(10000), "亿": float64(100000000), "億": float64(100000000), //单位
}
var spaces = []string{"\u3000", "\u2003", "\u00a0"}
var cutAllSpace = regexp.MustCompile(`\s*`)

func init() {
	regOperator, _ = regexp.Compile(`[*|+|)*)]`)
	regNumFloat, _ = regexp.Compile(`([1-9]\d*|0)(\.\d+)?`)
	regStrUnit, _ = regexp.Compile(`[元|万|亿]`)

	regStrChar := `[〇|零|点|.|．|壹|贰|叁|肆|伍|陆|柒|捌|玖|拾|百|佰|千|仟|万|亿|億|元|圆|角|分|整|正]`
	moneyRegChar, _ = regexp.Compile(regStrChar)

	contentUnit, _ = regexp.Compile(`(万元|单位/万)`)
}

//转int
func ObjToInt(data []interface{}) []interface{} {
	tmp, err := strconv.Atoi(fmt.Sprint(data[0]))
	if err != nil {
		data[0] = 0
		return data
	} else {
		data[0] = tmp
		return data
	}
}

//转float,精度小数点4位
func ObjToFloat(data []interface{}) []interface{} {
	tmp, err := strconv.ParseFloat(fmt.Sprint(data[0]), 64)
	if err != nil {
		return []interface{}{float64(0), data[1]}
	} else {
		tmp, err = strconv.ParseFloat(strconv.FormatFloat(tmp, 'f', 4, 64), 64)
		if err != nil {
			return []interface{}{float64(0), data[1]}
		} else {
			return []interface{}{tmp, data[1]}
		}
	}
}

//金额转换
func ObjToMoney(data []interface{}) []interface{} {
	isfindUnit := true
	ret := capitalMoney(data)[0]
	if ret.(float64) < float64(10000) || ret.(float64) > float64(50000000000) {
		ret2, b := numMoney(data)
		isfindUnit = b
		if ret2[0].(float64) > ret.(float64) {
			ret = ret2[0]
		}
	}
	f, _ := strconv.ParseFloat(strconv.FormatFloat(ret.(float64), 'f', 4, 64), 64)
	if f < 1 {
		f = 0
	}
	//若果金额小于50，全文检索单位：万
	if f < 50 && f > 0 && isfindUnit {
		rep := contentUnit.FindAllStringIndex(fmt.Sprint(data[1]), -1)
		if len(rep) > 0 {
			f = f * 10000
		}
	}
	data[0] = f
	return data
}

//清理所有空白符
func CutAllSpace(data []interface{}) []interface{} {
	tmp := cutAllSpace.ReplaceAllString(fmt.Sprint(data[0]), "")
	tmp = replaceSymbol(tmp, spaces)
	data[0] = tmp
	return data
}

//数字金额转换
func numMoney(data []interface{}) ([]interface{}, bool) {
	tmp := fmt.Sprint(data[0])
	tmp = replaceSymbol(tmp, []string{",", "，", "（", "）", "(", ")", "：", "\n"})
	tmp = replaceString(tmp, []string{"万元", "亿元", "．"}, []string{"万", "亿", "."})
	tmp = fmt.Sprint(CutAllSpace([]interface{}{tmp, data[1]})[0])
	rets := regNumFloat.FindAllString(tmp, -1)
	fnums := []float64{}
	unitstrs := []string{}
	if len(rets) > 0 {
		pindex := 0 //单位前置
		for k, v := range rets {
			f, err := strconv.ParseFloat(v, 64)
			if err == nil {
				fnums = append(fnums, f)
				index := strings.Index(tmp, v)
				//单位后置
				start := index + len(v)
				end := start + 3
				//log.Println("vvv", tmp, v, pindex, index, start)
				if k > 0 {
					if start >= pindex+3 {
						pstart := pindex + 3
						if pstart >= index {
							pstart = index
						}
						if len(tmp) > end {
							unitstrs = append(unitstrs, tmp[pstart:index]+tmp[start:end])
						} else {
							unitstrs = append(unitstrs, tmp[pstart:index]+tmp[start:])
						}
					} else {
						if len(tmp) > end {
							unitstrs = append(unitstrs, tmp[start:end])
						} else {
							unitstrs = append(unitstrs, tmp[start:])
						}
					}
				} else {
					if len(tmp) > end {
						if index-3 >= 0 {
							unitstrs = append(unitstrs, tmp[index-3:index]+tmp[start:end])
						} else {
							unitstrs = append(unitstrs, tmp[start:end])
						}
					} else {
						if index-3 >= 0 {
							unitstrs = append(unitstrs, tmp[index-3:index]+tmp[start:])
						} else {
							unitstrs = append(unitstrs, tmp[start:])
						}
					}
				}
				pindex = start
			}
		}
	}
	//log.Println("unitstrs", fnums, unitstrs)
	unit := float64(0)
	fnum := float64(0)
	for k, v := range fnums {
		fnum = v
		units := regStrUnit.FindAllString(unitstrs[k], -1)
		for _, v := range units {
			if moneyUnit[v] != 0 {
				unit = moneyUnit[v]
				break
			}
		}
		if unit != float64(0) { //取第一个
			break
		}
	}
	if unit == float64(0) {
		data[0] = fnum
	} else {
		data[0] = fnum * unit
	}
	if unit == 10000 {
		return data, false
	} else {
		return data, true
	}
}

//大写数子金额转换
func capitalMoney(data []interface{}) []interface{} {
	nodes := []float64{}
	node := float64(0)
	tmp := float64(0)
	decimals := 0.0
	ishaspoint := false //是否含小数点
	fnum := float64(0)
	moneyRegChar.ReplaceAllStringFunc(fmt.Sprint(data[0]), func(key string) string {
		if key == "元" || key == "圆" || key == "点" {
			ishaspoint = true
		}
		if v, ok := moneyChar[key].(float64); ok {
			if (ishaspoint && v > 10) || key == "整" || key == "正" { //排除后面有其他的单位
				return ""
			}
			//log.Println(key, v, fnum)
			if v < 10 && v >= 0 {
				if ishaspoint { //小数部分
					if v >= 1 {
						fnum = v
					} else if v < 1 && v > 0 {
						decimals += fnum * v
					}
				} else {
					if tmp != float64(0) {
						node += tmp
					}
					tmp = float64(v)
				}
			} else if v == 10000 || v == 100000000 { //单位万、亿
				if tmp != float64(0) {
					node += tmp
					tmp = float64(0)
				}
				nodes = append(nodes, node*float64(v))
				node = float64(0)
			} else {
				if v == 10 && tmp == 0 {
					tmp = 1
				}
				tmp = tmp * float64(v)
				node += tmp
				tmp = float64(0)
			}
		}
		return ""
	})
	nodes = append(nodes, node, tmp)
	ret := float64(0)
	for _, v := range nodes {
		ret = ret + v
	}
	return []interface{}{ret + decimals, data[1]}
}

//过滤符号
func replaceSymbol(con string, rep []string) string {
	for _, v := range rep {
		con = strings.Replace(con, v, "", -1)
	}
	return con
}

//符号替换
func replaceString(con string, ret, rep []string) string {
	for k, v := range ret {
		if len(rep) > k {
			con = strings.Replace(con, v, rep[k], -1)
		}
	}
	return con
}

//费率转小数
func RateToFloat(con []interface{}) []interface{} {
	tmp := fmt.Sprint(CutAllSpace(con)[0])
	if strings.Contains(tmp, "%") || strings.Contains(tmp, "％") {
		tmp = strings.Replace(tmp, "%", "", -1)
		tmp = strings.Replace(tmp, "％", "", -1)
		rep := ObjToFloat([]interface{}{tmp, con[1]})[0]
		con[0] = rep.(float64) / 100
		return con
	} else {
		return ObjToFloat([]interface{}{tmp, con[1]})
	}
}

//大于一万亿的过滤掉
func ClearMaxAmount(data []interface{}) []interface{} {
	value, _ := data[0].(float64)
	if value >= 1000000000000 {
		data[0] = float64(0)
	}
	return data
}
