package cg_sdk

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

const (
	delimiter = "_"
)

const (
	encodeSegmentFormType    = "form"
	encodeSegmentDynamicType = "dynamic"
)

type LibraryCodeInfo struct {
	ID       string `json:"id" sqlresult:"column:id;"`
	ParentID string `json:"parentId" sqlresult:"column:parent_id;"`
	Name     string `json:"name" sqlresult:"column:name;"`
	Code     string `json:"code" sqlresult:"column:content;"`
}

type ConfigEncode struct {
	InputStruct any

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

	inputMap         map[string]any
	segmentValueMap  map[string]LibraryCodeInfo
	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]LibraryCodeInfo)
	}
	for _, encodeSegment := range configEncode.encodeConfigInfo.ConfigContent {
		if inputFieldValueAny, ok := configEncode.inputMap[encodeSegment.FieldValue]; ok {
			switch encodeSegment.EncodeSegmentType {
			case encodeSegmentFormType:
				fallthrough
			case encodeSegmentDynamicType:
				switch inputFieldValueAny.(type) {
				case LibraryCodeInfo:
					configEncode.segmentValueMap[encodeSegment.EncodeSegmentID] = inputFieldValueAny.(LibraryCodeInfo)
				case string:
					configEncode.segmentValueMap[encodeSegment.EncodeSegmentID] = LibraryCodeInfo{Name: inputFieldValueAny.(string)}
				default:
					return errors.New("转化业务参数失败,未知类型:" + encodeSegment.EncodeSegmentType)
				}

			default:
				return errors.New("未知类型:" + encodeSegment.EncodeSegmentType)
			}
		}
	}
	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)
}