package rules

import (
	"bytes"
	"context"
	"fmt"
	"html/template"

	"code.tnxs.net/taxnexus/lib/api/auth0/auth0_models"
	"code.tnxs.net/taxnexus/lib/api/devops/devops_client/user"
	"code.tnxs.net/taxnexus/lib/api/devops/devops_models"
	httptransport "github.com/go-openapi/runtime/client"

	"code.tnxs.net/taxnexus/lib/api/workflow/workflow_client/outgoing_email_message"
	"code.tnxs.net/taxnexus/lib/api/workflow/workflow_models"
	"code.tnxs.net/taxnexus/lib/app"
	"go.temporal.io/sdk/workflow"
)

// StoreUserActivity posts a new user object to datastore and creates the auth0 user
func StoreUserActivity(ctx workflow.Context, w app.UserActivityWrapper) error { //nolint:gocritic // what we want
	postUserParams := user.NewPostUsersParamsWithTimeout(postTimeout)
	if w.Obj.Name == "" {
		w.Obj.Name = w.Obj.FirstName + " " + w.Obj.LastName
	}
	postUserParams.UserRequest = &devops_models.UserRequest{
		Data: []*devops_models.User{&w.Obj},
	}
	devopsResponse, err := devopsClient.User.PostUsers(postUserParams,
		httptransport.APIKeyAuth(
			"X-API-Key",
			"header",
			w.APIKey,
		))
	if err != nil {
		return err
	}
	var newUser *devops_models.User
	for _, itm := range devopsResponse.Payload.Data { // single iteration execution
		newUser = itm
	}
	//
	// create new Auth0 user
	//
	auth0UserID, err := app.GetAuth0UserByEmail(newUser.Email)
	if err != nil {
		return err
	}
	if auth0UserID != "not found" {
		return fmt.Errorf("app.StoreUserActivity: 💣 ⛔ Auth0 user exists: %s", auth0UserID)
	}
	newAuth0UserID, err := app.CreateNewAuth0User(&app.NewAuth0User{
		Email:         newUser.Email,
		EmailVerified: true,
		Name:          newUser.Name,
		UserID:        newUser.ID,
		Username:      newUser.Email,
		FamilyName:    newUser.LastName,
		GivenName:     newUser.FirstName,
	})
	if err != nil {
		return err
	}
	newUser.Auth0UserID = newAuth0UserID
	//
	// update Taxnexus user
	//
	putUserParams := user.NewPutUsersParamsWithTimeout(getTimeout)
	putUserParams.UserRequest = &devops_models.UserRequest{
		Data: []*devops_models.User{newUser},
	}
	_, err = devopsClient.User.PutUsers(putUserParams,
		httptransport.APIKeyAuth(
			"X-API-Key",
			"header",
			w.APIKey,
		))
	if err != nil {
		return err
	}
	//
	// send emails
	//
	sugar.Info("crm.storeUser: 👍 📤")
	return nil
}

// NotifyUserActivity sends an email to a new lead
func NotifyUserActivity(ctx context.Context, w *app.UserActivityWrapper) error {
	sugar.Info("workflow.notifyUser: 📥")
	var buf bytes.Buffer
	const textBody = `

Alert! New User Inquiry from Taxnexus.io website.

 Taxnexus ID: {{.ID}}
  First Name: {{.FirstName}}
   Last Name: {{.LastName}}
       Email: {{.Email}}
     Message: {{.Description}}

-- end --
`
	t := template.Must(template.New("textBody").Parse(textBody))
	err := t.Execute(&buf, w)
	if err != nil {
		return err
	}
	emailParams := outgoing_email_message.NewPostOutgoingEmailMessagesParamsWithTimeout(postTimeout)
	emailParams.OutgoingEmailMessageRequest = &workflow_models.OutgoingEmailMessageRequest{
		Data: []*workflow_models.OutgoingEmailMessage{
			{
				Subject:              "New lead from " + w.Obj.Name,
				ValidatedFromAddress: "support@taxnexus.net",
				ToAddress:            "info@taxnexus.net",
				FromName:             "Taxnexus Onboarding",
				Text:                 buf.String(),
				HTML:                 "<pre>" + buf.String() + "</pre>",
			},
		},
	}
	_, err = workflowClient.OutgoingEmailMessage.PostOutgoingEmailMessages(
		emailParams,
		httptransport.APIKeyAuth(
			"X-API-Key",
			"header",
			w.APIKey,
		))
	if err != nil {
		return err
	}
	sugar.Info("workflow.notifyUser: 👍 📤")
	return nil
}

// EnrichUsers synchronizes contact sources
func EnrichUsers(m *devops_models.User, r *auth0_models.User) (*devops_models.User, *auth0_models.User) { //nolint:gocritic,lll // shut up!
	// parse first/last name
	nm := *m
	nr := *r
	nm.LastIP = r.LastIP
	nm.LastLogin = r.LastLogin
	nm.LoginCount = r.LoginsCount
	nm.Auth0UserID = r.UserID

	// enrich taxnexus user (m->nm)
	if m.CommunityNickname == "" && r.Nickname != "" {
		nm.CommunityNickname = r.Nickname
	}
	if m.Email == "" && r.Email != "" {
		nm.Email = r.Email
	}
	if m.SmallPhotoURL == "" && r.Picture != "" {
		nm.SmallPhotoURL = r.Picture
	}
	// enrich auth0 user (r->nr)
	if r.Nickname == "" && m.CommunityNickname != "" {
		nr.Nickname = m.CommunityNickname
	}
	if r.Picture == "" && m.SmallPhotoURL != "" {
		nr.Picture = m.SmallPhotoURL
	}

	return &nm, &nr
}
