package accountapiimp

import (
	"errors"
	"net/http"

	"github.com/tech/sendico/pkg/api/http/response"
	"github.com/tech/sendico/pkg/merrors"
	"github.com/tech/sendico/pkg/model"
	mutil "github.com/tech/sendico/server/internal/mutil/param"
	"go.mongodb.org/mongo-driver/v2/bson"
	"go.uber.org/zap"
)

func (a *AccountAPI) verify(r *http.Request) http.HandlerFunc {
	// Validate user input
	token := mutil.GetToken(r)
	// Get user
	ctx := r.Context()
	// Delete verification token to confirm account
	t, err := a.vdb.Consume(ctx, bson.NilObjectID, model.PurposeAccountActivation, token)
	if err != nil {
		a.logger.Debug("Failed to consume verification token", zap.Error(err))
		return a.mapTokenErrorToResponse(err)
	}

	if t.Purpose != model.PurposeAccountActivation {
		a.logger.Warn("Invalid token purpose", zap.String("expected", string(model.PurposeAccountActivation)), zap.String("actual", string(t.Purpose)))
		return response.DataConflict(a.logger, a.Name(), "Invalid token purpose")
	}

	var user model.Account
	if err := a.db.Get(ctx, t.AccountRef, &user); err != nil {
		if errors.Is(err, merrors.ErrNoData) {
			a.logger.Debug("Verified user not found", zap.Error(err))
			return response.NotFound(a.logger, a.Name(), "User not found")
		}
		a.logger.Warn("Failed to fetch account", zap.Error(err))
		return response.Internal(a.logger, a.Name(), err)
	}

	user.Status = model.AccountActive
	if err = a.db.Update(ctx, &user); err != nil {
		a.logger.Warn("Failed to save account while verifying account", zap.Error(err))
		return response.Internal(a.logger, a.Name(), err)
	}
	if err := a.sendAccountVerificationCompletedNotification(&user); err != nil {
		a.logger.Warn("Failed to enqueue account verification notification", zap.Error(err), zap.String("email", user.Login))
	}

	// TODO: Send verification confirmation email
	return response.Success(a.logger)
}

func (a *AccountAPI) resendVerificationMail(r *http.Request) http.HandlerFunc {
	return a.sendVerificationMail(r, getID)
}

func (a *AccountAPI) resendVerification(r *http.Request) http.HandlerFunc {
	return a.sendVerificationMail(r, getEmail)
}
