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 com.lingniu.ingest.tdenginehistory.TdengineRawFrameQuery;
import com.lingniu.ingest.tdenginehistory.TdengineRawFrameRow;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;

import java.io.IOException;
import java.time.Instant;
import java.util.List;
import java.util.Optional;

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

class Jt808RawFrameHistoryControllerTest {

    @Test
    void queriesRawFramesByPhoneMessageIdAndCursor() throws Exception {
        CapturingReader reader = new CapturingReader(new TdenginePage<>(
                List.of(row("frame-1", "2026-06-29T12:00:01Z")),
                Optional.of(new TdenginePageCursor(Instant.parse("2026-06-29T12:00:01Z"), "frame-1"))));
        Jt808RawFrameHistoryController controller = new Jt808RawFrameHistoryController(reader);

        Jt808RawFrameHistoryController.RawFramePageResponse response = controller.rawFrames(
                "13079963320",
                null,
                null,
                0x0100,
                null,
                "2026-06-29T00:00:00+08:00",
                "2026-06-29T23:59:59+08:00",
                TdengineQueryOrder.DESC,
                20,
                "2026-06-29T12:00:00Z",
                "frame-0");

        assertThat(reader.query.protocol()).isEqualTo("JT808");
        assertThat(reader.query.vehicleKey()).isBlank();
        assertThat(reader.query.phone()).isEqualTo("13079963320");
        assertThat(reader.query.messageId()).isEqualTo(0x0100);
        assertThat(reader.query.cursor()).isEqualTo(new TdenginePageCursor(
                Instant.parse("2026-06-29T12:00:00Z"), "frame-0"));
        assertThat(response.items()).hasSize(1);
        Jt808RawFrameHistoryController.RawFrameResponse item = response.items().getFirst();
        assertThat(item.messageId()).isEqualTo(0x0100);
        assertThat(item.messageIdHex()).isEqualTo("0x0100");
        assertThat(item.metadataJson()).contains("jt808.register.deviceId");
        assertThat(response.nextCursor()).isEqualTo(new Jt808RawFrameHistoryController.CursorResponse(
                "2026-06-29T12:00:01Z", "frame-1"));
    }

    @Test
    void rejectsUnboundedRawFrameQuery() {
        Jt808RawFrameHistoryController controller = new Jt808RawFrameHistoryController(
                new CapturingReader(new TdenginePage<>(List.of(), Optional.empty())));

        assertThatThrownBy(() -> controller.rawFrames(
                null,
                null,
                null,
                null,
                null,
                "2026-06-29",
                "2026-06-29",
                TdengineQueryOrder.DESC,
                20,
                null,
                null))
                .isInstanceOfSatisfying(ResponseStatusException.class, ex ->
                        assertThat(ex.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST));
    }

    private static TdengineRawFrameRow row(String frameId, String ts) {
        Instant instant = Instant.parse(ts);
        return new TdengineRawFrameRow(
                instant,
                frameId,
                instant.plusMillis(500),
                0x0100,
                0,
                instant,
                "archive://2026/06/29/JT808/unknown/" + frameId + ".bin",
                "sha256:" + frameId,
                72,
                "SUCCEEDED",
                "",
                "222.66.200.68:41000",
                "{\"jt808.register.deviceId\":\"9963320\",\"jt808.register.plate\":\"沪A61559F\"}",
                "",
                "JT808",
                "jt808:13079963320",
                "unknown",
                "13079963320");
    }

    private static final class CapturingReader implements TdengineHistoryReader {
        private final TdenginePage<TdengineRawFrameRow> response;
        private TdengineRawFrameQuery query;

        private CapturingReader(TdenginePage<TdengineRawFrameRow> response) {
            this.response = response;
        }

        @Override
        public TdenginePage<TdengineRawFrameRow> queryRawFrames(TdengineRawFrameQuery query) throws IOException {
            this.query = query;
            return response;
        }

        @Override
        public TdenginePage<TdengineLocationRow> queryLocations(TdengineLocationQuery query) {
            throw new UnsupportedOperationException();
        }

    }
}
