package goodsmanage

import (
	"errors"
	"github.com/gin-gonic/gin"
	"go-admin/app/admin/models"
	orm "go-admin/common/global"
	"go-admin/logger"
	aliyun "go-admin/tools/ali"
	"go-admin/tools/app"
	"net/http"
	"strings"
)

func GameCardList(c *gin.Context) {
	req := struct {
		Page     int    `json:"pageIndex"`
		PageSize int    `json:"pageSize"`
		GameType int    `json:"gameTypeId"`
		Status   int    `json:"status"`
		NameKey  string `json:"nameKey"`
	}{
		Page:     1,
		PageSize: 20,
	}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}

	cardList, _, count, err := models.GetGameCardList(req.GameType, req.Status, req.Page, req.PageSize, req.NameKey)

	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "查询失败")
		return
	}

	ret := map[string]interface{}{
		"count":      count,
		"list":       cardList,
		"pageIndex":  req.Page,
		"total_page": req.PageSize,
	}
	app.OK(c, ret, "")
}

// GameCardGoodsList 查询库存游戏卡串码
// @Summary 查询库存游戏卡串码
// @Tags 租卡系统-库存管理
// @Produce json
// @Accept json
// @Param request body models.GetGameCardGoodsListReq true "查询库存游戏卡串码"
// @Success 200 {object} models.GetGameCardGoodsListResp
// @Router /api/v1/goods/goods_list [post]
func GameCardGoodsList(c *gin.Context) {
	req := models.GetGameCardGoodsListReq{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}

	resp, err := req.GetGameCardGoodsList(c)
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "查询失败")
		return
	}

	app.OK(c, resp, "")
}

func GameCardAdd(c *gin.Context) {
	req := struct {
		Name            string   `json:"name" gorm:"column:name;index"`              // 名称
		Price           uint32   `json:"price" gorm:"column:price;index"`            // 价格
		CoverImg        string   `json:"coverImg" gorm:"column:cover_img"`           // 封面
		OrderCount      uint32   `json:"orderCount" gorm:"column:order_count;index"` // 订单数
		NewProducts     uint8    `json:"newProducts"`                                // 新品: 1-新品 2-非新品
		Status          uint8    `json:"status"`                                     // 状态: 1-上架 2-下架
		GameTypeId      []int    `json:"gameTypeId"`                                 // 游戏类型id
		GoodsGalleryUrl string   `json:"goodsGalleryUrl"`                            // 轮播图
		ViewCount       uint32   `json:"viewCount"`                                  // 查看人数
		Playability     uint32   `json:"playability"`                                // 耐玩度
		Playfulness     uint32   `json:"playfulness"`                                // 好玩度
		GameTime        uint32   `json:"gameTime"`                                   // 游戏时间
		Likes           uint32   `json:"likes"`                                      // 点赞
		DetailInfo      string   `json:"detailInfo"`                                 // 详情描述
		DetailImg       string   `json:"detailImg"`                                  // 详情图片
		Labels          []string `json:"labels"`                                     // 游戏标签
		RealPrice       uint32   `json:"real_price"`                                 // 真实价格
		VideoLink       string   `json:"video_link"`                                 // 链接
		HomeCategoryId  []uint32 `json:"home_category_id"`                           // 首页分类ID
	}{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}

	card := &models.GameCard{
		Name:            req.Name,
		Price:           req.Price,
		CoverImg:        req.CoverImg,
		NewProducts:     req.NewProducts,
		Status:          req.Status,
		GoodsGalleryUrl: req.GoodsGalleryUrl,
		Playability:     req.Playability,
		Playfulness:     req.Playfulness,
		GameTime:        req.GameTime,
		DetailInfo:      req.DetailInfo,
		DetailImg:       req.DetailImg,
		RealPrice:       req.RealPrice,
		VideoLink:       req.VideoLink,
	}
	err := card.Add()
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误")
		return
	}
	err = models.GameCardAddType(req.GameTypeId, int(card.ID))
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误")
		return
	}

	for i, label := range req.Labels {
		label = strings.Replace(label, " ", "", -1)
		label = strings.Replace(label, "\n", "", -1)
		req.Labels[i] = label
	}
	labelMap := make(map[string]uint32)
	for i, _ := range req.Labels {
		labelMap[req.Labels[i]] = uint32(i)
	}
	for k, _ := range labelMap {
		if k == "" {
			continue
		}
		err := orm.Eloquent.Create(&models.GameCardLabel{
			GameCardId: card.ID,
			GameLabel:  k,
		}).Error
		if err != nil {
			logger.Error("create game card label err")
		}
	}

	// 添加到首页分类
	if len(req.HomeCategoryId) != 0 {
		for _, categoryId := range req.HomeCategoryId {
			// 删除已有的 home_category_id 和 game_id 记录
			err = orm.Eloquent.Table("home_category_game").
				Where("home_category_id = ? AND game_id = ?", categoryId, card.ID).
				Delete(&models.HomeCategoryGame{}).Error
			if err != nil {
				logger.Errorf("Failed to delete existing home_category_game record, home_category_id: %d, game_id: %d, err: %v", categoryId, card.ID, err)
				return
			}

			// 查询新的 HomeCategoryId 的最大排序值
			type MaxSortOrderResult struct {
				MaxSortOrder int `json:"max_sort_order"` // 数据库字段类型应与此字段匹配
			}

			var result MaxSortOrderResult
			err = orm.Eloquent.Table("home_category_game").
				Where("home_category_id = ?", categoryId).
				Select("COALESCE(MAX(sort_order), 0) AS max_sort_order").
				Scan(&result).Error
			if err != nil {
				logger.Errorf("Failed to fetch max sort_order for home_category_id: %d, err: %v", categoryId, err)
				return
			}

			// 插入新记录
			newHomeCategoryGame := models.HomeCategoryGame{
				HomeCategoryID: categoryId,
				GameID:         card.ID,
				GameName:       card.Name,
				SortOrder:      result.MaxSortOrder + 1,
			}
			err = orm.Eloquent.Table("home_category_game").
				Create(&newHomeCategoryGame).Error
			if err != nil {
				logger.Errorf("Failed to create new home_category_game record, home_category_id: %d, game_id: %d, err: %v", card.HomeCategoryId, card.ID, err)
			}
		}
	}

	app.OK(c, nil, "添加成功")
}

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

	err := card.Modify()
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误")
		return
	}
	app.OK(c, nil, "修改成功")
}

