package controllers

import (
	"fmt"
	"html/template"
	"merchant/datas"
	"merchant/models/merchant"
	"merchant/models/road"
	"merchant/service"
	"merchant/sys/enum"
	"merchant/utils/mfa"
	"merchant/utils/response"
	"regexp"
	"strings"
)

type UserInfo struct {
	KeepSession
}

func (c *UserInfo) ShowModifyUserInfoUI() {
	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)

	ranMd5 := encrypt.EncodeMd5([]byte(pubMethod.RandomString(46)))
	c.Ctx.SetCookie(enum.UserCookie, ranMd5, enum.CookieExpireTime)
	c.Ctx.SetSecureCookie(ranMd5, enum.UserCookie, ranMd5, enum.CookieExpireTime)
	c.SetSession(enum.UserCookie, ranMd5)

	c.Data["userName"] = u.MerchantName
	c.TplName = "modify_userInfo.html"
}

func (c *UserInfo) ShowTotpUI() {
	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)
	if u.MerchantUid == "" {
		c.Data["json"] = datas.BaseDataJSON{
			Code: -1,
			Msg:  "当前用户不存在",
		}
		_ = c.ServeJSON()
		return
	}
	otp, err := mfa.GetOtp(u.LoginAccount, fmt.Sprintf("商户 %s", u.MerchantName))
	if err != nil {
		c.Data["json"] = datas.BaseDataJSON{
			Code: -1,
			Msg:  "当前用户不存在",
		}
		_ = c.ServeJSON()
		return
	}
	c.Data["showTotp"] = u.OtpSecret == ""
	c.Data["totpImage"] = template.URL(otp.QrImage)
	c.Data["totpSecret"] = otp.Secret
	c.TplName = "totp.html"
}

// ModifyUserInfo 修改用户信息
func (c *UserInfo) ModifyUserInfo() {
	or_pwd := strings.TrimSpace(c.GetString("or_pwd"))
	new_pwd := strings.TrimSpace(c.GetString("new_pwd"))
	confirm_pwd := strings.TrimSpace(c.GetString("confirm_pwd"))

	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)

	var (
		msg  = enum.FailedString
		flag = enum.FailedFlag

		md     bool
		ud     bool
		pwdMd5 string
	)

	if or_pwd == "" ||
		new_pwd == "" ||
		confirm_pwd == "" {
		msg = "密码不能为空!"
		goto stopRun
	}

	pwdMd5 = encrypt.EncodeMd5([]byte(or_pwd))
	if strings.Compare(strings.ToUpper(pwdMd5), u.LoginPassword) != 0 {
		msg = "原始密码错误!"
	}

	md, _ = regexp.MatchString(enum.PasswordReg, new_pwd)
	if !md {
		msg = "密码只能输入6-20个以字母开头、可带数字、“_”、“.”的字串!"
		goto stopRun
	}

	md, _ = regexp.MatchString(enum.PasswordReg, confirm_pwd)
	if !md {
		msg = "密码只能输入6-20个以字母开头、可带数字、“_”、“.”的字串!"
		goto stopRun
	}

	if strings.Compare(new_pwd, confirm_pwd) != 0 {
		msg = "两次密码不匹配!"
		goto stopRun
	}

	u.LoginPassword = strings.ToUpper(encrypt.EncodeMd5([]byte(new_pwd)))
	ud = merchant.UpdateMerchant(u)
	if ud {
		msg = enum.SuccessString
		flag = enum.SuccessFlag

		// 退出重新登录
		c.DelSession(enum.UserSession)
	}

stopRun:
	c.Data["json"] = pubMethod.JsonFormat(flag, "", msg, "")
	c.ServeJSON()
	c.StopRun()
}

// ConfirmOriginPwd 验证原始密码
func (c *UserInfo) ConfirmOriginPwd() {
	ori := strings.TrimSpace(c.GetString("c"))
	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)
	var (
		msg  = enum.FailedString
		flag = enum.FailedFlag
	)
	pwdMd5 := encrypt.EncodeMd5([]byte(ori))
	if strings.Compare(strings.ToUpper(pwdMd5), u.LoginPassword) != 0 {
		msg = "原始密码错误!"
	} else {
		flag = enum.SuccessFlag
	}
	c.Data["json"] = pubMethod.JsonFormat(flag, "", msg, "")
	c.ServeJSON()
	c.StopRun()
}

