package com.lingniu.ingest.eventhistory;

import com.lingniu.ingest.tdenginehistory.TdengineHistoryReader;
import com.lingniu.ingest.tdenginehistory.TdengineLocationQuery;
import com.lingniu.ingest.tdenginehistory.TdengineLocationRow;
import com.lingniu.ingest.tdenginehistory.TdenginePage;
import com.lingniu.ingest.tdenginehistory.TdenginePageCursor;
import com.lingniu.ingest.tdenginehistory.TdengineQueryOrder;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;

import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

class LocationHistoryControllerTest {

    @Test
    void queriesGenericLocationHistoryWithCursor() throws Exception {
        AtomicReference<TdengineLocationQuery> captured = new AtomicReference<>();
        TdengineHistoryReader reader = new StubReader(captured, new TdenginePage<>(
                List.of(row("fact-1")),
                Optional.of(new TdenginePageCursor(Instant.parse("2026-06-29T05:00:01Z"), "fact-1"))));
        LocationHistoryController controller = new LocationHistoryController(reader);

        LocationHistoryController.LocationPageResponse response = controller.locations(
                "mqtt_yutong",
                null,
                "LMRKH9AC2R1004087",
                null,
                "2026-06-29T13:00:00",
                "2026-06-29T13:10:00",
                TdengineQueryOrder.DESC,
                100,
                null,
                null);

        assertThat(captured.get().protocol()).isEqualTo("MQTT_YUTONG");
        assertThat(captured.get().vehicleKey()).isEqualTo("LMRKH9AC2R1004087");
        assertThat(response.items()).extracting(LocationHistoryController.LocationResponse::factId)
                .containsExactly("fact-1");
        assertThat(response.nextCursor()).isEqualTo(new LocationHistoryController.CursorResponse(
                "2026-06-29T05:00:01Z", "fact-1"));
    }

    @Test
    void mapsJt808PhoneToVehicleKey() throws Exception {
        AtomicReference<TdengineLocationQuery> captured = new AtomicReference<>();
        LocationHistoryController controller = new LocationHistoryController(
                new StubReader(captured, new TdenginePage<>(List.of(), null)));

        controller.locations(
                "JT808",
                null,
                null,
                "g7gps",
                "2026-06-29T13:00:00",
                "2026-06-29T13:10:00",
                TdengineQueryOrder.DESC,
                100,
                null,
                null);

        assertThat(captured.get().vehicleKey()).isEqualTo("jt808:g7gps");
    }

    @Test
    void rejectsLegacyXindaProtocolOnDefaultLocationApi() {
        AtomicReference<TdengineLocationQuery> captured = new AtomicReference<>();
        LocationHistoryController controller = new LocationHistoryController(
                new StubReader(captured, new TdenginePage<>(List.of(), null)));

        assertThatThrownBy(() -> controller.locations(
                "XINDA_PUSH",
                null,
                "LB9A32A24P0LS1270",
                null,
                "2026-06-29T13:00:00",
                "2026-06-29T13:10:00",
                TdengineQueryOrder.DESC,
                100,
                null,
                null))
                .isInstanceOfSatisfying(ResponseStatusException.class, ex ->
                        assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST));
        assertThat(captured).hasValue(null);
    }

    private static TdengineLocationRow row(String factId) {
        Instant ts = Instant.parse("2026-06-29T05:00:00Z");
        return new TdengineLocationRow(
                ts,
                factId,
                "frame-1",
                ts,
                121.1,
                30.5,
                0.0,
                32.0,
                90.0,
                0,
                1,
                null,
                "",
                "MQTT_YUTONG",
                "LMRKH9AC2R1004087",
                "LMRKH9AC2R1004087",
                "");
    }

    private record StubReader(AtomicReference<TdengineLocationQuery> captured,
                              TdenginePage<TdengineLocationRow> page) implements TdengineHistoryReader {

        @Override
        public com.lingniu.ingest.tdenginehistory.TdenginePage<com.lingniu.ingest.tdenginehistory.TdengineRawFrameRow> queryRawFrames(
                com.lingniu.ingest.tdenginehistory.TdengineRawFrameQuery query) {
            throw new UnsupportedOperationException();
        }

        @Override
        public TdenginePage<TdengineLocationRow> queryLocations(TdengineLocationQuery query) {
            captured.set(query);
            return page;
        }

    }
}
