package cg_sdk

import (
	"errors"
	"git.sxidc.com/go-framework/baize/framework/core/api/request"
	"git.sxidc.com/go-framework/baize/framework/core/api/response"
)

const (
	delimiter = "_"
)

type ConfigEncode struct {
	InputStruct any

	ConfigNamespace  string
	ConfigName       string
	EncodeStatus     uint8
	CreateUserID     string
	TenantID         string
	OperatorUserName string

	inputMap         map[string]any
	segmentValueMap  map[string]string
	encodeConfigInfo *EncodeConfigInfo

	codeNamespace string
	Code          string
}

// 创建配置编码
func (configEncode *ConfigEncode) CreateConfigEncode() (*Code, error) {
	var err error
	configEncode.encodeConfigInfo, err = getEncodeConfigInfo(configEncode.TenantID, configEncode.ConfigNamespace, configEncode.ConfigName)
	if err != nil {
		return nil, err
	}

	configEncode.GenCodeNamespace()
	configEncode.inputMap = response.StructToMap(configEncode.InputStruct)
	err = configEncode.genSegmentValueMap()
	if err != nil {
		return nil, err
	}

	code := &Code{
		Namespace:        configEncode.codeNamespace,
		EncodeRuleID:     configEncode.encodeConfigInfo.EncodeRuleID,
		EncodeStatus:     configEncode.EncodeStatus,
		TenantID:         configEncode.TenantID,
		UpdateUserID:     configEncode.CreateUserID,
		OperatorUserName: configEncode.OperatorUserName,
	}

	code.Code, err = createEncode(configEncode.createCreateJsonBody())
	if err != nil {
		return nil, err
	}

	return code, nil
}

func (configEncode *ConfigEncode) UpdateConfigEncodeStatue() (*Code, error) {
	var err error
	configEncode.encodeConfigInfo, err = getEncodeConfigInfo(configEncode.TenantID, configEncode.ConfigNamespace, configEncode.ConfigName)
	if err != nil {
		return nil, err
	}

	configEncode.GenCodeNamespace()

	code := &Code{
		Code:             configEncode.Code,
		Namespace:        configEncode.codeNamespace,
		EncodeRuleID:     configEncode.encodeConfigInfo.EncodeRuleID,
		TenantID:         configEncode.TenantID,
		UpdateUserID:     configEncode.CreateUserID,
		OperatorUserName: configEncode.OperatorUserName,
	}

	return code, nil
}

func (configEncode *ConfigEncode) genSegmentValueMap() error {
	if configEncode.segmentValueMap == nil {
		configEncode.segmentValueMap = make(map[string]string)
	}
	for _, encodeSegment := range configEncode.encodeConfigInfo.ConfigContent {
		if valueString, ok := configEncode.inputMap[encodeSegment.FieldValue].(string); ok {
			configEncode.segmentValueMap[encodeSegment.EncodeSegmentID] = valueString
		} else {
			return errors.New("转化业务参数失败:SegmentValueMap")
		}
	}
	return nil
}

func (configEncode *ConfigEncode) createCreateJsonBody() CreateEncodeJsonBody {
	return CreateEncodeJsonBody{
		Namespace:                configEncode.codeNamespace,
		EncodeRuleID:             configEncode.encodeConfigInfo.EncodeRuleID,
		SegmentValueMap:          configEncode.segmentValueMap,
		EncodeStatus:             configEncode.EncodeStatus,
		CreateUserIDJsonBody:     request.CreateUserIDJsonBody{CreateUserID: configEncode.CreateUserID},
		TenantIDJsonBody:         request.TenantIDJsonBody{TenantID: configEncode.TenantID},
		OperatorUserNameJsonBody: request.OperatorUserNameJsonBody{OperatorUserName: configEncode.OperatorUserName},
	}
}

func (code *Code) FormUpdateEncodeJsonBody() *UpdateEncodeJsonBody {
	return &UpdateEncodeJsonBody{
		Namespace:                code.Namespace,
		EncodeRuleID:             code.EncodeRuleID,
		Content:                  code.Code,
		UpdateUserIDJsonBody:     request.UpdateUserIDJsonBody{UpdateUserID: code.UpdateUserID},
		TenantIDJsonBody:         request.TenantIDJsonBody{TenantID: code.TenantID},
		OperatorUserNameJsonBody: request.OperatorUserNameJsonBody{OperatorUserName: code.OperatorUserName},
	}
}

func GetFreeStatus() uint8 {
	return codeStatusFree
}

func GetUsingStatus() uint8 {
	return codeStatusUsing
}

func GenCodeNamespace(configNamespace string, configName string) string {
	return configNamespace + delimiter + configName
}

func (configEncode *ConfigEncode) GenCodeNamespace() {
	configEncode.codeNamespace = GenCodeNamespace(configEncode.ConfigNamespace, configEncode.ConfigName)
}