package param

import (
	"errors"
	"strings"

	"tower_api/pkg/errcode"
	"tower_api/pkg/setting"
	"tower_api/pkg/util"
	"tower_api/service"
)

var (
	playerService = service.NewPlayerService()
)

// LoginParam 玩家请求登录的param
type LoginParam struct {
	AppId    string `form:"appid" uri:"appid"`
	OpenId   string `form:"openid" uri:"openid"`
	ServerId int    `form:"server_id" uri:"server_id"`
	Platform int16  `form:"platform" uri:"platform"` //0开发环境 1微信包
	Version  string `form:"ver" uri:"ver"`           //版本号
	Token    string `form:"token" uri:"token"`       //额外的token
}

// Validate 参数校验
func (l *LoginParam) Validate() (code, specialId int, err error) {
	l.AppId = strings.TrimSpace(l.AppId)
	l.OpenId = strings.TrimSpace(l.OpenId)
	l.Version = strings.TrimSpace(l.Version)
	//1 基本格式校验
	//1.1 基础格式校验
	if util.IsAppId(l.AppId) == false || util.IsOpenId(l.OpenId) == false || l.ServerId < 0 || l.Platform < 0 || l.Version == "" {
		return errcode.InvalidParams, 0, errors.New("参数错误")
	}
	//1.2 判断平台是否在配置表中
	platFormChecked, err := playerService.CheckPlatForm(l.Platform)
	if err != nil || platFormChecked == false {
		return errcode.InvalidPlatform, 0, errors.New(errcode.GetMsg(errcode.InvalidPlatform))
	}
	//1.3 appid一定要校验(主要区分用户所属发行方及哪个游戏包)
	// 渠道信息主要用来标识去调用哪个api
	secret, channelName, specialId := l.GetAppSecretByAppid()
	if secret == "" {
		return errcode.InvalidAppid, specialId, errors.New("appid信息错误")
	}
	if channelName == "" {
		return errcode.InvalidChannel, specialId, errors.New(errcode.GetMsg(errcode.InvalidChannel))
	}
	//1.4 查看当前渠道用户的状态是否被禁用
	checked := l.CheckUser()
	if checked == false {
		return errcode.LoginForbidden, specialId, errors.New("用户非正常状态,禁止登录")
	}
	//2 openid是否真实有效校验(测试环境下不进行校验)
	if setting.Settings.Server.RunMode != "debug" {
		isOpenId, err := l.ValidateOpenId(secret, channelName)
		if err != nil || isOpenId == false {
			return errcode.InvalidOpenid, specialId, err
		}
	}
	return 0, specialId, nil
}

// GetAppSecretByAppid 通过appid获取密钥
func (l *LoginParam) GetAppSecretByAppid() (string, string, int) {
	secret, chanName, specialId := playerService.GetAppSecretWithChannel(l.AppId)
	return secret, chanName, specialId
}

// ValidateOpenId 请求sdk接口校验openid是否正确
func (l *LoginParam) ValidateOpenId(secret, channelName string) (bool, error) {
	if strings.ToUpper(channelName) == "QUICK" {
		secret = strings.TrimSpace(l.Token)
	}
	return playerService.CheckOpenid(l.AppId, l.OpenId, secret, channelName)
}

// CheckUser 校验玩家的状态,是否禁止登录
func (l *LoginParam) CheckUser() bool {
	user := playerService.GetChannelUser(l.OpenId)
	if user.UserId > 0 && user.UserState != 1 {
		return false
	}
	return true
}
