package survey

import (
	"context"
	"encoding/json"
	"strings"
	"sync"

	"github.com/tidbcloud/account/commons/database"

	"github.com/tidbcloud/account/idl/pbgen/proto/central"
	"github.com/tidbcloud/account/internel/dao"
	"github.com/tidbcloud/account/internel/dao/entity"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
)

var (
	showPlgOnBoardingSurveyPageEmailSuffix = []string{}
)

const (
	surveyIdentTypeUser = "USER"

	plgOnBoardingSurveyName = "plg_on_boarding"
)

type SurveySvcIface interface {
	IsShowPlgOnBoardingSurveyPage(ctx context.Context, email string) (bool, error)
	CreatePlgOnBoardingSurvey(ctx context.Context, email string, req *central.CreatePlgOnBoardingSurveyReq) error
}

var (
	surveySvcInitOnce sync.Once
	surveySvcInstance SurveySvcIface
)

func GetSurveySvc() (SurveySvcIface, error) {
	surveySvcInitOnce.Do(func() {
		surveySvcInstance = NewSurveySvc()
	})
	return surveySvcInstance, nil
}

type SurveySvc struct {
}

func NewSurveySvc() SurveySvcIface {
	return &SurveySvc{}
}

func (s *SurveySvc) IsShowPlgOnBoardingSurveyPage(ctx context.Context, email string) (bool, error) {
	tilog.Info(ctx, "IsShowPlgOnBoardingSurveyPage req", zap.Any("email", email))

	dbSurveys, err := dao.GetDaoHub().Survey.ListSurveysBySurveyNameIdentTyeVal(ctx, database.DBConn.DB, plgOnBoardingSurveyName, surveyIdentTypeUser, email)
	if err != nil {
		tilog.Warn(ctx, "IsShowPlgOnBoardingSurveyPage GetSurveyBySurveyNameIdentTyeVal", zap.Any("email", email), zap.Any("err", err))
		return false, err
	}
	if len(dbSurveys) > 0 {
		tilog.Info(ctx, "IsShowPlgOnBoardingSurveyPage dbSurvey exist", zap.Any("email", email))
		return false, nil
	}

	hitEmail := isShowPlgOnBoardingSurveyPageHitEmail(email)
	if !hitEmail {
		tilog.Info(ctx, "IsShowPlgOnBoardingSurveyPage not hit email", zap.Any("email", email))
		return false, nil
	}

	//companyInfo, err := getHubSpotCompanyInfo(ctx, email)
	//if err != nil {
	//	tilog.Warn(ctx, "IsShowPlgOnBoardingSurveyPage isEmailExistCompanyInfoOnHubSpot error", zap.Any("email", email), zap.Any("err", err))
	//	return false, err
	//}
	//if isShowPlgOnBoardingSurveyPageHitCompanyName(companyInfo) {
	//	tilog.Info(ctx, "IsShowPlgOnBoardingSurveyPage hit company name, to show survey", zap.Any("email", email), zap.Any("companyName", companyInfo.CompanyName))
	//	return true, nil
	//}
	//tilog.Info(ctx, "IsShowPlgOnBoardingSurveyPage not hit company name", zap.Any("email", email), zap.Any("companyName", companyInfo.CompanyName))
	//return false, nil

	return true, nil

}

//func isShowPlgOnBoardingSurveyPageHitCompanyName(companyInfo *HubSpotCompanyInfo) bool {
//	if companyInfo == nil || companyInfo.CompanyName == "" {
//		return true
//	}
//	lowerName := strings.ToLower(companyInfo.CompanyName)
//	if strings.Contains(lowerName, "null") || strings.HasSuffix(lowerName, "'s org") {
//		return true
//	}
//	return false
//}

func isShowPlgOnBoardingSurveyPageHitEmail(email string) bool {
	if len(showPlgOnBoardingSurveyPageEmailSuffix) == 0 {
		return true
	}
	for _, suffix := range showPlgOnBoardingSurveyPageEmailSuffix {
		if strings.HasSuffix(email, suffix) {
			return true
		}
	}
	return false
}

func (s *SurveySvc) CreatePlgOnBoardingSurvey(ctx context.Context, email string, req *central.CreatePlgOnBoardingSurveyReq) error {
	tilog.Info(ctx, "CreatePlgOnBoardingSurvey start", zap.Any("email", email), zap.Any("req", req))

	content := PlgOnBoardingSurveyContent{
		WhyYouWantToUseTiDB: req.WhyYouWantToUseTiDB,
		CompanyName:         req.CompanyName,
		CompanyURL:          req.CompanyURL,
		Role:                req.Role,
		UsingDatabase:       req.UsingDatabase,
		Language:            req.Language,
	}
	if content.Role == nil {
		content.Role = []string{}
	}
	if content.UsingDatabase == nil {
		content.UsingDatabase = []string{}
	}
	if content.Language == nil {
		content.Language = []string{}
	}
	marshal, _ := json.Marshal(&content)

	survey := entity.Survey{
		SurveyName: plgOnBoardingSurveyName,
		IdentType:  surveyIdentTypeUser,
		IdentVal:   email,
		Content:    string(marshal),
		Status:     req.Status,
		Trigger:    req.Trigger,
	}

	_, err := dao.GetDaoHub().Survey.CreateSurvey(ctx, database.DBConn.DB, &survey)
	if err != nil {
		tilog.Error(ctx, "CreatePlgOnBoardingSurvey error", zap.Any("survey", survey), zap.Any("err", err))
		return err
	}

	tilog.Info(ctx, "CreatePlgOnBoardingSurvey end", zap.Any("survey", survey))

	return nil
}

type PlgOnBoardingSurveyContent struct {
	WhyYouWantToUseTiDB string   `json:"whyYouWantToUseTiDB"`
	CompanyName         string   `json:"companyName"`
	CompanyURL          string   `json:"companyURL"`
	Role                []string `json:"role"`
	UsingDatabase       []string `json:"usingDatabase"`
	Language            []string `json:"language"`
}

type HubSpotCompanyInfo struct {
	CompanyName string
	CompanyURL  string
}
