package svc

import (
	"applet/app/db"
	"applet/app/db/model"
	"applet/app/e"
	"applet/app/md"
	"applet/app/utils"
	"applet/app/utils/cache"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"strings"
	"time"
	"xorm.io/xorm"
)

func PrinterCateList(c *gin.Context) {
	var list = []map[string]string{
		{
			"name": "普通打印机",
			"key":  "ordinary",
		},
	}
	e.OutSuc(c, list, nil)
	return
}

func PrinterLocationList(c *gin.Context) {
	var list = []map[string]string{
		{
			"name": "前台",
			"key":  "reception",
		},
		{
			"name": "后厨",
			"key":  "kitchen",
		},
	}
	e.OutSuc(c, list, nil)
	return
}

// 打印机列表
func PrinterIndexList(c *gin.Context) {
	var search md.IndexRequest
	if err := c.ShouldBindJSON(&search); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	engine := MasterDb(c)
	if engine == nil {
		e.OutErr(c, e.ERR_MASTER_ID, nil)
		return
	}
	user := GetUser(c)
	search.StoreId = utils.IntToStr(user.Info.Uid)
	list, err := db.GetPrinterIndexList(engine, &search)
	fmt.Println(err)
	fmt.Println(list)
	if err != nil {
		e.OutErr(c, e.ERR_BAD_REQUEST, err)
		return
	}
	if list == nil {
		list = make([]md.IndexResList, 0)
	}
	printerModule, _ := db.GetAllPrinterModuleList(engine)
	//处理模板数据
	var moduleArr = make(map[int]string, 0)
	var moduleContentArr = make(map[int]string, 0)
	if printerModule != nil {
		for _, v := range printerModule {
			moduleArr[v.Id] = v.Name
			moduleContentArr[v.Id] = v.Content
		}
	}
	var useArr = []string{"离线", "在线"}
	for k, v := range list {
		isUse := utils.StrToInt(v.IsUse)
		list[k].UseStr = useArr[isUse]
		ModuleId := utils.StrToInt(v.ModuleId)
		list[k].ModuleStr = moduleArr[ModuleId]
		list[k].Content = moduleContentArr[ModuleId]
		list[k].Img = "http://ossn.izhim.net/o2o_printer.png"
	}
	e.OutSuc(c, &list, nil)
	return
}

// 模板列表
func PrinterModuleList(c *gin.Context) {
	var search md.IndexRequest
	if err := c.ShouldBindJSON(&search); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	engine := MasterDb(c)
	if engine == nil {
		e.OutErr(c, e.ERR_MASTER_ID, nil)
		return
	}

	list, err := db.GetPrinterModuleList(engine, &search)
	if err != nil {
		e.OutErr(c, e.ERR_BAD_REQUEST, err)
		return
	}
	if list == nil {
		list = make([]md.ModuleResList, 0)
	}
	e.OutSuc(c, &list, nil)
	return
}
func PrinterIndexSave(c *gin.Context) {
	var search md.IndexSaveRequest
	if err := c.ShouldBindJSON(&search); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	if search.Type == "" {
		search.Type = "ordinary"
	}
	eg := MasterDb(c)
	//判断是不是有人绑过了
	if search.Type != "bluetooth" {
		count := db.IndexExists(eg, &search)
		check := 1
		if utils.StrToInt(search.Id) > 0 {
			//判断下是不是同一条记录保存
			data, _ := db.IndexById(eg, &search)
			if data != nil && data.SnNum == search.SnNum {
				check = 0
			}
		}
		if count > 0 && check == 1 {
			e.OutErr(c, 400, e.NewErr(400, "该打印机已被绑定过"))
			return
		}
	}
	user := GetUser(c)
	var module = model.CommunityTeamStorePrinter{
		Id:                 utils.StrToInt(search.Id),
		StoreId:            user.Info.Uid,
		SnNum:              search.SnNum,
		IdentificationCode: search.IdentificationCode,
		Name:               search.Name,
		IsUse:              utils.StrToInt(search.IsUse),
		UpdateTime:         time.Now(),
		Type:               search.Type,
		LocationType:       search.LocationType,
	}
	if search.Type != "bluetooth" {
		args := md.PrinterReq{
			Sn:          search.SnNum,
			Key:         search.IdentificationCode,
			Remark:      search.Name,
			PrinterType: search.Type,
		}
		//调用公共代码 调用打印机添加与编辑
		if utils.StrToInt(search.Id) > 0 { //编辑
			err := EditPrinter(c, args)
			if err != nil {
				e.OutErr(c, 400, err)
				return
			}
		} else {
			err := AddPrinter(c, args)
			if err != nil {
				e.OutErr(c, 400, err)
				return
			}
		}
	}
	id, err := db.IndexInsert(eg, &module)
	if id == 0 || err != nil {
		e.OutErr(c, 400, e.NewErr(400, "保存失败"))
		return
	}

	return
}

