package validator

import (
	"fmt"
	"strings"

	"github.com/go-pg/pg/v10"
	"github.com/go-playground/validator/v10"
)

func GetValidationErrorMsg(err error) (bool, string) {
	valerr, ok := err.(validator.ValidationErrors)
	if ok {
		return true, GetError(&valerr)
	}

	fielderr, ok := err.(*FieldError)
	if ok {
		return true, fielderr.Error()
	}

	pgerr, ok := err.(pg.Error)
	if ok && pgerr.IntegrityViolation() {
		return true, pgerr.Field(68)
	}

	return false, err.Error()
}

func GetError(errs *validator.ValidationErrors) string {
	size := len(*errs)
	msg := make([]string, size)
	for i, err := range *errs {
		key := err.Field()
		if len(key) == 0 {
			key = err.Tag()
		}
		msg[i] = fmt.Sprintf("%s %s", key, readableValidationError(err.Tag(), err.Param(), err.Value()))
	}

	return strings.Join(msg, ". ")
}

func readableValidationError(tag string, param string, value interface{}) string {
	switch tag {
	case "required":
		return tag
	case "lte":
		return fmt.Sprintf("greater than %s", param)
	case "gte":
		return fmt.Sprintf("less than %s", param)
	case "len":
		return fmt.Sprintf("not %s length", param)
	case "max":
		return fmt.Sprintf("greater than %s length", param)
	case "min":
		return fmt.Sprintf("less than %s length", param)
	case "serial":
		return fmt.Sprintf("'%v' invalid", value)
	case "vin":
		return fmt.Sprintf("'%v' invalid", value)
	case "url":
		return "invalid url"
	default:
		return fmt.Sprintf("%s %s", tag, param)
	}
}
