package mallmanage

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/codinl/go-logger"
	"github.com/gin-gonic/gin"
	"github.com/rs/zerolog/log"
	"go-admin/app/admin/models"
	orm "go-admin/common/global"
	"go-admin/tools/app"
	"net/http"
)

// GoodsCreate 新增商品
// @Summary 新增商品
// @Tags 商城管理
// @Produce json
// @Accept json
// @Param request body models.Goods true "新增商品模型"
// @Success 200 {object} models.Goods
// @Router /api/v1/mall/goods/create [post]
func GoodsCreate(c *gin.Context) {
	goods := &models.Goods{}
	if c.ShouldBindJSON(goods) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	goods.SaleStatus = 2
	discount, err := json.Marshal(goods.GoodsDiscount)
	if err != nil {
		logger.Error("goods discount err:", err)
		app.Error(c, http.StatusInternalServerError, errors.New("goods create err"), "创建商品失败")
		return
	}
	goods.DiscountList = string(discount)
	err = goods.GoodsCreate()
	if err != nil {
		logger.Errorf("err:%#v", err)
		msg := "创建商品失败"
		app.Error(c, http.StatusInternalServerError, errors.New("goods create err"), msg)
		return
	}
	//cat, err := models.GetGoodsCat(goods.CatId)
	//if err != nil {
	//	log.Error().Msgf("cat err:%#v", err)
	//	app.Error(c, http.StatusInternalServerError, errors.New("goods cat err"), "创建商品失败")
	//	return
	//}
	//goods.GoodsCat = cat

	app.OK(c, goods, "创建商品成功")
}

func GoodsList(c *gin.Context) {
	req := &models.GoodsListReq{}
	if c.ShouldBindJSON(req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	goodsList, totalCount, err := req.GoodsList()
	if err != nil {
		logger.Errorf("err:%#v", err)
		msg := "获取商品列表失败"
		app.Error(c, http.StatusInternalServerError, errors.New("goods list  err"), msg)
		return
	}

	var ids []uint32
	for _, goods := range goodsList {
		ids = append(ids, goods.GoodsId)
	}

	if len(ids) > 0 {
		cm := models.GetGoodsFirstSkuCombo(ids)
		fmt.Println(cm)
		if cm != nil {
			for j, combo := range cm {
				for i, goods := range goodsList {
					if combo.GoodsId == goods.GoodsId {
						goodsList[i].Combo = &cm[j]
					}
				}
			}
		}
	}
	ret := map[string]interface{}{
		"count":      totalCount,
		"list":       goodsList,
		"page_index": req.PageIdx,
		"page_size":  req.PageSize,
		//"total_page": totalPage,
	}
	app.OK(c, ret, "")
}

func GoodsEdit(c *gin.Context) {
	goods := &models.Goods{}
	if c.ShouldBindJSON(goods) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}

	if goods.GoodsDiscount != nil {
		discount, err := json.Marshal(goods.GoodsDiscount)
		if err != nil {
			logger.Error("goods discount err:", err)
			app.Error(c, http.StatusInternalServerError, errors.New("goods create err"), "创建商品失败")
			return
		}
		goods.DiscountList = string(discount)
	}
	err := goods.Edit()
	if err != nil {
		logger.Errorf("err:%#v", err)
		msg := "商品编辑失败"
		app.Error(c, http.StatusInternalServerError, errors.New("goods edit err"), msg)
		return
	}
	app.OK(c, nil, "商品编辑成功")
}

func GoodsDetail(c *gin.Context) {
	goods := &models.Goods{}
	if c.ShouldBindJSON(goods) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	err := goods.GetDetail()
	if err != nil {
		logger.Errorf("err:%#v", err)
		msg := "获取商品详情失败"
		app.Error(c, http.StatusInternalServerError, errors.New("goods edit err"), msg)
		return
	}
	app.OK(c, goods, "")
}

