package tenantctx

import (
	"context"

	"github.com/tidbcloud/account/central/jobqueue"
	"github.com/tidbcloud/account/commons/config"
	"github.com/tidbcloud/account/commons/database"
	"github.com/tidbcloud/account/internel/dao/entity"
	"github.com/tidbcloud/tiinf/errs"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

type PocApplication struct {
	TenantID       uint64
	CreatorID      uint64
	Questions      []PocQuestion
	PocExtraFields *entity.PocExtraFields
}

type PocQuestion struct {
	Number   uint64
	Type     entity.PocQuestionType
	Question string
	Options  []PocQuestionOption
	Note     string
}

type PocQuestionOption struct {
	Name       string
	IsSelected bool
}

func buildPocApplicationEntity(params *PocApplication) *entity.PocApplication {
	pocApplicationEntity := &entity.PocApplication{
		Updatable:      entity.Updatable{},
		TenantID:       entity.ID(params.TenantID),
		Tenant:         nil,
		CreatorID:      entity.ID(params.CreatorID),
		Creator:        nil,
		Questions:      nil,
		Synced:         false,
		PocExtraFields: params.PocExtraFields,
	}

	questions := make([]*entity.PocQuestion, 0, len(params.Questions))
	for _, question := range params.Questions {
		questionEntity := &entity.PocQuestion{
			Updatable: entity.Updatable{},
			Number:    question.Number,
			Type:      question.Type,
			Question:  question.Question,
			Options:   entity.PocQuestionOptions{},
			Note:      question.Note,
		}
		options := make([]*entity.PocQuestionOption, 0, len(question.Options))
		for _, option := range question.Options {
			options = append(options, &entity.PocQuestionOption{
				Name:       option.Name,
				IsSelected: option.IsSelected,
			})
		}
		questionEntity.Options = entity.PocQuestionOptions{
			Options: options,
		}
		questions = append(questions, questionEntity)
	}
	pocApplicationEntity.Questions = questions

	return pocApplicationEntity
}

func (c Context) CreatePocApplication(ctx context.Context, params *PocApplication) (uint64, error) {
	pocApplicationEntity := buildPocApplicationEntity(params)
	err := database.Transaction(func(tx *gorm.DB) error {
		return pocApplicationEntity.Create(tx)
	})
	if err != nil {
		c.log.Error("failed to create poc application db record", zap.Error(err))
		return 0, errs.NewInternalDB("failed to create poc application db record", err)
	}

	pocApplicationID := pocApplicationEntity.ID.Uint64()
	queuePayload := config.JobSyncPocApplicationSchema{
		PocApplicationID: pocApplicationID,
	}
	err = jobqueue.Enqueue(ctx, config.JobSyncPocApplication, queuePayload)
	if err != nil {
		c.Log().Error("failed to enqueue sync poc application job", zap.Uint64("pocApplicationID", pocApplicationID), zap.Error(err))
		return pocApplicationID, errs.NewInternalMQ("failed to enqueue sync poc application job", err)
	}
	return pocApplicationID, nil
}
