package com.lingniu.ingest.vehiclestat;

import org.junit.jupiter.api.Test;
import org.springframework.test.web.servlet.MockMvc;

import java.time.LocalDate;
import java.util.Optional;
import java.util.OptionalDouble;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;

class VehicleStatControllerTest {

    @Test
    void returnsDailyStatJson() throws Exception {
        InMemoryVehicleStatRepository repository = new InMemoryVehicleStatRepository();
        repository.recordDailyMileageSample("VIN001", LocalDate.parse("2026-06-22"), 100.0);
        repository.recordDailyMileageSample("VIN001", LocalDate.parse("2026-06-22"), 135.5);
        MockMvc mvc = standaloneSetup(new VehicleStatController(repository)).build();

        mvc.perform(get("/api/vehicle-stat/VIN001/daily").param("date", "2026-06-22"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.vin").value("VIN001"))
                .andExpect(jsonPath("$.statDate").value("2026-06-22"))
                .andExpect(jsonPath("$.dailyMileageKm").value(35.5))
                .andExpect(jsonPath("$.dailyMileageStrategy").value("JT808_TOTAL_MILEAGE_DIFF"));
    }

    private static final class InMemoryVehicleStatRepository implements VehicleStatRepository {
        private final java.util.Map<String, VehicleDailyStatResult> results = new java.util.HashMap<>();
        private final java.util.Map<String, Double> firstTotals = new java.util.HashMap<>();

        @Override
        public Optional<VehicleDailyStatResult> recordDailyMileageSample(String vin, LocalDate statDate,
                                                                         double totalMileageKm) {
            String key = vin + ":" + statDate;
            double firstTotal = firstTotals.computeIfAbsent(key, ignored -> totalMileageKm);
            VehicleDailyStatResult result = new VehicleDailyStatResult(
                    vin,
                    statDate,
                    OptionalDouble.of(totalMileageKm - firstTotal),
                    DailyMileageStrategy.JT808_TOTAL_MILEAGE_DIFF);
            results.put(key, result);
            return Optional.of(result);
        }

        @Override
        public Optional<VehicleDailyStatResult> findDailyStat(String vin, LocalDate statDate) {
            return Optional.ofNullable(results.get(vin + ":" + statDate));
        }
    }
}
