package validator

import (
	"apskel-pos-be/internal/models"
	"fmt"
	"strings"

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

type ChartOfAccountValidator interface {
	ValidateCreateChartOfAccount(req *models.CreateChartOfAccountRequest) error
	ValidateUpdateChartOfAccount(req *models.UpdateChartOfAccountRequest) error
}

type ChartOfAccountValidatorImpl struct {
	validator *validator.Validate
}

func NewChartOfAccountValidator() ChartOfAccountValidator {
	return &ChartOfAccountValidatorImpl{
		validator: validator.New(),
	}
}

func (v *ChartOfAccountValidatorImpl) ValidateCreateChartOfAccount(req *models.CreateChartOfAccountRequest) error {
	if err := v.validator.Struct(req); err != nil {
		return err
	}

	// Additional custom validations
	if strings.TrimSpace(req.Name) == "" {
		return fmt.Errorf("name cannot be empty")
	}

	if strings.TrimSpace(req.Code) == "" {
		return fmt.Errorf("code cannot be empty")
	}

	// Validate code format (alphanumeric)
	if !isValidAccountCodeFormat(req.Code) {
		return fmt.Errorf("code must be alphanumeric")
	}

	return nil
}

func (v *ChartOfAccountValidatorImpl) ValidateUpdateChartOfAccount(req *models.UpdateChartOfAccountRequest) error {
	if err := v.validator.Struct(req); err != nil {
		return err
	}

	// Additional custom validations
	if req.Name != nil && strings.TrimSpace(*req.Name) == "" {
		return fmt.Errorf("name cannot be empty")
	}

	if req.Code != nil && strings.TrimSpace(*req.Code) == "" {
		return fmt.Errorf("code cannot be empty")
	}

	// Validate code format if provided
	if req.Code != nil && !isValidAccountCodeFormat(*req.Code) {
		return fmt.Errorf("code must be alphanumeric")
	}

	return nil
}

func isValidAccountCodeFormat(code string) bool {
	// Check if code is alphanumeric
	for _, char := range code {
		if !((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z') || (char >= '0' && char <= '9')) {
			return false
		}
	}
	return true
}
