package validator

import (
	"errors"
	"strings"

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

	"github.com/google/uuid"
)

type ProductValidator interface {
	ValidateCreateProductRequest(req *contract.CreateProductRequest) (error, string)
	ValidateUpdateProductRequest(req *contract.UpdateProductRequest) (error, string)
	ValidateListProductsRequest(req *contract.ListProductsRequest) (error, string)
}

type ProductValidatorImpl struct{}

func NewProductValidator() *ProductValidatorImpl {
	return &ProductValidatorImpl{}
}

func (v *ProductValidatorImpl) ValidateCreateProductRequest(req *contract.CreateProductRequest) (error, string) {
	if req == nil {
		return errors.New("request body is required"), constants.MissingFieldErrorCode
	}

	if req.CategoryID == uuid.Nil {
		return errors.New("category_id is required"), constants.MissingFieldErrorCode
	}

	if strings.TrimSpace(req.Name) == "" {
		return errors.New("name is required"), constants.MissingFieldErrorCode
	}

	if len(req.Name) < 1 || len(req.Name) > 255 {
		return errors.New("name must be between 1 and 255 characters"), constants.MalformedFieldErrorCode
	}

	if req.Price < 0 {
		return errors.New("price must be non-negative"), constants.MalformedFieldErrorCode
	}

	if req.Cost != nil && *req.Cost < 0 {
		return errors.New("cost must be non-negative"), constants.MalformedFieldErrorCode
	}

	if req.SKU != nil && len(*req.SKU) > 100 {
		return errors.New("sku cannot exceed 100 characters"), constants.MalformedFieldErrorCode
	}

	if req.Description != nil && len(*req.Description) > 1000 {
		return errors.New("description cannot exceed 1000 characters"), constants.MalformedFieldErrorCode
	}

	if req.ImageURL != nil && len(*req.ImageURL) > 500 {
		return errors.New("image_url cannot exceed 500 characters"), constants.MalformedFieldErrorCode
	}

	if req.PrinterType != nil && len(*req.PrinterType) > 50 {
		return errors.New("printer_type cannot exceed 50 characters"), constants.MalformedFieldErrorCode
	}

	return nil, ""
}

func (v *ProductValidatorImpl) ValidateUpdateProductRequest(req *contract.UpdateProductRequest) (error, string) {
	if req == nil {
		return errors.New("request body is required"), constants.MissingFieldErrorCode
	}

	// At least one field should be provided for update
	if req.CategoryID == nil && req.SKU == nil && req.Name == nil && req.Description == nil &&
		req.Price == nil && req.Cost == nil && req.BusinessType == nil && req.ImageURL == nil &&
		req.PrinterType == nil && req.Metadata == nil && req.IsActive == nil {
		return errors.New("at least one field must be provided for update"), constants.MissingFieldErrorCode
	}

	if req.Name != nil {
		if strings.TrimSpace(*req.Name) == "" {
			return errors.New("name cannot be empty"), constants.MalformedFieldErrorCode
		}
		if len(*req.Name) < 1 || len(*req.Name) > 255 {
			return errors.New("name must be between 1 and 255 characters"), constants.MalformedFieldErrorCode
		}
	}

	if req.Price != nil && *req.Price < 0 {
		return errors.New("price must be non-negative"), constants.MalformedFieldErrorCode
	}

	if req.Cost != nil && *req.Cost < 0 {
		return errors.New("cost must be non-negative"), constants.MalformedFieldErrorCode
	}

	if req.SKU != nil && len(*req.SKU) > 100 {
		return errors.New("sku cannot exceed 100 characters"), constants.MalformedFieldErrorCode
	}

	if req.Description != nil && len(*req.Description) > 1000 {
		return errors.New("description cannot exceed 1000 characters"), constants.MalformedFieldErrorCode
	}

	if req.ImageURL != nil && len(*req.ImageURL) > 500 {
		return errors.New("image_url cannot exceed 500 characters"), constants.MalformedFieldErrorCode
	}

	if req.PrinterType != nil && len(*req.PrinterType) > 50 {
		return errors.New("printer_type cannot exceed 50 characters"), constants.MalformedFieldErrorCode
	}

	return nil, ""
}

func (v *ProductValidatorImpl) ValidateListProductsRequest(req *contract.ListProductsRequest) (error, string) {
	if req == nil {
		return errors.New("request is required"), constants.MissingFieldErrorCode
	}

	if req.Page < 1 {
		return errors.New("page must be at least 1"), constants.MalformedFieldErrorCode
	}

	if req.Limit < 1 || req.Limit > 100 {
		return errors.New("limit must be between 1 and 100"), constants.MalformedFieldErrorCode
	}

	if req.MinPrice != nil && *req.MinPrice < 0 {
		return errors.New("min_price must be non-negative"), constants.MalformedFieldErrorCode
	}

	if req.MaxPrice != nil && *req.MaxPrice < 0 {
		return errors.New("max_price must be non-negative"), constants.MalformedFieldErrorCode
	}

	if req.MinPrice != nil && req.MaxPrice != nil && *req.MinPrice > *req.MaxPrice {
		return errors.New("min_price cannot be greater than max_price"), constants.MalformedFieldErrorCode
	}

	return nil, ""
}
