package com.example.weighttracker;

import java.util.List;
import java.util.Locale;

// This class handles the algorithmic part of the weight tracker.
// It loops through the saved entries once, so the time complexity is O(n).
public class WeightStats {

    private final boolean hasEntries;
    private final double startingWeight;
    private final double currentWeight;
    private final double totalChange;
    private final double highestWeight;
    private final double lowestWeight;
    private final Double goalWeight;

    private WeightStats(
            boolean hasEntries,
            double startingWeight,
            double currentWeight,
            double totalChange,
            double highestWeight,
            double lowestWeight,
            Double goalWeight
    ) {
        this.hasEntries = hasEntries;
        this.startingWeight = startingWeight;
        this.currentWeight = currentWeight;
        this.totalChange = totalChange;
        this.highestWeight = highestWeight;
        this.lowestWeight = lowestWeight;
        this.goalWeight = goalWeight;
    }

    // Analyzes the full list of saved weights and returns one summary object.
    public static WeightStats calculate(List<WeightEntry> entries, Double goalWeight) {
        if (entries == null || entries.isEmpty()) {
            return new WeightStats(false, 0, 0, 0, 0, 0, goalWeight);
        }

        double startingWeight = entries.get(0).getWeight();
        double currentWeight = entries.get(entries.size() - 1).getWeight();
        double highestWeight = startingWeight;
        double lowestWeight = startingWeight;

        for (WeightEntry entry : entries) {
            double weight = entry.getWeight();

            if (weight > highestWeight) {
                highestWeight = weight;
            }

            if (weight < lowestWeight) {
                lowestWeight = weight;
            }
        }

        double totalChange = currentWeight - startingWeight;

        return new WeightStats(
                true,
                startingWeight,
                currentWeight,
                totalChange,
                highestWeight,
                lowestWeight,
                goalWeight
        );
    }

    // Creates the text shown on the screen.
    public String getDisplayText() {
        if (!hasEntries) {
            return "Progress Summary\nNo weight entries yet.";
        }

        StringBuilder summary = new StringBuilder();

        summary.append("Progress Summary\n");
        summary.append("Starting Weight: ").append(format(startingWeight)).append(" lbs\n");
        summary.append("Current Weight: ").append(format(currentWeight)).append(" lbs\n");
        summary.append("Total Change: ").append(format(totalChange)).append(" lbs\n");
        summary.append("Highest Weight: ").append(format(highestWeight)).append(" lbs\n");
        summary.append("Lowest Weight: ").append(format(lowestWeight)).append(" lbs\n");
        summary.append("Goal Progress: ").append(getGoalProgressText());

        return summary.toString();
    }

    private String getGoalProgressText() {
        if (goalWeight == null) {
            return "No goal set";
        }

        double difference = currentWeight - goalWeight;

        if (difference == 0) {
            return "At goal weight";
        }

        if (difference > 0) {
            return format(difference) + " lbs above goal";
        }

        return format(Math.abs(difference)) + " lbs below goal";
    }

    private String format(double value) {
        return String.format(Locale.US, "%.1f", value);
    }
}