package com.foxx.androidcast.stats.ui;

/*********************************************************************
 * ChartTickHelper.java
 * Created at: Tue 19 May 2026 19:43:06 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (2 commits, 85 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	f53b085b914a3ffd3aeaf98331f60e838dae2ff7428627d0bbb7e2788c5b3836
**********************************************************************/
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/** Nice axis ticks for session charts. */
final class ChartTickHelper {
    private ChartTickHelper() {}

    static final class Tick {
        final double value;
        final String label;

        Tick(double value, String label) {
            this.value = value;
            this.label = label;
        }
    }

    static List<Tick> linear(double min, double max, int maxTicks) {
        List<Tick> out = new ArrayList<>();
        if (!Double.isFinite(min) || !Double.isFinite(max) || max <= min) {
            return out;
        }
        double step = niceStep(max - min, maxTicks);
        double start = Math.ceil(min / step) * step;
        for (double v = start; v <= max + step * 0.001; v += step) {
            out.add(new Tick(v, formatValue(v, step)));
        }
        return out;
    }

    static List<Tick> timeMs(long minMs, long maxMs, int maxTicks) {
        List<Tick> out = new ArrayList<>();
        if (maxMs <= minMs) {
            return out;
        }
        double range = maxMs - minMs;
        double step = niceStep(range, maxTicks);
        double start = Math.ceil(minMs / step) * step;
        for (double v = start; v <= maxMs + step * 0.001; v += step) {
            long ms = Math.round(v);
            out.add(new Tick(ms, formatTimeMs(ms)));
        }
        return out;
    }

    private static double niceStep(double range, int maxTicks) {
        double raw = range / Math.max(2, maxTicks);
        if (raw <= 0) {
            return 1;
        }
        double mag = Math.pow(10, Math.floor(Math.log10(raw)));
        double norm = raw / mag;
        double nice = norm <= 1 ? 1 : norm <= 2 ? 2 : norm <= 5 ? 5 : 10;
        return nice * mag;
    }

    private static String formatValue(double v, double step) {
        if (step >= 1) {
            return String.format(Locale.US, "%.0f", v);
        }
        if (step >= 0.1) {
            return String.format(Locale.US, "%.1f", v);
        }
        return String.format(Locale.US, "%.2f", v);
    }

    private static String formatTimeMs(long ms) {
        if (ms >= 60_000) {
            return String.format(Locale.US, "%.1fm", ms / 60_000.0);
        }
        if (ms >= 1000) {
            return String.format(Locale.US, "%.1fs", ms / 1000.0);
        }
        return ms + "ms";
    }
}
