package service

import (
	"github.com/gomodule/redigo/redis"
	"github.com/tidwall/gjson"
	"go_sku_server/model"
	c "go_sku_server/pkg/common"
	"go_sku_server/pkg/gredis"
	"sort"
	"strconv"
)

type PriceService struct {
}

//这里有个前置条件处理美金价,因为element(6)存到美金字段里面的是港币,rs(21)存到美金字段里的是人民币,buerklin(1676)是欧元
//所以要全部先转成正确的美金价才能显示,目前先写死汇率,因为目前没有地方能获取实时的各种转美金的汇率
func (ls *LyService) TransformSpecialSupplierPrice(supplierId int64, priceUs float64, usRatio float64) float64 {
	switch supplierId {
	case 6:
		customRate := 7.85 //港币转美金
		priceUs = c.MyRound(c.DivFloat(priceUs, customRate), 4)
		break
	case 21:
		customRate := usRatio //人民币转美金
		priceUs = c.MyRound(c.DivFloat(priceUs, customRate), 4)
		priceUs = c.MyRound(c.DivFloat(priceUs, 1.13), 4)
		break
	case 1676:
		customRate := 0.93 //欧元转美金
		priceUs = c.MyRound(c.DivFloat(priceUs, customRate), 4)
		break
		// case 1673:
		// 	customRate := 0.93 //欧元转美金
		// 	priceUs = c.MyRound(c.DivFloat(priceUs, customRate), 4)
		// 	break
	}
	return priceUs
}

