package validator

import (
	"apskel-pos-be/internal/constants"
	"apskel-pos-be/internal/contract"
	"fmt"

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

type OutletValidator interface {
	ValidateListOutletsRequest(req *contract.ListOutletsRequest) (error, string)
	ValidateCreateOutletRequest(req *contract.CreateOutletRequest) (error, string)
	ValidateUpdateOutletRequest(req *contract.UpdateOutletRequest) (error, string)
}

type OutletValidatorImpl struct {
	validate *validator.Validate
}

func NewOutletValidator() *OutletValidatorImpl {
	return &OutletValidatorImpl{
		validate: validator.New(),
	}
}

func (v *OutletValidatorImpl) ValidateListOutletsRequest(req *contract.ListOutletsRequest) (error, string) {
	if req.Page < 1 {
		return fmt.Errorf("page must be greater than 0"), constants.MalformedFieldErrorCode
	}

	if req.Limit < 1 {
		return fmt.Errorf("limit must be greater than 0"), constants.MalformedFieldErrorCode
	}

	if req.Limit > 100 {
		return fmt.Errorf("limit cannot exceed 100"), constants.MalformedFieldErrorCode
	}

	if req.BusinessType != nil {
		if err := v.validate.Var(*req.BusinessType, "oneof=restaurant cafe bar fastfood retail"); err != nil {
			return fmt.Errorf("invalid business type"), constants.MalformedFieldErrorCode
		}
	}

	return nil, ""
}

func (v *OutletValidatorImpl) ValidateCreateOutletRequest(req *contract.CreateOutletRequest) (error, string) {
	if err := v.validate.Struct(req); err != nil {
		return err, constants.MalformedFieldErrorCode
	}

	if req.TaxRate < 0 || req.TaxRate > 1 {
		return fmt.Errorf("tax rate must be between 0 and 1"), constants.MalformedFieldErrorCode
	}

	if err := v.validate.Var(req.BusinessType, "oneof=restaurant cafe bar fastfood retail"); err != nil {
		return fmt.Errorf("invalid business type"), constants.MalformedFieldErrorCode
	}

	if err := v.validate.Var(req.Currency, "len=3"); err != nil {
		return fmt.Errorf("currency must be 3 characters"), constants.MalformedFieldErrorCode
	}

	return nil, ""
}

func (v *OutletValidatorImpl) ValidateUpdateOutletRequest(req *contract.UpdateOutletRequest) (error, string) {
	if req.Name != nil {
		if err := v.validate.Var(*req.Name, "required,min=1,max=255"); err != nil {
			return fmt.Errorf("name must be between 1 and 255 characters"), constants.MalformedFieldErrorCode
		}
	}

	if req.Address != nil {
		if err := v.validate.Var(*req.Address, "required,min=1,max=500"); err != nil {
			return fmt.Errorf("address must be between 1 and 500 characters"), constants.MalformedFieldErrorCode
		}
	}

	if req.PhoneNumber != nil {
		if err := v.validate.Var(*req.PhoneNumber, "e164"); err != nil {
			return fmt.Errorf("invalid phone number format"), constants.MalformedFieldErrorCode
		}
	}

	if req.TaxRate != nil {
		if *req.TaxRate < 0 || *req.TaxRate > 1 {
			return fmt.Errorf("tax rate must be between 0 and 1"), constants.MalformedFieldErrorCode
		}
	}

	return nil, ""
}
