package validator

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

	"fmt"

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

type FileValidator interface {
	Validate(interface{}) error
}

type FileValidatorImpl struct {
	validate *validator.Validate
}

func NewFileValidatorImpl() *FileValidatorImpl {
	v := validator.New()

	// Register custom validations
	v.RegisterValidation("file_type", validateFileType)

	return &FileValidatorImpl{
		validate: v,
	}
}

func (v *FileValidatorImpl) Validate(i interface{}) error {
	return v.validate.Struct(i)
}

// Custom validation functions
func validateFileType(fl validator.FieldLevel) bool {
	fileType, ok := fl.Field().Interface().(string)
	if !ok {
		return false
	}
	return constants.IsValidFileType(constants.FileType(fileType))
}

// Specific validation methods for different request types
func (v *FileValidatorImpl) ValidateUploadFileRequest(req *contract.UploadFileRequest) error {
	if req == nil {
		return fmt.Errorf("request cannot be nil")
	}

	// Validate file type
	if req.FileType == "" {
		return fmt.Errorf("file type is required")
	}

	if !constants.IsValidFileType(constants.FileType(req.FileType)) {
		return fmt.Errorf("invalid file type: %s", req.FileType)
	}

	return nil
}

func (v *FileValidatorImpl) ValidateUpdateFileRequest(req *contract.UpdateFileRequest) error {
	if req == nil {
		return fmt.Errorf("request cannot be nil")
	}

	// Additional validation can be added here
	return nil
}

func (v *FileValidatorImpl) ValidateListFilesRequest(req *contract.ListFilesRequest) error {
	if req == nil {
		return fmt.Errorf("request cannot be nil")
	}

	if req.Page < 1 {
		return fmt.Errorf("page must be greater than 0")
	}

	if req.Limit < 1 || req.Limit > 100 {
		return fmt.Errorf("limit must be between 1 and 100")
	}

	// Validate file type if provided
	if req.FileType != nil && !constants.IsValidFileType(constants.FileType(*req.FileType)) {
		return fmt.Errorf("invalid file type: %s", *req.FileType)
	}

	return nil
}