//构建专营的阶梯价,现在专营只会存一个简单的成本价,阶梯数量是1,所以我这边要根据专营的阶梯系数去构建具体的阶梯价
func (ps *PriceService) GenerateLadderPrice(sku model.LySku) (generatedLadderPrice []model.LadderPrice, showPriceRatio []model.PriceRatio) {
	//先直接获取成本价原始值,判断第一个阶梯的阶梯数量是否为0,如果是0,那么代表是要走成本价生成,如果不是0,那么就要走阶梯价生成
	firstLadderPurchases := sku.LadderPrice[0].Purchases
	isCostPrice := bool(firstLadderPurchases == 0)

	//先去获取配置的redis
	redisCon := gredis.Conn("default_r")
	defer redisCon.Close()
	priceRatio, _ := redis.String(redisCon.Do("HGET", "magic_cube_price_rule_v2", sku.Canal))
	//拿不到就去取默认的
	if priceRatio == "" {
		priceRatio, _ = redis.String(redisCon.Do("GET", "magic_cube_price_rule_v2_default"))
	}
	//这是用来展示在商品服务的价格系数,专营的系数和代购的不一样,所以要转换一下展示形式
	//是否有设置最低利润点阶梯,不足5个阶梯时,最高阶梯对应的最小利润点阶梯
	ladderPriceMiniProfitLevel := int(gjson.Get(priceRatio, "ladder_price_mini_profit_level").Int())
	//判断是否走成本价判断还是走阶梯价判断,因为上传sku的时候,可以设置每个sku的成本价(人民币&&美金),也可以设置每个sku的阶梯价
	//如果有阶梯价,就要跳过设置的成本价(假设有设置的话)
	if isCostPrice {
		costPriceCn := sku.LadderPrice[0].PriceCn
		costPriceUs := sku.LadderPrice[0].PriceUs
		//fmt.Println("人民币和美金的成本价分别为 : ", costPriceCn, costPriceUs)
		//先去判断起订量,如果起订量小于50,就要走固定配置的阶梯价格系数
		if sku.Moq <= 50 {
			moq := int(sku.Moq)
			fixedRatio := make(map[int]float64)
			//var fixedRatioSlice map[int]float64
			switch {
			case sku.Moq < 10:
				//fixedRatio = map[int]float64{moq: 1.07, 30: 1.08, 100: 1.09, 300: 1.1, 1000: 1.11}
				fixedRatio = map[int]float64{moq: 1.11, 30: 1.1, 100: 1.09, 300: 1.08, 1000: 1.07}
				break
			case sku.Moq < 30:
				//fixedRatio = map[int]float64{moq: 1.07, 50: 1.08, 200: 1.09, 500: 1.1, 1000: 1.11}
				fixedRatio = map[int]float64{moq: 1.11, 50: 1.1, 200: 1.09, 500: 1.08, 1000: 1.07}
				break
			default:
				//fixedRatio = map[int]float64{moq: 1.07, 200: 1.08, 500: 1.09, 1000: 1.1, 2000: 1.11}
				fixedRatio = map[int]float64{moq: 1.11, 200: 1.1, 500: 1.09, 1000: 1.08, 2000: 1.07}
				break
			}

			//然后根据一开始只有一个的阶梯价去生成阶梯价格
			for purchases, ratio := range fixedRatio {
				//同时还要构建价格系数展示在商品服务
				showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: ratio, RatioUsd: ratio})
				generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
					Purchases: int64(purchases),
					PriceCn:   c.MyRound(c.MulFloat(costPriceCn, ratio), 4),
					PriceUs:   c.MyRound(c.MulFloat(costPriceUs, ratio), 4),
				})
			}
			sort.Slice(showPriceRatio, func(i, j int) bool {
				return showPriceRatio[i].Ratio > showPriceRatio[j].Ratio
			})
			sku.PriceRatio = showPriceRatio

			sort.Slice(generatedLadderPrice, func(i, j int) bool {
				return generatedLadderPrice[i].Purchases < generatedLadderPrice[j].Purchases
			})
			return generatedLadderPrice, showPriceRatio
		}
		//判断最小起订量是属于哪个范围
		ratioKey := ""
		if sku.Moq >= 50 && sku.Moq < 200 {
			ratioKey = "cost_ladder_price_egt50_lt200"
		} else {
			ratioKey = "cost_ladder_price_egt200"
		}
		costLadderPriceRatio := gjson.Get(priceRatio, ratioKey).Map()
		// 成本价阶梯数 由最高库存计算得到
		costLadderCount := 0
		for i := 1; i <= len(costLadderPriceRatio); i++ {
			costPurchases := costLadderPriceRatio[strconv.Itoa(i)].Get("purchases").Int()
			if costPurchases*sku.Moq > sku.Stock {
				break
			}
			costLadderCount++
		}
		//fmt.Println("阶梯数量为 : ", costLadderCount)
		//fmt.Println("设置的利润阶梯为 : ", ladderPriceMiniProfitLevel)
		if costLadderCount <= ladderPriceMiniProfitLevel {
			for i := 1; i <= costLadderCount; i++ {
				priceRatioAndPurchases := costLadderPriceRatio[strconv.Itoa(i)]
				// 阶梯数量系数正序取
				costPurchases := sku.Moq * priceRatioAndPurchases.Get("purchases").Int()
				//fmt.Println(costPurchases, sku.Stock)
				// 阶梯数量上限为库存量,超出则不再计算下级阶梯
				if costPurchases > sku.Stock {
					break
				}
				//利润阶梯索引
				//计算出库存满足了n个价格阶梯之后 从最小利润点层级反向取n个层级,然后正序计算
				//如:库存满足1、2、3层阶梯,最小利润点层级是第5个层级,则利润点取3、4、5层级的
				//最小利润点层级 - 库存满足多少个阶梯 + i
				costMapIndex := ladderPriceMiniProfitLevel - costLadderCount + i
				if costMapIndex <= 0 {
					costMapIndex = 1
				}
				priceRatioAndPurchases = costLadderPriceRatio[strconv.Itoa(costMapIndex)]
				//fmt.Println("获取到的阶梯系数为 : ", priceRatioAndPurchases)
				priceCnRatio := priceRatioAndPurchases.Get("price").Float()
				priceUsRatio := priceRatioAndPurchases.Get("price_usd").Float()
				// 阶梯价格系数正序取
				showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: priceCnRatio, RatioUsd: priceUsRatio})
				generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
					Purchases: costPurchases,
					PriceCn:   c.MyRound(c.MulFloat(costPriceCn, priceCnRatio), 4),
					PriceUs:   c.MyRound(c.MulFloat(costPriceUs, priceUsRatio), 4),
				})
				sku.PriceRatio = showPriceRatio
			}
		} else {
			//价格阶梯数量超过最利润点的层级的情况
			for i := 1; i <= costLadderCount; i++ {
				priceRatioAndPurchases := costLadderPriceRatio[strconv.Itoa(i)]
				// 阶梯数量系数正序取
				costPurchases := sku.Moq * priceRatioAndPurchases.Get("purchases").Int()
				// 阶梯数量上限为库存量,超出则不再计算下级阶梯
				if costPurchases > sku.Stock {
					break
				}
				priceCnRatio := priceRatioAndPurchases.Get("price").Float()
				priceUsRatio := priceRatioAndPurchases.Get("price_usd").Float()
				showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: priceCnRatio, RatioUsd: priceUsRatio})
				// 阶梯价格系数正序取
				generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
					Purchases: sku.Moq * priceRatioAndPurchases.Get("purchases").Int(),
					PriceCn:   c.MyRound(c.MulFloat(costPriceCn, priceCnRatio), 4),
					PriceUs:   c.MyRound(c.MulFloat(costPriceUs, priceUsRatio), 4),
				})
			}
			sku.PriceRatio = showPriceRatio
		}
		return generatedLadderPrice, showPriceRatio
	} else {
		ladderPriceRatio := gjson.Get(priceRatio, "ladder_price_egt50_lt200").Map()
		//fmt.Println(ladderPriceRatio)
		ladderCount := len(sku.LadderPrice)
		//走阶梯价
		if ladderCount <= ladderPriceMiniProfitLevel {
			for i := 1; i <= ladderCount; i++ {
				ladder := sku.LadderPrice[i-1]
				//利润阶梯索引
				//计算出库存满足了n个价格阶梯之后 从最小利润点层级反向取n个层级,然后正序计算 如:库存满足1、2、3层阶梯,最小利润点层级是第5个层级,则利润点取3、4、5层级的
				//最小利润点层级 - 库存满足多少个阶梯 + i
				costMapIndex := ladderPriceMiniProfitLevel - ladderCount + i
				if costMapIndex <= 0 {
					costMapIndex = 1
				}
				//fmt.Println(costMapIndex)
				priceRatio := ladderPriceRatio[strconv.Itoa(costMapIndex)]
				//fmt.Println("获取到的阶梯系数为 : ", priceRatio)
				priceCnRatio := priceRatio.Get("ratio").Float()
				priceUsRatio := priceRatio.Get("ratio_usd").Float()
				showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: priceCnRatio, RatioUsd: priceUsRatio})
				// 阶梯价格系数正序取
				generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
					Purchases: ladder.Purchases,
					PriceCn:   c.MyRound(c.MulFloat(ladder.PriceCn, priceCnRatio), 4),
					PriceUs:   c.MyRound(c.MulFloat(ladder.PriceUs, priceUsRatio), 4),
				})
			}
			sku.PriceRatio = showPriceRatio

		} else {
			//价格阶梯数量超过最利润点的层级的情况
			for i := 1; i <= 9; i++ {
				ladder := sku.LadderPrice[i-1]
				// 阶梯数量系数正序取
				priceRatio := ladderPriceRatio[strconv.Itoa(i)]
				priceCnRatio := priceRatio.Get("ratio").Float()
				priceUsRatio := priceRatio.Get("ratio_usd").Float()
				showPriceRatio = append(showPriceRatio, model.PriceRatio{Ratio: priceCnRatio, RatioUsd: priceUsRatio})
				// 阶梯价格系数正序取
				generatedLadderPrice = append(generatedLadderPrice, model.LadderPrice{
					Purchases: int64(ladder.Purchases),
					PriceCn:   c.MyRound(c.MulFloat(ladder.PriceCn, priceRatio.Get("ratio").Float()), 4),
					PriceUs:   c.MyRound(c.MulFloat(ladder.PriceUs, priceRatio.Get("ratio_usd").Float()), 4),
				})
			}
			sku.PriceRatio = showPriceRatio
		}
		return generatedLadderPrice, showPriceRatio
	}
}