package benefactorkindboxreqvalidator

import (
	"context"
	"fmt"
	"git.gocasts.ir/ebhomengo/niki/entity"
	addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
	param "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactore"
	errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
	validation "github.com/go-ozzo/ozzo-validation/v4"
	"time"
)

const (
	MinKindBoxReq uint = 1
	MaxKindBoxReq uint = 100
)

type BenefactorSvc interface {
	BenefactorExistByID(ctx context.Context, request param.BenefactorExistByIDRequest) (param.BenefactorExistByIDResponse, error)
}

type AddressSvc interface {
	AddressExistByID(ctx context.Context, request addressparam.GetAddressByIDRequest) (addressparam.GetAddressByIDResponse, error)
}

type Validator struct {
	benefactorSvc BenefactorSvc
	addressSvc    AddressSvc
}

type ValidatorError struct {
	Fields map[string]string `json:"error"`
	Err    error             `json:"message"`
}

func (v ValidatorError) Error() string {
	var err string

	for key, value := range v.Fields {
		err += fmt.Sprintf("%s: %s\n", key, value)
	}

	return err
}

func New(benefactorSvc BenefactorSvc, addressSvc AddressSvc) Validator {
	return Validator{benefactorSvc: benefactorSvc, addressSvc: addressSvc}
}

func (v Validator) doesBenefactorExist(value interface{}) error {
	benefactorID, ok := value.(uint)
	if !ok {
		return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
	}
	_, err := v.benefactorSvc.BenefactorExistByID(context.Background(), param.BenefactorExistByIDRequest{ID: benefactorID})
	if err != nil {
		return fmt.Errorf(errmsg.ErrorMsgNotFound)
	}

	return nil
}

func (v Validator) doesTypeExist(value interface{}) error {
	typeID, ok := value.(entity.KindBoxType)
	if !ok {
		return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
	}
	if !typeID.IsValid() {
		return fmt.Errorf(errmsg.ErrorMsgNotFound)
	}

	return nil
}

func (v Validator) doesAddressExist(benefactorID uint) validation.RuleFunc {
	return func(value interface{}) error {
		addressID, ok := value.(uint)
		if !ok {
			return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
		}
		address, err := v.addressSvc.AddressExistByID(context.Background(), addressparam.GetAddressByIDRequest{ID: addressID})
		if err != nil {
			return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
		}
		if address.Address == nil {
			return fmt.Errorf(errmsg.ErrorMsgNotFound)
		}
		if address.Address.BenefactorID != benefactorID {
			return fmt.Errorf(errmsg.ErrorMsgNotFound)
		}

		return nil
	}
}

func (v Validator) isDateValid(value interface{}) error {
	date, ok := value.(string)
	if !ok {
		return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
	}
	t, err := time.Parse(time.DateTime, date)
	if err != nil {
		return fmt.Errorf(errmsg.ErrorMsgInvalidInput)
	}
	if t.Before(time.Now()) {
		return fmt.Errorf(errmsg.ErrorMsgInvalidInput)
	}

	return nil
}

// func (v Validator) doesKindBoxRequestExist(value interface{}) error {
//	kindBoxReqID, ok := value.(uint)
//	if !ok {
//		return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
//	}
//	_, err := v.repo.KindBoxReqExist(kindBoxReqID)
//	if err != nil {
//		return fmt.Errorf(errmsg.ErrorMsgNotFound)
//	}
//
//	return nil
//}
//
// func (v Validator) doesKindBoxBelongToBenefactor(benefactorID uint) validation.RuleFunc {
//	return func(value interface{}) error {
//		kbID, ok := value.(uint)
//		if !ok {
//			return fmt.Errorf(errmsg.ErrorMsgNotFound)
//		}
//		_, err := v.repo.KindBoxBelongToBenefactor(benefactorID, kbID)
//		if err != nil {
//			return fmt.Errorf(errmsg.ErrorMsgNotFound)
//		}
//
//		return nil
//	}
//}
//
// func (v Validator) hasPendingStatus(value interface{}) error {
//	kindboxID, ok := value.(uint)
//	if !ok {
//		return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
//	}
//	_, err := v.repo.PendingStatus(kindboxID)
//	if err != nil {
//		return fmt.Errorf(errmsg.ErrorMsgNotFound)
//	}
//
//	return nil
//}