// 模板id修改
func PrinterIndexModuleSave(c *gin.Context) {
	var search md.IndexSaveRequest
	if err := c.ShouldBindJSON(&search); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	var module = model.CommunityTeamStorePrinter{
		Id:         utils.StrToInt(search.Id),
		ModuleId:   utils.StrToInt(search.ModuleId),
		UpdateTime: time.Now(),
	}
	id, err := db.IndexUpdate(MasterDb(c), &module, "module_id,update_time")
	if id == 0 || err != nil {
		e.OutErr(c, 400, e.NewErr(400, "保存失败"))
		return
	}
	e.OutSuc(c, "success", nil)
	return
}

// 使用状态修改
func PrinterIndexStateSave(c *gin.Context) {
	var search md.IndexSaveRequest
	if err := c.ShouldBindJSON(&search); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	var module = model.CommunityTeamStorePrinter{
		Id:         utils.StrToInt(search.Id),
		IsUse:      utils.StrToInt(search.IsUse),
		UpdateTime: time.Now(),
	}
	id, err := db.IndexUpdate(MasterDb(c), &module, "is_use,update_time")
	if id == 0 || err != nil {
		e.OutErr(c, 400, e.NewErr(400, "保存失败"))
		return
	}
	e.OutSuc(c, "success", nil)
	return
}

// 删除打印机
func PrinterDelIndex(c *gin.Context, ids string) {
	engine := MasterDb(c)
	//查出这条记录拿sn码
	user := GetUser(c)
	storeId := utils.IntToStr(user.Info.Uid)
	printerOne, _ := db.GetPrinterIndexById(engine, ids, storeId)
	if printerOne.Id == 0 {
		e.OutErr(c, 400, e.NewErr(400, "删除失败"))
		return
	}
	if printerOne.Type != "bluetooth" {
		//调用打印机删除
		args := md.PrinterReq{
			Sn:          printerOne.SnNum,
			PrinterType: printerOne.Type,
		}
		err := DelPrinter(c, args)
		if err != nil {
			e.OutErr(c, 400, err)
			return
		}
	}
	has, err := engine.Where("id=? and store_id=?", ids, storeId).Delete(new(model.CommunityTeamStorePrinter))
	if err != nil {
		e.OutErr(c, e.ERR_DB_ORM, err)
		return
	}
	if has == 0 {
		e.OutErr(c, 400, e.NewErr(400, "删除失败"))
		return
	}
	e.OutSuc(c, []int{}, nil)
	return
}

// 明细筛选条件
func PrinterIndexRecordScreen(c *gin.Context) {

	engine := MasterDb(c)
	if engine == nil {
		e.OutErr(c, e.ERR_MASTER_ID, nil)
		return
	}
	user := GetUser(c)
	printer, _ := db.GetPrinterIndexAll(engine, utils.IntToStr(user.Info.Uid))
	var r md.RecordPrinterScreen
	r.TimeSort = []md.NewSelectList{
		{
			Key:  "",
			Name: "默认排序",
		},
		{
			Key:  "printer_time_desc",
			Name: "时间由近到远",
		},
		{
			Key:  "printer_time_asc",
			Name: "时间由远到近",
		},
	}
	r.PrinterList = make([]md.NewSelectList, 0)
	for _, v := range printer {
		var tmp = md.NewSelectList{
			Key:  utils.IntToStr(v.Id),
			Name: v.Name,
		}
		r.PrinterList = append(r.PrinterList, tmp)
	}
	e.OutSuc(c, r, nil)
	return
}

