package com.social.media.domain.shared;

import java.util.Objects;

/**
 * Base abstract class for all Value Objects.
 * 
 * Provides common functionality for value objects including:
 * - Immutability contract
 * - Value-based equality
 * - Validation support
 * 
 * @author Social Media Manager Team
 * @version 2.0
 * @since 2025-01-01
 */
public abstract class BaseValueObject implements ValueObject {
    
    /**
     * Protected constructor to enforce immutability.
     * Subclasses should validate input in their constructors.
     */
    protected BaseValueObject() {
        validate();
    }
    
    /**
     * Validates the value object state.
     * Override in subclasses to implement specific validation rules.
     * 
     * @throws IllegalArgumentException if the value object is invalid
     */
    @Override
    public void validate() {
        // Default implementation does nothing
    }
    
    /**
     * Utility method to validate that a string is not null or empty.
     * 
     * @param value the string to validate
     * @param fieldName the name of the field for error messages
     * @throws IllegalArgumentException if the string is null or empty
     */
    protected void validateNotEmpty(String value, String fieldName) {
        if (value == null || value.trim().isEmpty()) {
            throw new IllegalArgumentException(fieldName + " cannot be null or empty");
        }
    }
    
    /**
     * Utility method to validate that an object is not null.
     * 
     * @param value the object to validate
     * @param fieldName the name of the field for error messages
     * @throws IllegalArgumentException if the object is null
     */
    protected void validateNotNull(Object value, String fieldName) {
        if (value == null) {
            throw new IllegalArgumentException(fieldName + " cannot be null");
        }
    }
    
    /**
     * Utility method to validate that a number is positive.
     * 
     * @param value the number to validate
     * @param fieldName the name of the field for error messages
     * @throws IllegalArgumentException if the number is not positive
     */
    protected void validatePositive(Number value, String fieldName) {
        if (value == null || value.doubleValue() <= 0) {
            throw new IllegalArgumentException(fieldName + " must be positive");
        }
    }
    
    /**
     * Utility method to validate that a number is non-negative.
     * 
     * @param value the number to validate
     * @param fieldName the name of the field for error messages
     * @throws IllegalArgumentException if the number is negative
     */
    protected void validateNonNegative(Number value, String fieldName) {
        if (value == null || value.doubleValue() < 0) {
            throw new IllegalArgumentException(fieldName + " cannot be negative");
        }
    }
    
    @Override
    public abstract boolean equals(Object obj);
    
    @Override
    public abstract int hashCode();
    
    @Override
    public abstract String toString();
}
