package nodomain.freeyourgadget.gadgetbridge.devices.cmfwatchpro.workout;

import org.junit.Test;

import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryData;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries;
import nodomain.freeyourgadget.gadgetbridge.test.TestBase;
import nodomain.freeyourgadget.gadgetbridge.util.GB;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class CmfWorkoutSummaryParserTest extends TestBase {
    @Test
    public void testParseSummary_v1_2() {
        // From https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/4530
        final byte[] bytes = GB.hexStringToByteArray("9F7734685D02039D8B0008060000FA0500007B01000000000000057A346800001B0064000000B40001000100000006000000401F0000");

        final CmfWorkoutSummaryParser parser = new CmfWorkoutSummaryParser(null, getContext(), 1);
        final BaseActivitySummary summary = new BaseActivitySummary();
        summary.setRawSummaryData(bytes);
        parser.parseBinaryData(summary, false);

        assertEquals(1748268959000L, summary.getStartTime().getTime());
        assertEquals(1748269573000L, summary.getEndTime().getTime());
        assertEquals(ActivityKind.INDOOR_RUNNING.getCode(), summary.getActivityKind());

        final ActivitySummaryData summaryData = ActivitySummaryData.fromJson(summary.getSummaryData());
        assertNotNull(summaryData);

        assertEquals(1530d, summaryData.getNumber(ActivitySummaryEntries.DISTANCE_METERS, -1));
        assertEquals(605d, summaryData.getNumber(ActivitySummaryEntries.ACTIVE_SECONDS, -1));
        assertEquals(139d, summaryData.getNumber(ActivitySummaryEntries.CALORIES_BURNT, -1));

        // TODO max pace 6'23''
        // TODO avg speed 6.50kmph
        assertEquals(6d * 60 + 19, summaryData.getNumber(ActivitySummaryEntries.PACE_AVG_SECONDS_KM, -1)); // 6'19"

        assertEquals(1544d, summaryData.getNumber(ActivitySummaryEntries.STEPS, -1));

        // TODO avg step rate 151 steps/min
        // TODO avg step stride 102cm

        assertEquals(157d, summaryData.getNumber(ActivitySummaryEntries.HR_AVG, -1));

        // TODO max hr 190

        assertEquals(1 * 60d, summaryData.getNumber(ActivitySummaryEntries.HR_ZONE_WARM_UP, -1)); // 1 min
        assertEquals(1 * 60d, summaryData.getNumber(ActivitySummaryEntries.HR_ZONE_FAT_BURN, -1)); // 1 min
        assertEquals(0d, summaryData.getNumber(ActivitySummaryEntries.HR_ZONE_AEROBIC, -1)); // 0 min
        assertEquals(6 * 60d, summaryData.getNumber(ActivitySummaryEntries.HR_ZONE_ANAEROBIC, -1)); // 6 min

        assertEquals(1.0d, summaryData.getNumber(ActivitySummaryEntries.TRAINING_EFFECT_AEROBIC, -1)); // 1.0 / relaxed

        assertEquals(27d, summaryData.getNumber(ActivitySummaryEntries.TRAINING_LOAD, -1));
        assertEquals(3 * 60 * 60d, summaryData.getNumber(ActivitySummaryEntries.RECOVERY_TIME, -1)); // 3h
        assertEquals(8d, summaryData.getNumber(ActivitySummaryEntries.ACTIVE_SCORE, -1)); // +8
    }

    @Test
    public void testParseSummary_v1_3() {
        // From https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/4530
        final byte[] bytes = GB.hexStringToByteArray("ec153769380e02afe8039d250000e222000097010000000000002524376901006400e000f401310d0000000001002b000e00281d0100");

        final CmfWorkoutSummaryParser parser = new CmfWorkoutSummaryParser(null, getContext(), 1);
        final BaseActivitySummary summary = new BaseActivitySummary();
        summary.setRawSummaryData(bytes);
        parser.parseBinaryData(summary, false);

        final long durationSeconds = 3600 + 40; // 01:00:40
        assertEquals(1765217772000L, summary.getStartTime().getTime()); // 2025-12-08 19:16
        assertEquals(summary.getStartTime().getTime() + durationSeconds * 1000L + 1000L /* FIXME why +1? */, summary.getEndTime().getTime());
        assertEquals(ActivityKind.OUTDOOR_RUNNING.getCode(), summary.getActivityKind());

        final ActivitySummaryData summaryData = ActivitySummaryData.fromJson(summary.getSummaryData());
        assertNotNull(summaryData);

        assertEquals(8930d, summaryData.getNumber(ActivitySummaryEntries.DISTANCE_METERS, -1)); // 8.93km
        assertEquals((double) durationSeconds, summaryData.getNumber(ActivitySummaryEntries.ACTIVE_SECONDS, -1));
        assertEquals(1000d, summaryData.getNumber(ActivitySummaryEntries.CALORIES_BURNT, -1));

        // TODO max pace 6‘12“
        // TODO avg speed 8.83kmph
        assertEquals(6d * 60 + 47, summaryData.getNumber(ActivitySummaryEntries.PACE_AVG_SECONDS_KM, -1)); // 6‘47“

        assertEquals(9629d, summaryData.getNumber(ActivitySummaryEntries.STEPS, -1));

        // TODO avg step rate 158 steps/min
        // TODO avg step stride  	92cm

        assertEquals(175d, summaryData.getNumber(ActivitySummaryEntries.HR_AVG, -1));

        // TODO max hr 194

        assertEquals(0d, summaryData.getNumber(ActivitySummaryEntries.HR_ZONE_WARM_UP, -1)); // N/A
        assertEquals(0d, summaryData.getNumber(ActivitySummaryEntries.HR_ZONE_FAT_BURN, -1)); // 0 min
        assertEquals(1 * 60d, summaryData.getNumber(ActivitySummaryEntries.HR_ZONE_AEROBIC, -1)); // 1 min
        assertEquals(43 * 60d, summaryData.getNumber(ActivitySummaryEntries.HR_ZONE_ANAEROBIC, -1)); // 43 min
        assertEquals(14 * 60d, summaryData.getNumber(ActivitySummaryEntries.HR_ZONE_MAXIMUM, -1)); // 14 min

        assertEquals(2.24d, summaryData.getNumber(ActivitySummaryEntries.TRAINING_EFFECT_AEROBIC, -1)); // 2.2 / foundation
        assertEquals(5.0d, summaryData.getNumber(ActivitySummaryEntries.TRAINING_EFFECT_ANAEROBIC, -1)); // 5.0 / ultimate

        assertEquals(100d, summaryData.getNumber(ActivitySummaryEntries.TRAINING_LOAD, -1));
        assertEquals(56 * 60 * 60d + 17 * 60d, summaryData.getNumber(ActivitySummaryEntries.RECOVERY_TIME, -1)); // 56.3h
        assertEquals(73d, summaryData.getNumber(ActivitySummaryEntries.ACTIVE_SCORE, -1)); // +73
    }

    @Test
    public void testParseSummary_v3_1() {
        // From https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/4530
        final byte[] bytes = GB.hexStringToByteArray("f3459269ad469269b8000000134b0100000000000a0000000000000000000000000000000000000000000302000000000000000000000000");
        final CmfWorkoutSummaryParser parser = new CmfWorkoutSummaryParser(null, getContext(), 3);
        final BaseActivitySummary summary = new BaseActivitySummary();
        summary.setRawSummaryData(bytes);
        parser.parseBinaryData(summary, true);
    }

    @Test
    public void testParseSummary_v3_2() {
        // From https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/4530
        final byte[] bytes = GB.hexStringToByteArray("70A39369C6A3936954000000135C0200000000000A0000000000000000000000000000004401000000000306000000000000000000000000");
        final CmfWorkoutSummaryParser parser = new CmfWorkoutSummaryParser(null, getContext(), 3);
        final BaseActivitySummary summary = new BaseActivitySummary();
        summary.setRawSummaryData(bytes);
        parser.parseBinaryData(summary, true);
    }
}