// 明细
func PrinterIndexRecordList(c *gin.Context) {
	var search md.RecordRequest
	if err := c.ShouldBindJSON(&search); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	engine := MasterDb(c)
	if engine == nil {
		e.OutErr(c, e.ERR_MASTER_ID, nil)
		return
	}
	user := GetUser(c)
	search.StoreId = utils.IntToStr(user.Info.Uid)
	list, err := db.GetPrinterRecordList(engine, &search)
	if err != nil {
		e.OutErr(c, e.ERR_BAD_REQUEST, err)
		return
	}

	if list == nil {
		list = make([]md.RecordResList, 0)
	}
	var stateArr = []string{"正在打印", "打印成功", "打印失败"}
	var ordTypeArr = []string{"聚合收款订单", "外卖订单", "到店订单", "聚合收款订单"}
	for k, v := range list {
		State := utils.StrToInt(v.State)
		list[k].StateStr = stateArr[State]
		OrdType := utils.StrToInt(v.OrdType)
		list[k].OrdTypeStr = ordTypeArr[OrdType]
		list[k].Title = "#" + v.Id + " " + ordTypeArr[OrdType]
		if v.OrdId == "XXX" {
			list[k].Title = "#" + v.Id + " 测试"
		}
		list[k].PrintContent = strings.ReplaceAll(v.PrintContent, "<BR>", "\n")
		list[k].PrintContent = strings.ReplaceAll(list[k].PrintContent, "<QR>", "<二维码标签左>")
		list[k].PrintContent = strings.ReplaceAll(list[k].PrintContent, "</QR>", "<二维码标签右>")
	}
	e.OutSuc(c, &list, nil)
	return
}
func PrinterIndexToSend(c *gin.Context) {
	var search md.IndexTestRequest
	if err := c.ShouldBindJSON(&search); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	user := GetUser(c)
	search.StoreId = utils.IntToStr(user.Info.Uid)
	// 加锁 防止并发
	mutexKey := fmt.Sprintf("%s:printer_send:p%ss%s", c.GetString("mid"), search.PrinterId, search.StoreId)
	withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX")
	if err != nil {
		e.OutErr(c, e.ERR, err)
		return
	}
	if withdrawAvailable != "OK" {
		e.OutErr(c, e.ERR, e.NewErr(400000, "操作过于频繁，请稍后再试"))
		return
	}
	eg := MasterDb(c)
	printerOne, _ := db.GetPrinterIndexById(eg, search.PrinterId, search.StoreId)
	if printerOne.Id == 0 {
		e.OutErr(c, 400, e.NewErr(400, "打印机不存在"))
		return
	}
	if printerOne.ModuleId == 0 {
		e.OutErr(c, 400, e.NewErr(400, "请选择打印模板"))
		return
	}
	ord := make(map[string]string, 0)
	ord["name"] = "XXX"
	ord["payment"] = "XXX"
	ord["phone"] = "XXX"
	ord["address"] = "XXX"
	ord["main_ord_id"] = "XXX"
	ord["num"] = "XXX"
	ord["table_num"] = "XXX"
	ord["store_name"] = "XXX"
	ord["store_qrcode_url"] = getStoreUrl(c, search.StoreId, "")
	ord["qrcode_url"] = getDownUrl(c, "")
	goodsInfo := make([]map[string]string, 0)
	one := map[string]string{
		"name":   "测试",
		"price":  "10",
		"num":    "1",
		"prices": "10",
	}
	goodsInfo = append(goodsInfo, one)
	var args = &md.PrinterRequest{
		StoreId:   search.StoreId,
		PrinterId: search.PrinterId,
		MasterId:  c.GetString("mid"),
		Ord:       ord,
		GoodsInfo: goodsInfo,
	}
	ReplaceOne(c, args)
	e.OutSuc(c, "success", nil)
	return
}

// 处理订单打印内容
func ReplacePrinterContent(c *gin.Context) {
	var maps map[string]string
	if err := c.ShouldBindJSON(&maps); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	mainOrdId := maps["main_ord_id"]
	// 加锁 防止并发
	mutexKey := fmt.Sprintf("%s:printer_content:%s", c.GetString("mid"), mainOrdId)
	withdrawAvailable, err := cache.Do("SET", mutexKey, 1, "EX", 5, "NX")
	if err != nil {
		e.OutErr(c, e.ERR, err)
		return
	}
	if withdrawAvailable != "OK" {
		e.OutErr(c, e.ERR, e.NewErr(400000, "操作过于频繁，请稍后再试"))
		return
	}
	engine := MasterDb(c)
	storeId, ord, goodsInfo, err := CommGetPrinterContent(c, mainOrdId)
	if err != nil {
		e.OutErr(c, 400, err)
		return
	}
	//打印操作
	go ReplaceDoing(c, engine, storeId, ord, goodsInfo)
	e.OutSuc(c, "success", nil)
	return
}
func CommGetPrinterContent(c *gin.Context, mainOrdId string) (int, map[string]string, []map[string]string, error) {
	var storeId int
	ord := make(map[string]string, 0)
	var goodsInfo = make([]map[string]string, 0)

	engine := MasterDb(c)
	mainOrd := db.GetOrderByOid(engine, mainOrdId)
	if mainOrd == nil {
		return storeId, ord, goodsInfo, e.NewErr(400, "未查询到订单！")
	}
	ordItem := db.GetOrderInfoAllEg(engine, mainOrdId)
	if ordItem == nil {
		return storeId, ord, goodsInfo, e.NewErr(400, "未查询到订单！")
	}
	//查出订单id
	storeId = mainOrd.StoreUid
	ord["name"] = mainOrd.BuyName
	ord["phone"] = mainOrd.BuyPhone
	ord["address"] = mainOrd.Address
	ord["main_ord_id"] = utils.Int64ToStr(mainOrd.Oid)
	ord["order_type"] = "2"

	if mainOrd.Code != "" {
		ord["num"] = mainOrd.Code
	}
	if mainOrd.TableNum != "" {
		ord["table_num"] = mainOrd.TableNum
	}
	var storeInfo model.CommunityTeamStore
	engine.Where("uid = ?", storeId).Get(&storeInfo)
	ord["store_name"] = storeInfo.Name
	userProfile, _ := db.UserProfileFindByID(engine, storeId)
	inviteCode := ""
	if userProfile != nil && userProfile.Uid > 0 {
		inviteCode = userProfile.InviteCode
	}
	ord["qrcode_url"] = getDownUrl(c, inviteCode)
	ord["store_qrcode_url"] = getStoreUrl(c, utils.IntToStr(storeId), inviteCode)
	//查出对应商品的信息
	var payment float64 = 0
	for _, v := range *ordItem {
		one := map[string]string{
			"name":   v.Title,
			"price":  utils.Float64ToStr(utils.FloatFormat(utils.StrToFloat64(v.Price)/float64(v.Num), 2)),
			"num":    utils.IntToStr(v.Num),
			"prices": v.Price,
		}
		payment += utils.StrToFloat64(v.Price)
		one["sku_text"] = ""
		skuText := make([]map[string]string, 0)
		json.Unmarshal([]byte(v.SkuInfo), &skuText)
		if len(skuText) > 0 {
			skuText1 := ""
			for _, v1 := range skuText {
				skuText1 += v1["name"] + ":" + v1["value"] + " "
			}
			one["sku_text"] = skuText1
		}
		goodsInfo = append(goodsInfo, one)
	}
	payment = utils.FloatFormat(payment, 2)
	ord["payment"] = utils.Float64ToStr(payment)
	return storeId, ord, goodsInfo, nil

}

