package actions

import (
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/iapologizewhenimwrong/Vestmore_GO/model"
	"github.com/iapologizewhenimwrong/Vestmore_GO/utils/auth"
	"github.com/iapologizewhenimwrong/Vestmore_GO/utils/basic"
	"github.com/iapologizewhenimwrong/Vestmore_GO/utils/email"
	"github.com/iapologizewhenimwrong/Vestmore_GO/utils/encryption_decryption"
	"github.com/iapologizewhenimwrong/Vestmore_GO/utils/log"
)

var CompanyKey = "vestmore-bjwl"

// @Action base/getToken
// Base_GetToken
// action: string;
// app_market: string;
// lang: string;
// token: string;
func BaseGetToken(ctx *gin.Context, param *BaseGetTokenParam) (resp *basic.Response) {
	ctx.ShouldBind(param)
	// model.Models.KillaraCustomerModel.Find()
	log.Println()

	return resp.Success()
}

// @Action account/loginWithTelephonePassword
// AccountLoginWithTelephonePassword
// randstr: string;
// sign: string;
// telephone: string;
// version: string;.0.14
// token: string;
// country_code: string; 86
// password: string;
// action: string;
// device: string;,12
// app_market: uint64;
// email: string;
// timestamp: int64;
func AccountLoginWithTelephonePassword(ctx *gin.Context, param *AccountLoginWithTelephonePasswordParam) (resp *basic.Response) {
	// ctx.ShouldBind()
	// model.Models.KillaraCustomerModel.Find()

	if param.CountryCode == "" {
		resp.ErrorMsg(1, "country_code 参数缺失")
		return

	}
	if param.Telephone == "" {
		resp.ErrorMsg(1, "telephone 参数缺失")
		return
	}

	if param.Password == "" {
		resp.ErrorMsg(1, "password 参数缺失")
		return
	}

	telephone := strings.TrimSpace(param.Telephone)
	password := strings.TrimSpace(param.Password)
	countryCode := strings.TrimSpace(param.CountryCode)

	// 假设 modelCustomer 和 modelCustomerToken 是对应的服务接口

	var customer *model.KillaraCustomer
	var err error

	customer, err = model.Models.KillaraCustomerModel.GetCustomerByTelephoneForBackEnd(telephone)
	if err != nil {
		resp.ErrorMsg(1, err.Error())
		return
	}
	if customer == nil {
		customer, err = model.Models.KillaraCustomerModel.GetCustomerByCode(telephone)
		if err != nil {
			resp.ErrorMsg(1, err.Error())
			return
		}
	}

	if customer == nil {
		return resp.ErrorMsg(1, "账号未注册")
	}

	if *customer.CountryCode != countryCode {
		return resp.ErrorMsg(1, "电话号码国家不正确")
	}

	if *customer.Status != 1 {
		return resp.ErrorMsg(1, "账号已禁用,无法登录")
	}

	if !auth.CheckPassword(*customer.Password, *customer.Salt, *customer.RandomPassword, password) {
		return resp.ErrorMsg(1, "账号或密码错误")
	}

	customerID := *customer.CustomerId

	err = model.Models.KillaraCustomerTokenModel.UpdateTokenCustomerID(param.Token, customerID)
	if err != nil {
		return resp.ErrorMsg(1, err.Error())
	}

	var deviceCode string
	if param.Device != "" {
		deviceCode = param.Device
	}

	var version string
	if param.Version != "" {
		version = param.Version
	}

	var ip string
	addr := strings.Split(ctx.Request.RemoteAddr, ":")
	if len(addr) > 0 {
		ip = addr[0]
	}

	log.Println(deviceCode, version, ip)

	data := &model.KillaraCustomerDevice{
		CustomerId: &customerID,
		Device:     &deviceCode,
		Version:    &version,
		Ip:         &ip,
		AppMarket:  &param.AppMarket,
		Date:       basic.TimePtr(time.Now()),
	}

	// 假设 insertCustomerDevice 是对应的服务接口
	// insertCustomerDevice(data)
	err = model.Models.KillaraCustomerModel.InsertCustomerDevice(data)
	if err != nil {
		return resp.ErrorErr(1, err)
	}

	// // 假设 clearDuplicateToken 是对应的服务接口
	// clearDuplicateToken(customerID, param.Token)
	model.Models.KillaraCustomerTokenModel.ClearDuplicateToken(customerID, param.Token, 1)

	// return map[string]interface{}{
	// 	"success":    true,
	// 	"error_code": 0,
	// 	"error_text": "",
	// 	"data":       make(map[string]interface{}),
	// }, nil

	// log.Println(param)
	return resp.Success()
}

// @Action account/registerSmsCode
// AccountRegisterSmsCode
// action: string;
// country_code?: string;
// telephone?: string;
// token: string;
func AccountRegisterSmsCode(ctx *gin.Context, param *AccountRegisterSmsCodeParam) (resp *basic.Response) {
	// ctx.ShouldBind()
	log.Println()
	return resp.Success()
}

// @Action account/forgetSmsCode
// AccountForgetSmsCode
// action: string;
// country_code?: string;
// telephone?: string;
// token: string;
func AccountForgetSmsCode(ctx *gin.Context, param *AccountForgetSmsCodeParam) (resp *basic.Response) {
	// ctx.ShouldBind()
	log.Println()
	return resp.Success()
}

type RegisterValidEmailCode struct {
	Code      string
	Email     string
	AppMarket int
}

// @Action account/registerEmailCode
// AccountRegisterEmailCode
// randstr:    string;
// sign:       string;
// action:     string;
// app_market: int;
// email:      string;
// timestamp:  int64;
// token:      string;
func AccountRegisterEmailCode(ctx *gin.Context, param *AccountRegisterEmailCodeParam) (resp *basic.Response) {
	log.Println(param)

	if !email.IsEmailValid(param.Email) {
		return resp.Error(basic.ErrEmailFormat)
	}

	gcm := encryption_decryption.NewSecretGCM[RegisterValidEmailCode](CompanyKey)

	code := auth.GenerateVerificationCode()
	codetoken := &RegisterValidEmailCode{
		Code:      code,
		Email:     param.Email,
		AppMarket: param.AppMarket,
	}
	tokenstr, err := gcm.Encrypt(codetoken)
	if err != nil {
		return resp.Error(basic.ErrEncGcm)
	}

	resp.Success(map[string]any{
		"token": tokenstr,
	})
	return resp.Success()
}

// @Action member/alterPassword
// MemberAlterPassword
// action: string;
// confirm_password: string;
// new_password: string;
// old_password: string;
// token?: string;
func MemberAlterPassword(ctx *gin.Context, param *MemberAlterPasswordParam) (resp *basic.Response) {
	// ctx.ShouldBind()
	log.Println()
	return resp.Success()
}

// @Action account/loginWithEmailPassword
// AccountLoginWithEmailPassword
// password:   string;
// randstr:    string;
// sign:       string;
// action:     string;
// device:     string;
// version:    string;
// app_market: int;
// email:      string;
// timestamp:  int64;
// token:      string;
func AccountLoginWithEmailPassword(ctx *gin.Context, param *AccountLoginWithEmailPasswordParam) (resp *basic.Response) {

	log.Println(param)
	return resp.Success()
}