package logic

import (
	"fmt"
	"fusenapi/model/gmodel"
	"fusenapi/utils/auth"
	"fusenapi/utils/basic"
	"fusenapi/utils/wevent"
	"net/http"
	"time"

	"context"

	"fusenapi/server/auth/internal/svc"
	"fusenapi/server/auth/internal/types"

	"github.com/474420502/requests"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/rest/httpx"
	"gorm.io/gorm"
)

type UserEmailConfirmationLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUserEmailConfirmationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserEmailConfirmationLogic {
	return &UserEmailConfirmationLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

// 处理进入前逻辑w,r
// func (l *UserEmailConfirmationLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
// }

func FinishRegister(svcCtx *svc.ServiceContext, user *gmodel.FsUser, token *auth.RegisterToken) error {
	// 创建签证
	jwtToken, err := auth.GenerateJwtTokenUint64(
		auth.StringToHash(*user.PasswordHash),
		svcCtx.Config.Auth.AccessExpire,
		time.Now().UTC().Unix(),
		user.Id,
		token.GuestId,
	)

	if err != nil {

		return err
	}

	event := wevent.NewWebsocketEventSuccess(wevent.UserEmailRegister, token.TraceId)
	event.Data = wevent.DataEmailRegister{
		JwtToken: jwtToken,
	}
	err = CommonNotify(svcCtx.Config.MainAddress, token.Wid, event)
	if err != nil {
		// logx.Error(err, token.TraceId)
		return err
	}

	return nil
}

func CommonNotify(MainAddress, wid string, event *wevent.WebsocketEvent) error {
	tp := requests.Post(fmt.Sprintf("%s/api/websocket/common_notify", MainAddress))
	tp.SetBodyJson(requests.M{
		"wid":  wid,
		"data": event,
	})

	wresp, err := tp.Execute()
	if err != nil {
		// logx.Error(err, token.TraceId)
		return err
	}

	result := wresp.Json()
	if result.Get("code").Int() != 200 {
		// logx.Error(result.Get("message"))
		return fmt.Errorf("%s", result.Get("message").Str)
	}

	return nil
}

func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEmailConfirmation, userinfo *auth.UserInfo) (resp *basic.Response) {
	// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
	// userinfo 传入值时, 一定不为null

	token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.Token)
	if err != nil {
		logx.Error(err)
		return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
	}

	switch token.OperateType {
	case auth.OpTypeRegister:
		if time.Since(token.CreateAt) >= 24*time.Hour {
			return resp.SetStatus(basic.CodeOAuthConfirmationTimeoutErr)
		}
		logx.Info(token.Platform)
		switch token.Platform {
		case string(auth.PLATFORM_GOOGLE):
			//   谷歌平台的注册流程
			user, err := l.svcCtx.AllModels.FsUser.RegisterByGoogleOAuth(l.ctx, token)
			if err != nil {
				logx.Error(err, token.TraceId)
				return resp.SetStatus(basic.CodeDbSqlErr)
			}

			err = FinishRegister(l.svcCtx, user, token)
			if err != nil {
				logx.Error(err)
			}
			logx.Info("success", token.TraceId)

		case string(auth.PLATFORM_FACEBOOK):
		case string(auth.PLATFORM_FUSEN):
			// log.Println("aaaa", token)
			user, err := l.svcCtx.AllModels.FsUser.RegisterByFusen(l.ctx, token)
			if err != nil && err != gorm.ErrRecordNotFound {
				logx.Error(err, ":", token.TraceId)
				return resp.SetStatus(basic.CodeDbSqlErr, err.Error())
			}
			err = FinishRegister(l.svcCtx, user, token)
			if err != nil {
				logx.Error(err)
			}
			logx.Info("success:", token.TraceId)
		}

	default:
		return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
	}

	return resp.SetStatus(basic.CodeOK)
}

// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
func (l *UserEmailConfirmationLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
	if resp.Code == 200 {
		successHtml := `<!DOCTYPE html>
		<html>
		<head>
		  <title>注册成功</title>
		  <style>
			body {
			  font-family: sans-serif; 
			  font-size: 16px;
			}
			
			h1 {
			  font-size: 24px;
			  color: red;  
			}
			
			@media screen and (max-width: 480px) {
			  body {
				font-size: 14px;  
			  }
			  
			  h1 {
				font-size: 18px;
			  }
			}
		  </style>
		</head>
		<body>
		  <h1>恭喜!您的注册成功。</h1>  
		
		  <p>感谢您在我们网站进行注册。您的账号已经激活。</p>
		
		  <p>您现在可以使用您的邮箱地址和密码登录我们的网站,享受完整的服务和功能。</p>
		
		  <p>再次感谢您的信任和支持。如果您有任何问题,请随时联系我们。</p>
		
		  <p>祝您使用愉快!</p>
		</body>
		</html>`
		w.Write([]byte(successHtml))
		httpx.Ok(w)
	} else {

		errorHtml := `
		<!DOCTYPE html>
		<html>
		<head>
		  <title>注册失败</title>
		  <style>
			body {
			  font-family: sans-serif; 
			  font-size: 16px;
			}
			
			h1 {
			  font-size: 24px;
			  color: blue;  
			}
			
			@media screen and (max-width: 480px) {
			  body {
				font-size: 14px;  
			  }
			  
			  h1 {
				font-size: 18px;
			  }
			}
		  </style>
		</head>
		<body>
		  <h1>%s</h1>  
		</body>
		</html>
		`

		errorHtml = fmt.Sprintf(errorHtml, resp.Message)
		w.Write([]byte(errorHtml))
		httpx.Ok(w)
	}
}