package validator

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

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

type AccountValidator interface {
	ValidateCreateAccount(req *models.CreateAccountRequest) error
	ValidateUpdateAccount(req *models.UpdateAccountRequest) error
}

type AccountValidatorImpl struct {
	validator *validator.Validate
}

func NewAccountValidator() AccountValidator {
	return &AccountValidatorImpl{
		validator: validator.New(),
	}
}

func (v *AccountValidatorImpl) ValidateCreateAccount(req *models.CreateAccountRequest) 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.Number) == "" {
		return fmt.Errorf("number cannot be empty")
	}

	// Validate account type
	if !isValidAccountType(req.AccountType) {
		return fmt.Errorf("invalid account type")
	}

	// Validate number format (alphanumeric)
	if !isValidAccountNumberFormat(req.Number) {
		return fmt.Errorf("number must be alphanumeric")
	}

	return nil
}

func (v *AccountValidatorImpl) ValidateUpdateAccount(req *models.UpdateAccountRequest) 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.Number != nil && strings.TrimSpace(*req.Number) == "" {
		return fmt.Errorf("number cannot be empty")
	}

	// Validate account type if provided
	if req.AccountType != nil && !isValidAccountType(*req.AccountType) {
		return fmt.Errorf("invalid account type")
	}

	// Validate number format if provided
	if req.Number != nil && !isValidAccountNumberFormat(*req.Number) {
		return fmt.Errorf("number must be alphanumeric")
	}

	return nil
}

func isValidAccountType(accountType string) bool {
	validTypes := []string{"cash", "wallet", "bank", "credit", "debit", "asset", "liability", "equity", "revenue", "expense"}
	for _, validType := range validTypes {
		if accountType == validType {
			return true
		}
	}
	return false
}

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