package com.njcn.gather.steady.datavie.component;

import com.njcn.gather.steady.datavie.config.SteadyInfluxDbProperties;
import com.njcn.gather.steady.datavie.pojo.bo.SteadyTrendResolvedFieldBO;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;

/**
 * 稳态趋势 InfluxQL 构造契约测试。
 */
class SteadyInfluxQueryComponentTest {

    @Test
    void shouldBuildRawPointQueryWithoutTimeBucketAggregation() {
        SteadyInfluxQueryComponent component = new SteadyInfluxQueryComponent(new SteadyInfluxDbProperties());
        SteadyTrendResolvedFieldBO field = new SteadyTrendResolvedFieldBO();
        field.setMeasurement("data_v");
        field.setField("RMS");
        field.setLineId("line-001");
        field.setPhase("A");

        String query = component.buildTrendQuery(field,
                LocalDateTime.of(2026, 5, 1, 0, 0, 0),
                LocalDateTime.of(2026, 5, 1, 23, 59, 59),
                1);

        Assertions.assertTrue(query.startsWith("SELECT \"RMS\" AS \"value\""), "趋势查询应读取原始字段值");
        Assertions.assertTrue(query.endsWith(" ORDER BY time ASC"), "趋势查询应按原始时间升序返回");
        Assertions.assertFalse(query.contains("mean("), "趋势查询不应按颗粒度聚合");
        Assertions.assertFalse(query.contains("GROUP BY time"), "趋势查询不应生成时间分桶");
    }

    @Test
    void shouldBuildQueryWithActualInfluxTagsAndValueType() {
        SteadyInfluxQueryComponent component = new SteadyInfluxQueryComponent(new SteadyInfluxDbProperties());
        SteadyTrendResolvedFieldBO field = new SteadyTrendResolvedFieldBO();
        field.setMeasurement("data_v");
        field.setField("rms");
        field.setLineId("00B78D00A8791");
        field.setPhase("A");
        field.setStatType("AVG");

        String query = component.buildTrendQuery(field,
                LocalDateTime.of(2026, 5, 1, 0, 0, 0),
                LocalDateTime.of(2026, 5, 1, 23, 59, 59),
                0);

        Assertions.assertTrue(query.contains("\"line_id\" = '00B78D00A8791'"));
        Assertions.assertTrue(query.contains("\"phasic_type\" = 'A'"));
        Assertions.assertTrue(query.contains("\"quality_flag\" = '0'"));
        Assertions.assertTrue(query.contains("\"value_type\" = 'AVG'"));
        Assertions.assertFalse(query.contains("\"LINEID\""));
        Assertions.assertFalse(query.contains("\"PHASIC_TYPE\""));
        Assertions.assertFalse(query.contains("\"QUALITYFLAG\""));
    }

    @Test
    void shouldDefaultValueTypeToUpperAvg() {
        SteadyInfluxQueryComponent component = new SteadyInfluxQueryComponent(new SteadyInfluxDbProperties());
        SteadyTrendResolvedFieldBO field = new SteadyTrendResolvedFieldBO();
        field.setMeasurement("data_v");
        field.setField("rms");
        field.setLineId("0798e5a9a72ebbc4daaa4a631701c813");
        field.setPhase("A");

        String query = component.buildTrendQuery(field,
                LocalDateTime.of(2026, 5, 1, 0, 0, 0),
                LocalDateTime.of(2026, 5, 1, 23, 59, 59),
                0);

        Assertions.assertTrue(query.contains("\"value_type\" = 'AVG'"));
    }

    @Test
    void shouldBuildDiagnosticTextForTrendQuery() {
        SteadyInfluxQueryComponent component = new SteadyInfluxQueryComponent(new SteadyInfluxDbProperties());
        SteadyTrendResolvedFieldBO field = new SteadyTrendResolvedFieldBO();
        field.setMeasurement("data_harmpower_p");
        field.setField("p_3");
        field.setLineId("f828bc42132841c2aeebc6859f5a9b7c");
        field.setPhase("A");
        field.setStatType("AVG");

        String diagnostic = component.buildTrendQueryDiagnostic(field,
                LocalDateTime.of(2026, 5, 1, 0, 0, 0),
                LocalDateTime.of(2026, 5, 31, 23, 59, 59),
                0);

        Assertions.assertTrue(diagnostic.contains("measurement=data_harmpower_p"));
        Assertions.assertTrue(diagnostic.contains("field=p_3"));
        Assertions.assertTrue(diagnostic.contains("lineId=f828bc42132841c2aeebc6859f5a9b7c"));
        Assertions.assertTrue(diagnostic.contains("phase=A"));
        Assertions.assertTrue(diagnostic.contains("statType=AVG"));
        Assertions.assertTrue(diagnostic.contains("qualityFlag=0"));
        Assertions.assertTrue(diagnostic.contains("timeStart=2026-05-01T00:00"));
        Assertions.assertTrue(diagnostic.contains("timeEnd=2026-05-31T23:59:59"));
    }

    @Test
    void shouldSkipValueTypeWhenMeasurementHasNoValueTypeTag() {
        SteadyInfluxQueryComponent component = new SteadyInfluxQueryComponent(new SteadyInfluxDbProperties());
        SteadyTrendResolvedFieldBO field = new SteadyTrendResolvedFieldBO();
        field.setMeasurement("data_fluc");
        field.setField("fluc");
        field.setLineId("0798e5a9a72ebbc4daaa4a631701c813");
        field.setPhase("T");
        field.setStatType("AVG");

        String query = component.buildTrendQuery(field,
                LocalDateTime.of(2026, 5, 1, 0, 0, 0),
                LocalDateTime.of(2026, 5, 1, 23, 59, 59),
                0);

        Assertions.assertFalse(query.contains("\"value_type\""));
        Assertions.assertTrue(query.contains("\"quality_flag\" = '0'"));
    }
}