func GoodsDelete(c *gin.Context) {
	req := &struct {
		Id uint32 `json:"id"`
	}{}
	if c.ShouldBindJSON(req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	err := orm.Eloquent.Table("goods").Where("id=?", req.Id).Delete(&models.Goods{}).Error
	//err := goods.GetDetail()
	if err != nil {
		logger.Errorf("err:%#v", err)
		msg := "删除商品详情失败"
		app.Error(c, http.StatusInternalServerError, errors.New("goods delete err"), msg)
		return
	}
	app.OK(c, nil, "操作成功")
	return
}

func GoodsAttributeAdd(c *gin.Context) {
	attribute := &models.GoodsAttribute{}
	if c.ShouldBindJSON(attribute) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	if attribute.SpecValueIndex == "" || attribute.GoodsId == 0 {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	indexSort, err := models.IndexSortString(attribute.SpecValueIndex)
	if err != nil {
		logger.Error("err:", err)
		app.Error(c, http.StatusInternalServerError, errors.New("sort spec value err"), "添加商品规格失败")
		return
	}
	attribute.SpecValueList = indexSort
	exist, err := models.QueryRecordExist(
		fmt.Sprintf("SELECT * FROM goods_attribute WHERE spec_value_index = '%s' ANd goods_id=%d",
			indexSort, attribute.GoodsId))
	if err != nil {
		log.Error().Msgf("exist attribute  err:%#v", err)
		app.Error(c, http.StatusInternalServerError, err, "添加商品规格失败")
		return
	}
	goods, err := models.GetGoods(attribute.GoodsId)
	if err != nil {
		logger.Error("get goods err")
		app.Error(c, http.StatusInternalServerError, errors.New("get goods err"), "添加商品不存在")
		return
	}

	if !exist {
		attribute.SerialNo = goods.SerialNo
		attribute.CatId = goods.CatId
		attribute.Name = goods.Name
		attribute.Title = goods.Title
		//attribute.MainImage = goods.MainImage // 规格图
		attribute.SetSpecValues()

		specIds := make([]int, 0)
		for i, _ := range attribute.SpecValues {
			specIds = append(specIds, int(attribute.SpecValues[i].SpecId))
		}
		if goods.SpecIndex != "" && goods.SpecIndex != models.IndexToString(specIds) {
			logger.Error("goods spec  err:")
			app.Error(c, http.StatusInternalServerError, errors.New("goods spec err"), "添加商品规格不一致")
			return
		}

		specValue, err := json.Marshal(attribute.SpecValues)
		if err != nil {
			logger.Error("marshal spec values err:", err)
			app.Error(c, http.StatusInternalServerError, errors.New("marshal spec values err"), "添加商品规格失败")
			return
		}
		begin := orm.Eloquent.Begin()
		attribute.SpecValueList = string(specValue)
		err = begin.Create(attribute).Error
		if err != nil {
			begin.Rollback()
			log.Error().Msgf("create attribute err:%#v", err)
			app.Error(c, http.StatusInternalServerError, errors.New("create attribute err"), "添加商品规格失败")
			return
		}
		rm := uint32(0)
		vm := uint32(0)
		for _, combo := range attribute.Combos {
			combo.GoodsAttributeId = attribute.ID
			combo.GoodsId = goods.GoodsId
			combo.SerialNo = goods.SerialNo
			combo.CatId = goods.CatId
			combo.Name = goods.Name
			combo.Title = goods.Title
			combo.MainImage = goods.MainImage
			rm = combo.PriceRm
			vm = combo.PriceVm
			fmt.Println("combo.PriceRm:", combo.PriceRm)
			err = begin.Create(&combo).Error
			if err != nil {
				begin.Rollback()
				log.Error().Msgf("create goods attribute combo:", err)
				app.Error(c, http.StatusInternalServerError, err, "添加商品规格失败")
				return
			}
		}

		if rm != 0 || vm != 0 {
			err = orm.Eloquent.Debug().Table("goods").Where("id=?", goods.ID).Updates(&map[string]interface{}{
				"price_vm": vm,
				"price_rm": rm,
			}).Error
			if err != nil {
				begin.Rollback()
				log.Error().Msgf(" goods update err:", err)
				app.Error(c, http.StatusInternalServerError, err, "添加商品规格失败")
				return
			}
		}
		err = begin.Commit().Error
		if err != nil {
			begin.Rollback()
			log.Error().Msgf("commit err:", err)
			app.Error(c, http.StatusInternalServerError, err, "添加商品规格失败")
			return
		}
	} else {
		log.Error().Msgf("goods spec exist ")
		app.Error(c, http.StatusInternalServerError, errors.New("goods spec exist"), "商品规格重复")
		return
	}
	miniRm := uint32(0)
	if len(attribute.Combos) > 0 {
		miniRm = attribute.Combos[0].PriceRm
	}
	for i, _ := range attribute.Combos {
		if attribute.Combos[i].PriceRm < miniRm {
			miniRm = attribute.Combos[i].PriceRm
		}
	}
	//fmt.Println("更新规格值")
	models.UpdateSpecList(attribute.GoodsId, miniRm)
	//fmt.Println("添加规格值成功----")
	app.OK(c, nil, "添加规格值成功")
	return
}

func GoodsAttributeUpdate(c *gin.Context) {
	attribute := &models.GoodsAttribute{}
	if c.ShouldBindJSON(attribute) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	//attrString, err := json.Marshal(attribute)
	//if err != nil {
	//	logger.Error("attrString err:", err)
	//}
	//fmt.Println("attrString:", string(attrString))
	if attribute.ID == 0 {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	indexSort, err := models.IndexSortString(attribute.SpecValueIndex)
	if err != nil {
		logger.Error("err:", err)
		app.Error(c, http.StatusInternalServerError, errors.New("sort spec value err"), "添加商品规格失败")
		return
	}
	attribute.SpecValueList = indexSort

	goods, err := models.GetGoods(attribute.GoodsId)
	if err != nil {
		logger.Error("get goods err")
		app.Error(c, http.StatusInternalServerError, errors.New("get goods err"), "添加商品不存在")
		return
	}

	attribute.SetSpecValues()

	specIds := make([]int, 0)
	for i, _ := range attribute.SpecValues {
		specIds = append(specIds, int(attribute.SpecValues[i].SpecId))
	}
	if goods.SpecIndex != "" && goods.SpecIndex != models.IndexToString(specIds) {
		logger.Error("goods spec  err:")
		app.Error(c, http.StatusInternalServerError, errors.New("goods spec err"), "添加商品规格不一致")
		return
	}

	specValue, err := json.Marshal(attribute.SpecValues)
	if err != nil {
		logger.Error("marshal spec values err:", err)
		app.Error(c, http.StatusInternalServerError, errors.New("marshal spec values err"), "添加商品规格失败")
		return
	}

	attribute.SpecValueList = string(specValue)
	//fmt.Println("规格 Combos", attribute.Combos)
	begin := orm.Eloquent.Begin()
	err = begin.Save(attribute).Error
	if err != nil {
		begin.Rollback()
		logger.Errorf("save err:%#v", err)
		msg := "商品规格编辑失败"
		app.Error(c, http.StatusInternalServerError, errors.New("goods edit err"), msg)
		return
	}
	//fmt.Println("Combos", attribute.Combos)
	if len(attribute.Combos) != 0 {
		//fmt.Println("更新Combos数据")
		for _, combo := range attribute.Combos {
			//fmt.Println("规格id combo :", combo.ID)
			err := begin.Table("goods_attribute_combo").Where("id=?", combo.ID).Updates(map[string]interface{}{
				"price_vm": combo.PriceVm,
				"price_rm": combo.PriceRm,
			}).Error
			if err != nil {
				begin.Rollback()
				logger.Errorf("update combo err:%#v", err)
				msg := "商品规格编辑失败"
				app.Error(c, http.StatusInternalServerError, errors.New("goods edit err"), msg)
				return
			}
		}
	}
	err = begin.Commit().Error
	if err != nil {
		begin.Rollback()
		logger.Error("commit err:", err)
		msg := "商品规格编辑失败"
		app.Error(c, http.StatusInternalServerError, errors.New("goods edit err"), msg)
		return
	}

	app.OK(c, nil, "商品规格编辑成功")
	//fmt.Println("添加规格值成功----")
	return
}

func GoodsAttributeMDel(c *gin.Context) {
	attributeIds := &struct {
		GoodsAttributeIds []uint32 `json:"goods_attribute_ids"`
	}{}
	if c.ShouldBindJSON(attributeIds) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	if len(attributeIds.GoodsAttributeIds) == 0 {
		app.OK(c, nil, "操作成功")
		return
	}
	attribute, err := models.GetGoodsAttribute(attributeIds.GoodsAttributeIds[0])
	if err != nil {
		log.Error().Msgf("attribute err:%#v", err)
		app.Error(c, http.StatusInternalServerError, err, "删除商品规格失败")
		return
	}

	for i, _ := range attributeIds.GoodsAttributeIds {
		begin := orm.Eloquent.Begin()
		err := begin.Table("goods_attribute").Where("id=?", attributeIds.GoodsAttributeIds[i]).
			Delete(&models.GoodsAttribute{}).Error
		if err != nil {
			begin.Rollback()
			log.Error().Msgf("goods attribute del err:%#v", err)
			app.Error(c, http.StatusInternalServerError, err, "删除商品规格失败")
			return
		}
		err = begin.Table("goods_attribute_combo").Where("goods_attribute_id=?", attributeIds.GoodsAttributeIds[i]).
			Delete(&models.GoodsAttributeCombo{}).Error
		if err != nil {
			begin.Rollback()
			log.Error().Msgf("goods attribute del err:%#v", err)
			app.Error(c, http.StatusInternalServerError, err, "删除商品规格失败")
			return
		}
		err = begin.Commit().Error
		if err != nil {
			begin.Rollback()
			log.Error().Msgf("commit err:%#v", err)
			app.Error(c, http.StatusInternalServerError, err, "删除商品规格失败")
			return
		}
	}

	models.UpdateSpecList(attribute.GoodsId, 1000000)
	fmt.Println("删除规格:----")
	app.OK(c, nil, "操作成功")
	return
}

func DeliverTaskList(c *gin.Context) {
	req := &models.DeliverTaskReq{}
	if c.ShouldBindJSON(req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	sysUser, err := models.GetSysUserByCtx(c)
	if err != nil {
		logger.Error("err:", err)
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	req.StoreId = sysUser.StoreId
	fmt.Println("StoreId:", req.StoreId)
	list, totalCount, err := req.List(c)
	if err != nil {
		logger.Errorf("err:%#v", err)
		msg := "获取发货列表失败"
		app.Error(c, http.StatusInternalServerError, errors.New("goods list  err"), msg)
		return
	}
	ret := map[string]interface{}{
		"total":      totalCount,
		"list":       list,
		"page_index": req.PageIdx,
		"page_size":  req.PageSize,
	}
	app.OK(c, ret, "")
}

func DeliverTaskDetail(c *gin.Context) {
	req := &struct {
		DeliverTaskId uint32 `json:"deliver_task_id" binding:"required"`
	}{}
	if c.ShouldBindJSON(req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	var task models.DeliverTask
	err := orm.Eloquent.Table("deliver_task").Where("id=?", req.DeliverTaskId).
		Find(&task).Error
	if err != nil {
		log.Error().Msgf("deliver task err:%#v", err)
		app.Error(c, http.StatusInternalServerError, err, "获取详情失败")
		return
	}

	var subs []*models.DeliverTaskSub
	err = orm.Eloquent.Table("deliver_task_sub").Where("deliver_task_id=?", req.DeliverTaskId).Find(&subs).Error
	if err != nil {
		log.Error().Msgf("deliver task err:%#v", err)
		app.Error(c, http.StatusInternalServerError, err, "获取详情失败")
		return
	}

	models.DeliverTaskSubListSetDetail(subs)

	task.Subs = subs
	//list, totalCount, err := req.List()
	//if err != nil {
	//	logger.Errorf("err:%#v", err)
	//	msg := "获取发货列表失败"
	//	app.Error(c, http.StatusInternalServerError, errors.New("goods list  err"), msg)
	//	return
	//}
	//ret := map[string]interface{}{
	//	"count":      totalCount,
	//	"list":       list,
	//	"page_index": req.PageIdx,
	//	"page_size":  req.PageSize,
	//}
	app.OK(c, task, "")
}
