package core

import (
	"intent-system/pkg/config"
	"intent-system/pkg/dal/dao"
	"intent-system/pkg/dal/models"
	"intent-system/pkg/email"
	"intent-system/pkg/itypes"
	"intent-system/pkg/proto"
	"intent-system/pkg/utils"
	"strings"

	"github.com/civet148/log"
	"github.com/civet148/sqlca/v2"
)

type CommonCore struct {
	db  *sqlca.Engine
	cfg *config.Config

	loginDAO      *dao.LoginDAO
	dictionaryDAO *dao.DictionaryDAO
	inviteCodeDAO *dao.InviteCodeDAO
	customerDAO   *dao.CustomerDAO
	userDAO       *dao.UserDAO
}

func NewCommonCore(cfg *config.Config, db *sqlca.Engine) *CommonCore {
	return &CommonCore{
		db:            db,
		cfg:           cfg,
		loginDAO:      dao.NewLoginDAO(db),
		dictionaryDAO: dao.NewDictionaryDAO(db),
		inviteCodeDAO: dao.NewInviteCodeDAO(db),
		customerDAO:   dao.NewCustomerDAO(db),
		userDAO:       dao.NewUserDAO(db),
	}
}

func (m *CommonCore) SendAuthCode(req *proto.SendAuthCodeReq) (resp *proto.SendAuthCodeResp, code itypes.BizCode) {
	var err error

	//TODO: check DDOS

	_, err = m.inviteCodeDAO.DeleteUnusedCodeByUserAcc(req.Email)
	if err != nil {
		log.Errorf(err.Error())
		return nil, itypes.NewBizCodeDatabaseError()
	}

	cfg, err := m.dictionaryDAO.SelectEmailConfig()
	if err != nil {
		log.Errorf(err.Error())
		return nil, itypes.NewBizCode(itypes.CODE_INVALID_PARAMS, err.Error())
	}
	regCode := utils.GenAuthCode()
	var strLanguage = req.Language
	if strLanguage == "" {
		strLanguage = models.Language_EN
	}
	ss := strings.Split(req.Email, "@")
	if len(ss) == 1 {
		err = log.Errorf("invalid email address [%s]", req.Email)
		return nil, itypes.NewBizCode(itypes.CODE_INVALID_PARAMS, err.Error())
	}

	switch req.ActionType {
	case proto.ActionType_UserRegister:
		{
			var body string
			body = email.RegisterVerificationCodeMessage(req.Language, ss[0], regCode)
			err = email.SendVerificationCode(cfg, email.SubjectVerificationCodeForRegister, req.Email, body)
			if err != nil {
				err = log.Errorf("email send error [%s]", err.Error())
				return nil, itypes.NewBizCode(itypes.CODE_INTERNAL_SERVER_ERROR, err.Error())
			}
		}
	case proto.ActionType_ResetPassword:
		log.Warnf("TODO: send verification code for reset password")
	}

	_, err = m.inviteCodeDAO.Insert(&models.InviteCodeDO{
		RandomCode: regCode,
		UserAcc:    req.UserName,
		LinkUrl:    req.Email,
		State:      dao.InviteCodeStateUnused,
	})
	if err != nil {
		log.Errorf(err.Error())
		return nil, itypes.NewBizCodeDatabaseError()
	}
	return &proto.SendAuthCodeResp{}, itypes.BizOK
}