// ShowUserInfoUI 展示用户信息
func (c *UserInfo) ShowUserInfoUI() {
	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)
	c.Data["userName"] = u.MerchantName
	c.Data["mobile"] = u.LoginAccount
	c.Data["email"] = u.LoginAccount
	c.Data["riskDay"] = "1"
	//c.Data["key"] = uPayConfig.PayKey
	//c.Data["secret"] = uPayConfig.PaySecret
	c.TplName = "show_userInfo.html"
}

func (c *UserInfo) SaveTotp() {
	code := c.GetString("totpCode")
	secret := c.GetString("totpSecret")
	if code == "" || secret == "" {
		c.Data["json"] = datas.BaseDataJSON{
			Code: -1,
			Msg:  "未填写验证码",
		}
		_ = c.ServeJSON()
		return
	}
	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)
	ok := mfa.ValidCode(code, secret)
	if !ok {
		c.Data["json"] = datas.KeyDataJSON{
			Code: -1,
			Msg:  "验证码验证错误",
		}
		_ = c.ServeJSON()
		return
	}
	err2 := merchant.UpdateOtpByUserID(u.MerchantUid, secret)
	if err2 != nil {
		c.Data["json"] = datas.BaseDataJSON{
			Code: -1,
			Msg:  "更新二步验证失败",
		}
		_ = c.ServeJSON()
		return
	}
	c.Data["json"] = datas.KeyDataJSON{
		Code: 0,
		Msg:  "success",
	}
	u.OtpSecret = secret
	_ = c.SetSession(enum.UserSession, u)
	_ = c.ServeJSON()
}

func (c *UserInfo) ResetTotp() {
	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)
	code := c.GetString("totpCode")
	ok := mfa.ValidCode(code, u.OtpSecret)
	if !ok {
		c.Data["json"] = datas.KeyDataJSON{
			Code: -1,
			Msg:  "验证码错误",
		}
		_ = c.ServeJSON()
		return
	}
	err := merchant.UpdateOtpByUserID(u.MerchantUid, "")
	if err != nil {
		c.Data["json"] = datas.BaseDataJSON{
			Code: -1,
			Msg:  "更新二步验证失败",
		}
		_ = c.ServeJSON()
		return
	}
	c.Data["json"] = datas.KeyDataJSON{
		Code: 0,
		Msg:  "success",
	}
	u.OtpSecret = ""
	_ = c.SetSession(enum.UserSession, u)
	_ = c.ServeJSON()
}

func (c *UserInfo) QueryAllowedRoad() {
	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)
	if u.Id == 0 {
		c.Data["json"] = response.CommonRes{
			Msg:  "获取用户失败",
			Code: -1,
		}
		_ = c.ServeJSON()
		return
	}
	result := service.QueryAllowedRoad(u.MerchantUid)
	c.Data["json"] = response.CommonResWithData{
		CommonRes: response.CommonRes{
			Msg:  "成功",
			Code: 0,
		},
		Data: result,
	}
	_ = c.ServeJSON()
}

// QueryAllowedMM 获取允许的面值
func (c *UserInfo) QueryAllowedMM() {
	roadCode := c.GetString("roadCode")
	if roadCode == "" {
		c.Data["json"] = response.CommonRes{
			Msg:  "请填写通道编码",
			Code: -1,
		}
		_ = c.ServeJSON()
		return
	}
	roadPool := road.GetRoadByProductCode(roadCode)
	if roadPool.Id == 0 {
		c.Data["json"] = response.CommonRes{
			Msg:  "当前通道不存在",
			Code: -1,
		}
		_ = c.ServeJSON()
		return
	}
	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)
	if u.Id == 0 {
		c.Data["json"] = response.CommonRes{
			Msg:  "获取用户失败",
			Code: -1,
		}
		_ = c.ServeJSON()
		return
	}
	result := service.QueryAllowedDeployInfoMM(u.MerchantUid, roadPool.RoadUid)
	returnList := make([]struct {
		ShowLabel float64 `json:"showLabel"`
	}, 0)
	for _, margin := range result {
		isInList := false
		for _, s := range returnList {
			if s.ShowLabel == margin.ShowLabel {
				//	存在
				isInList = true
			}
		}
		if !isInList {
			returnList = append(returnList, struct {
				ShowLabel float64 `json:"showLabel"`
			}{
				ShowLabel: margin.ShowLabel,
			})
		}
	}
	c.Data["json"] = response.CommonResWithData{
		CommonRes: response.CommonRes{
			Msg:  "成功",
			Code: 0,
		},
		Data: returnList,
	}
	_ = c.ServeJSON()
}