// 替换打印
func ReplaceDoing(c *gin.Context, eg *xorm.Engine, storeId int, ord map[string]string, goodsInfo []map[string]string) {
	var args = &md.PrinterRequest{
		StoreId:   utils.IntToStr(storeId),
		PrinterId: "",
		MasterId:  c.GetString("mid"),
		Ord:       ord,
		GoodsInfo: goodsInfo,
	}
	ReplaceMore(c, args)
}
func getDownUrl(c *gin.Context, inviteCode string) string {
	downLoadRoute := "/#/zy-landing-page/pages/lading-page-download/lading-page-download?invited_code=" + inviteCode
	h5Domain := GetWebSiteDomainInfo(c, "wap")
	shareUrl := h5Domain + downLoadRoute
	//判断生成短链
	shareUrl = CommShareShorUrl(c, shareUrl)
	return shareUrl
}

func getStoreUrl(c *gin.Context, storeId, invitedCode string) string {
	downLoadRoute := "%s/#/zy-o2o-base/pages/store-page/store-page?id=%s&invited_code=%s"
	h5Domain := GetWebSiteDomainInfo(c, "wap")
	shareUrl := fmt.Sprintf(downLoadRoute, h5Domain, storeId, invitedCode)
	//判断生成短链
	shareUrl = CommShareShorUrl(c, shareUrl)
	return shareUrl
}
func CommShareShorUrl(c *gin.Context, shareUrl string) string {
	val := SysCfgFind(c, "share_link_type")
	if val["share_link_type"] == "1" { //百度短链
		shareUrl, _ = ShortenUrl(shareUrl)
	} else if val["share_link_type"] == "2" { //快站短链
		shareUrl = KuaiZhanShortURL(c, shareUrl)
	}
	return shareUrl
}

func PrinterIndexCheck(c *gin.Context) {
	var maps map[string]string
	if err := c.ShouldBindJSON(&maps); err != nil {
		e.OutErr(c, e.ERR_INVALID_ARGS, err)
		return
	}
	mainOrdId := maps["main_ord_id"]
	engine := MasterDb(c)
	storeId, ord, goodsInfo, err := CommGetPrinterContent(c, mainOrdId)
	if err != nil {
		e.OutErr(c, 400, err)
		return
	}
	printerOne, _ := db.GetPrinterIndexByBluetooth(engine, utils.IntToStr(storeId))
	var res = map[string]interface{}{
		"is_has_bluetooth": "0",
		"content":          "",
	}
	if printerOne != nil {
		res["is_has_bluetooth"] = "1"
	}
	var args = &md.PrinterRequest{
		StoreId:   utils.IntToStr(storeId),
		PrinterId: "",
		MasterId:  c.GetString("mid"),
		Ord:       ord,
		GoodsInfo: goodsInfo,
	}
	res["content"] = GetReplaceContent(c, args)
	e.OutSuc(c, res, nil)
	return
}