func GameCardModifyType(c *gin.Context) {
	req := struct {
		GameCardId int   `json:"gameCardId"`
		GameTypeId []int `json:"gameTypeId"`
	}{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}

	err := models.GameType{GameCardId: uint64(req.GameCardId)}.GameCardTypeModify(req.GameTypeId)
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误")
		return
	}
	app.OK(c, nil, "修改成功")
}

func GameCardMDel(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
	}
	data := models.GameCard{}
	err := data.MDel(req.Id)
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误")
		return
	}
	app.OK(c, nil, "删除成功")
}

func GameCardTypeList(c *gin.Context) {
	typeList, err := models.GetGameCardTypeList()
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误")
		return
	}

	app.OK(c, typeList, "")
}

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

	err := cardType.Modify()
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误")
		return
	}

	app.OK(c, "", "修改成功")
}

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

	err := cardType.Add()
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误")
		return
	}
	app.OK(c, nil, "添加成功")
}

func GameCardTypeDel(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
	}
	data := &models.GameCardType{}
	err := data.MDel(req.Id)
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusBadRequest, err, "参数错误")
		return
	}
	app.OK(c, nil, "删除成功")
}

func GameTypeAdd(c *gin.Context) {
	req := struct {
		GameCardId int   `json:"gameCardId"`
		Id         []int `json:"id"`
	}{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	err := models.GameCardAddType(req.Id, req.GameCardId)
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "")
		return
	}
	app.OK(c, nil, "添加成功")
	return
}

func GameCardTypes(c *gin.Context) {
	req := struct {
		GameCardId int `json:"gameCardId"`
	}{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	card := models.GameCard{}
	card.ID = uint32(req.GameCardId)
	cardTypes, err := card.GetGameType()
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "")
		return
	}

	app.OK(c, cardTypes, "")
	return
}

func AliyunStsTokenGet(c *gin.Context) {
	uploadInfo, err := aliyun.GenStsToken("21000505")
	if err != nil {
		logger.Error("err", logger.Field("err", err))
		return
	}

	stsToken := models.RspAliyunStsToken{
		AccessKeyId:     uploadInfo.AccessKeyId,
		AccessKeySecret: uploadInfo.AccessKeySecret,
		SecurityToken:   uploadInfo.SecurityToken,
		BucketName:      uploadInfo.BucketName,
		Expiration:      uint64(uploadInfo.Expiration),
	}

	ret := map[string]interface{}{
		"stsToken": stsToken,
		"ossUrl":   aliyun.AliyunOssUrl,
	}
	app.OK(c, ret, "")
	return
}

