using BankSampahApp.Models;

namespace BankSampahApp.Services;

/// <summary>
/// Implementation of validation service
/// </summary>
public class ValidationService : IValidationService
{
    /// <inheritdoc/>
    public ValidationResult ValidateStatistics(StatisticsModel statistics)
    {
        if (statistics == null)
            return ValidationResult.Failure("Statistics model is required");

        var errors = new List<string>();

        if (statistics.TotalUsers < 0)
            errors.Add("Total users cannot be negative");

        if (statistics.WasteCollected < 0)
            errors.Add("Waste collected cannot be negative");

        if (statistics.RewardsDistributed < 0)
            errors.Add("Rewards distributed cannot be negative");

        if (statistics.EnvironmentImpact < 0 || statistics.EnvironmentImpact > 100)
            errors.Add("Environment impact must be between 0 and 100");

        return errors.Any() ? ValidationResult.Failure(errors) : ValidationResult.Success();
    }

    /// <inheritdoc/>
    public ValidationResult ValidateFeature(FeatureModel feature)
    {
        if (feature == null)
            return ValidationResult.Failure("Feature model is required");

        var errors = new List<string>();

        var titleValidation = ValidateRequiredString(feature.Title, "Title", 100);
        if (!titleValidation.IsValid)
            errors.AddRange(titleValidation.Errors);

        var descriptionValidation = ValidateRequiredString(feature.Description, "Description", 500);
        if (!descriptionValidation.IsValid)
            errors.AddRange(descriptionValidation.Errors);

        var iconValidation = ValidateRequiredString(feature.Icon, "Icon", 10);
        if (!iconValidation.IsValid)
            errors.AddRange(iconValidation.Errors);

        return errors.Any() ? ValidationResult.Failure(errors) : ValidationResult.Success();
    }

    /// <inheritdoc/>
    public ValidationResult ValidateDateRange(DateTime startDate, DateTime endDate)
    {
        var errors = new List<string>();

        if (startDate > endDate)
            errors.Add("Start date cannot be greater than end date");

        if (startDate > DateTime.UtcNow)
            errors.Add("Start date cannot be in the future");

        if (endDate > DateTime.UtcNow)
            errors.Add("End date cannot be in the future");

        var maxRangeDays = 365; // 1 year maximum
        if ((endDate - startDate).Days > maxRangeDays)
            errors.Add($"Date range cannot exceed {maxRangeDays} days");

        return errors.Any() ? ValidationResult.Failure(errors) : ValidationResult.Success();
    }

    /// <inheritdoc/>
    public ValidationResult ValidateRequiredString(string? value, string fieldName, int maxLength = int.MaxValue)
    {
        var errors = new List<string>();

        if (string.IsNullOrWhiteSpace(value))
            errors.Add($"{fieldName} is required");
        else if (value.Length > maxLength)
            errors.Add($"{fieldName} cannot exceed {maxLength} characters");

        return errors.Any() ? ValidationResult.Failure(errors) : ValidationResult.Success();
    }

    /// <inheritdoc/>
    public ValidationResult ValidateNumericRange(decimal value, string fieldName, decimal minValue = 0, decimal maxValue = decimal.MaxValue)
    {
        var errors = new List<string>();

        if (value < minValue)
            errors.Add($"{fieldName} cannot be less than {minValue}");

        if (value > maxValue)
            errors.Add($"{fieldName} cannot be greater than {maxValue}");

        return errors.Any() ? ValidationResult.Failure(errors) : ValidationResult.Success();
    }
}