package service

import (
	richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
	validation "github.com/go-ozzo/ozzo-validation/v4"
)

const (
	ErrValidationPositive     = "must be positive"
	ErrValidationInvalidInput = "invalid input"
)

type Validate struct{}

func NewValidate() Validate {
	return Validate{}
}

func (v Validate) ValidateAddToCart(req AddToCartRequest) error {
	const op = "shoppingbasketapp.service.AddToCart"

	if err := validation.ValidateStruct(&req,
		validation.Field(&req.UserID, validation.Required),
		validation.Field(&req.ProductID, validation.Required),
		validation.Field(&req.Price, validation.Required, validation.Min(int64(1)).Error(ErrValidationPositive)),
		validation.Field(&req.Quantity, validation.Min(int(1)).Error(ErrValidationPositive)),
		validation.Field(&req.Name, validation.Required)); err != nil {

		fieldErr := make(map[string]interface{})
		vErr, ok := err.(validation.Errors)
		if ok {
			for key, value := range vErr {
				if value != nil {
					fieldErr[key] = value.Error()
				}
			}
		}

		return richerror.New(op).WithMessage(ErrValidationInvalidInput).
			WithMeta(fieldErr).WithErr(err).WithKind(richerror.KindInvalid)
	}

	return nil
}

func (v Validate) ValidateRemoveFromCart(req RemoveFromCartRequest) error {
	const op = "shoppingbasketapp.service.ValidateRemoveFromCart"

	if err := validation.ValidateStruct(&req,
		validation.Field(&req.UserID, validation.Required),
		validation.Field(&req.ProductID, validation.Required)); err != nil {

		fieldErrs := make(map[string]interface{})
		vErr, ok := err.(validation.Errors)
		if ok {
			for key, value := range vErr {
				if value != nil {
					fieldErrs[key] = value.Error()
				}
			}
		}
		return richerror.New(op).WithMessage(ErrValidationInvalidInput).
			WithKind(richerror.KindInvalid).WithMeta(fieldErrs).WithErr(err)
	}

	return nil
}

func (v Validate) ValidateUpdateQuantity(req UpdateQuantityRequest) error {
	const op = "shoppingbasketapp.service.ValidateUpdateQuantity"

	if err := validation.ValidateStruct(&req,
		validation.Field(&req.UserID, validation.Required),
		validation.Field(&req.ProductID, validation.Required),
		validation.Field(&req.Quantity, validation.Required, validation.Min(int(1)))); err != nil {

		fieldErrs := make(map[string]interface{})
		vErr, ok := err.(validation.Errors)
		if ok {
			for key, value := range vErr {
				if value != nil {
					fieldErrs[key] = value.Error()
				}
			}
		}
		return richerror.New(op).WithMessage(ErrValidationInvalidInput).
			WithKind(richerror.KindInvalid).WithMeta(fieldErrs).WithErr(err)
	}

	return nil
}
