package controller

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/gogf/gf/util/gconv"
	"github.com/syyongx/php2go"
	"go_sku_server/pkg/common"
	"go_sku_server/pkg/gredis"
	"go_sku_server/pkg/logger"
	"go_sku_server/service"
	"sync"
	"time"
)

const goodsSliceCount = 10 //每多少个型号id开启一个协程

/*
  查询商品详情(自营或者联营)
@doc  http://192.168.1.237:3000/project/128/interface/api/649

@param   goods_id                   支持批量,不建议超过40个,超过会导致处理时间超过2秒,进程异常 : 74564,65897,456464131
@param   power[newCustomer]         是否获取新客价  :true
@param   power[member]              是否获取会员价  :true
@param   power[mobile]              获取会员价时,用户有手机号时必填,用于会员价可见名单。活动价时必须,否则可能导致用户无法享受活动价 :13510507993
@param   power[email]               获取会员价时,用户有邮箱时必填,用于会员价可见名单。活动价时必须,否则可能导致用户无法享受活动价   ymx@ichunt.com
@param   power[user_id]             获取会员价时,必填,用于会员价可见名单。活动价时必须,否则可能导致用户无法享受活动价,如果用户未登录,可为空,用户是否可见活动价取决于配置 65139
@param   power[fast]                仅获取价格与库存 :1
@param   power[invoice]             增值税普通发票公司名字,活动价时必须,否则可能导致用户无法享受活动价  :深圳是猎芯科技有限公司
@param   power[special_invoice]     增值税专用发票公司名字,活动价时需要,否则可能导致用户无法享受活动价  : 深圳是猎芯科技有限公司
@param   power[verify_blacklist]    是否验证黑名单,用于折扣活动提交订单页面与后台下单 :true

*/

func CommonController(ctx *gin.Context) map[string]interface{} {
	GoodsIdStr := ctx.Request.FormValue("goods_id")
	common.PrintDebugHeader(ctx) //开启debug调试
	//抽取自营 或者联营 goods_id
	zyService := service.ZiyingService{} //实例化自营查询
	lyService := service.LyService{}     //实例化自营查询
	var goodsIdArr []string
	if GoodsIdStr == "" {
		goodsIdMap := ctx.PostFormMap("goods_id")
		for _, goodsId := range goodsIdMap {
			goodsIdArr = append(goodsIdArr, goodsId)
		}
	} else {
		goodsIdArr = php2go.Explode(",", GoodsIdStr)
	}
	if len(goodsIdArr) == 0 {
		common.Output(ctx, 1001, "查询型号ID不得为空", "")
		return nil
	}

	ch := make(chan sync.Map) //管道
	p := 0                    //总共协程
	zyGoodsId := make([]string, 0)
	lyGoodsId := make([]string, 0)
	for _, goodsId := range goodsIdArr {
		if goodsId == "" {
			continue
		}
		if len(goodsId) < 19 { //自营
			zyGoodsId = append(zyGoodsId, goodsId)
			if len(zyGoodsId) >= goodsSliceCount {
				common.PrintDebugHtml(ctx, "zy增加协程1001:")
				common.PrintDebugHtml(ctx, zyGoodsId)
				//wg.Add(1) //协程计数一
				go zyService.ZyGoodsDetail(ctx, zyGoodsId, ch)
				zyGoodsId = zyGoodsId[:0:0]
				p++
			}
		} else { //联营
			lyGoodsId = append(lyGoodsId, goodsId)
			if len(lyGoodsId) >= goodsSliceCount {
				common.PrintDebugHtml(ctx, "ly增加协程1002:")
				common.PrintDebugHtml(ctx, lyGoodsId)
				//wg.Add(1)
				go lyService.LyGoodsDetail(ctx, lyGoodsId, ch)
				lyGoodsId = lyGoodsId[:0:0]
				p++
			}
		}
	}

	if len(zyGoodsId) > 0 {
		common.PrintDebugHtml(ctx, "zy增加协程1003:")
		common.PrintDebugHtml(ctx, zyGoodsId)
		//wg.Add(1) //协程计数一
		go zyService.ZyGoodsDetail(ctx, zyGoodsId, ch)
		p++
	}

	if len(lyGoodsId) > 0 {
		common.PrintDebugHtml(ctx, "ly增加协程1004:")
		common.PrintDebugHtml(ctx, zyGoodsId)
		go lyService.LyGoodsDetail(ctx, lyGoodsId, ch)
		p++
	}

	//异步map最后转成map
	temp := make(map[string]interface{})
	for i := 0; i < p; i++ {
		select {
		case GoodsRes := <-ch:
			GoodsRes.Range(func(k, v interface{}) bool {
				s, _ := k.(string)
				temp[s] = v
				return true
			})

		case <-time.After(time.Second * 20):
			logger.Log("协程超时", "sku", 1)
		}
	}
	return temp

}
func Synchronization(ctx *gin.Context) {

	res := CommonController(ctx)
	common.Output(ctx, 0, "success", res)
}

/*
健康监测
*/
func Hbsdata(ctx *gin.Context) {
	ctx.String(200, "ok")
}

/*
 测试redis
*/
func Testr(ctx *gin.Context) {

	time1 := time.Now().UnixNano() / 1e6

	redisConn := gredis.Conn("search_r")
	defer func() {
		redisConn.Close()
	}()

	goodsIds := ctx.Request.FormValue("goods_ids")
	skuArr := gredis.Hmget("default_r", "sku", php2go.Explode(",", goodsIds))
	skustr, _ := json.Marshal(skuArr)

	time2 := time.Now().UnixNano() / 1e6

	ctx.String(200, "查询redis开始时间毫秒:"+gconv.String(time1)+" 结束时间毫秒:"+gconv.String(time2)+" 查询时间毫秒:"+gconv.String(time2-time1)+"  "+string(skustr))
}