package libs

import (
	"fmt"
	"strings"

	"git.apinb.com/bsm-sdk/core/errcode"
	"github.com/go-playground/validator/v10"
)

var (
	validate *validator.Validate
)

func init() {
	validate = validator.New()
	// 注册自定义验证规则
	registerCustomValidators()
}

// registerCustomValidators 注册自定义验证器
func registerCustomValidators() {
	// 注册手机号验证
	validate.RegisterValidation("phone", validatePhone)
	// 注册邮箱验证
	validate.RegisterValidation("email_format", validateEmail)
}

// validatePhone 验证手机号（11位数字，以1开头）
func validatePhone(fl validator.FieldLevel) bool {
	phone := fl.Field().String()
	// 空字符串由omitempty或required处理，这里返回true
	if phone == "" {
		return true
	}
	if len(phone) != 11 {
		return false
	}
	if len(phone) > 0 && phone[0] != '1' {
		return false
	}
	for _, char := range phone {
		if char < '0' || char > '9' {
			return false
		}
	}
	return true
}

// validateEmail 验证邮箱格式（简单的邮箱格式验证）
func validateEmail(fl validator.FieldLevel) bool {
	email := fl.Field().String()
	if email == "" {
		return true // 允许为空，使用omitempty处理
	}
	parts := strings.Split(email, "@")
	if len(parts) != 2 {
		return false
	}
	if len(parts[0]) == 0 || len(parts[1]) == 0 {
		return false
	}
	if !strings.Contains(parts[1], ".") {
		return false
	}
	return true
}

// ValidateStruct 验证结构体，返回格式化的错误信息
func ValidateStruct(s interface{}) error {
	if err := validate.Struct(s); err != nil {
		return formatValidationError(err)
	}
	return nil
}

// formatValidationError 格式化验证错误信息
func formatValidationError(err error) error {
	if validationErrors, ok := err.(validator.ValidationErrors); ok {
		var errMsg strings.Builder
		errMsg.WriteString("参数验证失败: ")
		for i, validationError := range validationErrors {
			if i > 0 {
				errMsg.WriteString("; ")
			}
			errMsg.WriteString(getFieldErrorMsg(validationError))
		}
		// 返回ErrInvalidArgument错误
		return errcode.ErrInvalidArgument
	}
	return errcode.ErrInvalidArgument
}

// getFieldErrorMsg 获取字段错误信息
func getFieldErrorMsg(fe validator.FieldError) string {
	field := fe.Field()
	tag := fe.Tag()

	switch tag {
	case "required":
		return fmt.Sprintf("%s 字段为必填项", field)
	case "min":
		return fmt.Sprintf("%s 字段长度不能小于 %s", field, fe.Param())
	case "max":
		return fmt.Sprintf("%s 字段长度不能大于 %s", field, fe.Param())
	case "len":
		return fmt.Sprintf("%s 字段长度必须为 %s", field, fe.Param())
	case "email_format":
		return fmt.Sprintf("%s 字段邮箱格式不正确", field)
	case "phone":
		return fmt.Sprintf("%s 字段手机号格式不正确（应为11位数字）", field)
	case "gte":
		return fmt.Sprintf("%s 字段值必须大于或等于 %s", field, fe.Param())
	case "lte":
		return fmt.Sprintf("%s 字段值必须小于或等于 %s", field, fe.Param())
	case "gt":
		return fmt.Sprintf("%s 字段值必须大于 %s", field, fe.Param())
	case "lt":
		return fmt.Sprintf("%s 字段值必须小于 %s", field, fe.Param())
	default:
		return fmt.Sprintf("%s 字段验证失败 (%s)", field, tag)
	}
}
