package api

import (
	"encoding/json"
	"fmt"
	"gadmin/internal/admin/consts"
	"gadmin/internal/admin/forms"
	"gadmin/internal/admin/service"
	"gadmin/internal/gorm/model"
	"gadmin/utility/serializer"
	"github.com/gin-gonic/gin"
	"github.com/go-resty/resty/v2"
	"os"
)

func UserAccountList(c *gin.Context) {
	var req forms.UserAccountListReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	if err := forms.ParseParams(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	c.JSON(200, service.UserAccount.List(c, req))
}

func UserAccountSearch(c *gin.Context) {
	var req forms.UserAccountSearchReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	if err := forms.ParseParams(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	c.JSON(200, service.UserAccount.Search(c, req))
}

func UserAccountGet(c *gin.Context) {
	var req forms.UserAccountGetReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	if err := forms.ParseParams(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	c.JSON(200, service.UserAccount.Get(c, req))
}

func UserBan(c *gin.Context) {
	var req forms.UserAccountBanReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}
	c.JSON(200, service.UserAccount.BanUser(c, req))
}

/*func SingleBanUser(c *gin.Context) {
	var req forms.UserAccountBanReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}
	c.JSON(200, service.UserAccount.SingleBanUser(c, req))
}

func UpdatePlayerPaySwitch(c *gin.Context) {
	var req forms.GmSetPaySwitch
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}
	c.JSON(200, service.UserAccount.UpdatePaySwitch(c, req))
}*/

func BanUserChat(c *gin.Context) {
	var req forms.BanChatReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}
	c.JSON(200, service.UserAccount.BanUserChat(c, req))
}

/*func UpdateNickname(c *gin.Context) {
	var req forms.UpdateNicknameReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}
	c.JSON(200, service.UserAccount.UpdateNickname(c, req))
}*/

var ServiceMap = map[int64]struct {
	ServiceName string
	ApiKey      string
}{
	1: {
		ServiceName: "微信",
		ApiKey:      "WX_RELEASE_GM_API",
	},
	2: {
		ServiceName: "抖音",
		ApiKey:      "DY_RELEASE_GM_API",
	},
	3: {
		ServiceName: "美团",
		ApiKey:      "MT_RELEASE_GM_API",
	},
	4: {
		ServiceName: "闲闲",
		ApiKey:      "XX_RELEASE_GM_API",
	},
}

func CompatibilityTestVerify(c *gin.Context) {
	var req forms.CompatibilityTestVerifyReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	if os.Getenv("GIN_MODE") == "release" {
		c.JSON(200, gin.H{"code": 1, "msg": "正式服不允许操作！"})
		return
	}

	if _, ok := ServiceMap[req.Service]; !ok {
		c.JSON(200, gin.H{"code": 1, "msg": "请选择正确的服务器！"})
		return
	}

	var (
		client = resty.New().SetDebug(true)
		url    = fmt.Sprintf("%s/api/migrate/userInfo", os.Getenv(ServiceMap[req.Service].ApiKey))
		data   = `{"player_id":%v}`
	)
	fmt.Printf("url:%v; data:%v; token:%v; params:%+v", url, data, os.Getenv("RELEASE_GM_API_TOKEN"), req)
	post, err := client.R().
		SetHeader("Content-Type", "application/json").
		SetHeader("token", os.Getenv("RELEASE_GM_API_TOKEN")).
		SetBody(fmt.Sprintf(data, req.ProduceUserId)).Post(url)
	if err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	type RspData struct {
		*model.UserAccount
		Has bool `json:"has"`
	}

	type Rsp struct {
		Code  int     `json:"code"`
		Data  RspData `json:"data"`
		Msg   string  `json:"msg"`
		Error string  `json:"error"`
	}

	var rsp *Rsp

	if err = json.Unmarshal(post.Body(), &rsp); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	if rsp == nil {
		c.JSON(200, serializer.Err(consts.CodeParamErr, "未解析到玩家信息！", err))
		return
	}

	if rsp.Code != 0 {
		c.JSON(200, serializer.Err(consts.CodeParamErr, fmt.Sprintf("查询出错:%+v", rsp.Error), nil))
		return
	}

	rsp.Data.Has = true
	c.JSON(200, serializer.Suc(rsp.Data))
}

/*func CompatibilityTestMigrate(c *gin.Context) {
	var req forms.CompatibilityTestMigrateReq
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	if os.Getenv("GIN_MODE") == "release" {
		c.JSON(200, gin.H{"code": 1, "msg": "正式服不允许操作！"})
		return
	}

	if _, ok := ServiceMap[req.Service]; !ok {
		c.JSON(200, gin.H{"code": 1, "msg": "请选择正确的服务器！"})
		return
	}

	var (
		client = resty.New().SetDebug(true)
		url    = fmt.Sprintf("%s/api/migrate/complete", os.Getenv(ServiceMap[req.Service].ApiKey))
		data   = `{"player_id":%v}`
	)

	post, err := client.R().
		SetHeader("Content-Type", "application/json").
		SetHeader("token", os.Getenv("RELEASE_GM_API_TOKEN")).
		SetBody(fmt.Sprintf(data, req.ProduceUserId)).Post(url)
	if err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	logrus.Warnf("CompatibilityTestMigrate post:%+v", post)

	type Rsp struct {
		Code  int                        `json:"code"`
		Data  *forms.MigrateCompleteData `json:"data"`
		Msg   string                     `json:"msg"`
		Error string                     `json:"error"`
	}

	var rsp *Rsp
	if err = json.Unmarshal(post.Body(), &rsp); err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	if rsp == nil {
		c.JSON(200, serializer.Err(consts.CodeParamErr, "迁移未解析到玩家信息！", err))
		return
	}

	if rsp.Code != 0 {
		c.JSON(200, serializer.Err(consts.CodeParamErr, fmt.Sprintf("迁移出错:%+v", rsp.Error), nil))
		return
	}

	if rsp.Data == nil {
		c.JSON(200, serializer.Err(consts.CodeParamErr, "迁移未解析到玩家信息-2！", nil))
		return
	}

	if rsp.Data.PlayerMaterial == nil {
		c.JSON(200, serializer.Err(consts.CodeParamErr, "迁移未解析到玩家信息-3！", nil))
		return
	}

	DB, err := player.GetDBByUserId(req.UserId)
	if err != nil {
		c.JSON(200, serializer.Err(consts.CodeParamErr, "GetDBByUserId err", err))
		return
	}

	q := query.Use(config.GDBGroup[DB])
	err = q.Transaction(func(tx *query.Query) error {
		// 材料表
		if _, err = tx.PlayerMaterial.WithContext(c).Where(tx.PlayerMaterial.Playerid.Eq(req.UserId)).Delete(); err != nil {
			return err
		}
		pm := rsp.Data.PlayerMaterial
		pm.ID = 0
		pm.Playerid = req.UserId
		if err = tx.PlayerMaterial.WithContext(c).Create(FilterEmptyPlayerMaterial(pm)); err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		c.JSON(200, ErrorResponse(err))
		return
	}

	c.JSON(200, serializer.Suc(nil))
}

// FilterEmptyPlayerMaterial 对一些空值可能存在转换异常的做下初始化处理
func FilterEmptyPlayerMaterial(value *model.PlayerMaterial) *model.PlayerMaterial {
	if value == nil {
		return nil
	}

	if value.BroadTrigger == "" {
		bt := new(model2.BroadTrigger)
		bt.SynthEquip = make(map[string]struct{})
		b, _ := json.Marshal(bt)
		value.BroadTrigger = string(b)
	}

	if value.Treasures == "" {
		b, _ := json.Marshal(make([]*model2.DropedTreasure, 0))
		value.Treasures = string(b)
	}

	if value.RoleCollocate == "" {
		b, _ := json.Marshal(make([]int, 0))
		value.RoleCollocate = string(b)
	}

	if value.BuffMaterials == "" {
		b, _ := json.Marshal(make([]int, 0))
		value.BuffMaterials = string(b)
	}
	return value
}*/