func BatchStandUpDown(c *gin.Context) {
	req := struct {
		StandType uint32 `json:"stand_type"` // 批量:1-上架 2-下架
	}{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	err := models.GameCardBatchStand(req.StandType)
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "")
		return
	}
	app.OK(c, nil, "成功")
	return
}

func BatchStandUp(c *gin.Context) {
	req := struct {
		GameCardId []uint32 `json:"game_card_id"` // 批量上架
	}{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	err := models.GameCardBatchStandUp(req.GameCardId)
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "")
		return
	}
	app.OK(c, nil, "成功")
	return
}

func OrderAndStockAnalysis(c *gin.Context) {
	req := struct {
		StoreId uint32 `json:"store_id"`
	}{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}

	poolData, err := models.CardPoolData(req.StoreId)
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "")
		return
	}
	orderRank, err := models.GameCardOrderRank(req.StoreId)
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "")
		return
	}
	ret := make(map[string]interface{}, 0)
	ret["pool_data"] = poolData
	ret["order_rank"] = orderRank
	app.OK(c, ret, "成功")
	return
}

func GameCardStockAnalysis(c *gin.Context) {
	req := struct {
		SortType      uint32 `json:"sort_type"`      // 1-总库存 2-库存 3-用户持有 4-订单数量
		SortDirection uint32 `json:"sort_direction"` // 1-升序 2-降序
		StoreId       uint32 `json:"store_id"`
		PageNum       uint32 `json:"pageIndex"`
		PageSize      uint32 `json:"page_size"`
		Name          string `json:"name"`
	}{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}

	resp, err := models.GameCardStockList(req.Name, req.SortType, req.SortDirection, req.StoreId, req.PageNum, req.PageSize, c)
	if err != nil {
		logger.Error("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "")
		return
	}
	//ret := make(map[string]interface{}, 0)
	//ret["list"] = stockList
	//ret["count"] = total
	//ret["page_index"] = req.PageNum
	app.OK(c, resp, "")
	return
}

func GameCardLabelAdd(c *gin.Context) {
	req := struct {
		GameCardId uint32   `json:"game_card_id"`
		Labels     []string `json:"labels"`
	}{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	for i, label := range req.Labels {
		label = strings.Replace(label, " ", "", -1)
		label = strings.Replace(label, "\n", "", -1)
		req.Labels[i] = label
	}
	var gameLabels []models.GameCardLabel
	err := orm.Eloquent.Table("game_card_label").Where("game_card_id=?", req.GameCardId).
		//Where("game_label in (?)", req.Labels).Find(&gameLabels).Error
		Find(&gameLabels).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "查询失败")
		return
	}
	isRepeat := false
	labelMap := make(map[string]uint32)
	if len(gameLabels) > 0 {
		isRepeat = true
		for i, _ := range gameLabels {
			labelMap[gameLabels[i].GameLabel] = gameLabels[i].GameCardId
		}
	}

	for i, _ := range req.Labels {
		if isRepeat {
			_, ok := labelMap[req.Labels[i]]
			if ok {
				continue
			}
		}
		if req.Labels[i] == "" {
			continue
		}

		err := orm.Eloquent.Create(&models.GameCardLabel{
			GameCardId: req.GameCardId,
			GameLabel:  req.Labels[i],
		}).Error
		if err != nil {
			logger.Error("create game card label err")
		}
	}
	for i, _ := range req.Labels {
		delete(labelMap, req.Labels[i])
	}
	labs := make([]string, 0)
	for k, _ := range labelMap {
		labs = append(labs, k)
	}
	err = orm.Eloquent.Table("game_card_label").Where("game_card_id=?", req.GameCardId).
		Where("game_label in (?)", labs).Delete(&models.GameCardLabel{}).Error
	if err != nil {
		logger.Error("delete game card label err:", logger.Field("err", err))
	}

	app.OK(c, nil, "操作成功")
}

func GameCardLabelList(c *gin.Context) {
	req := struct {
		GameCardId uint32 `json:"game_card_id"`
	}{}
	if c.ShouldBindJSON(&req) != nil {
		logger.Errorf("para err")
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	var gameLabels []models.GameCardLabel
	err := orm.Eloquent.Table("game_card_label").Where("game_card_id=?", req.GameCardId).
		Find(&gameLabels).Error
	if err != nil {
		logger.Errorf("err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, "查询失败")
		return
	}

	app.OK(c, gameLabels, "")
}
