package com.purui.prims;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.purui.prims.auth.api.authentication.pojo.User;
import com.purui.prims.common.pojo.Constants;
import com.purui.prims.common.pojo.DateConf;
import com.purui.prims.common.pojo.Filter;
import com.purui.prims.common.pojo.enums.FilterOperatorEnum;
import com.purui.prims.headless.api.pojo.request.QueryMetricReq;
import com.purui.prims.headless.api.pojo.request.QueryStructReq;
import com.purui.prims.headless.api.pojo.response.SemanticQueryResp;
import com.purui.prims.headless.server.service.MetricService;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.assertThrows;

public class QueryByMetricTest extends BaseTest {

    @Autowired
    protected MetricService metricService;

    @Test
    public void testWithMetricAndDimensionBizNames() throws Exception {
        QueryMetricReq queryMetricReq = new QueryMetricReq();
        queryMetricReq.setMetricNames(Arrays.asList("stay_hours", "pv"));
        queryMetricReq.setDimensionNames(Arrays.asList("user_name", "department"));
        SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getFakeUser());
        Assert.assertNotNull(queryResp.getResultList());
        Assert.assertEquals(6, queryResp.getResultList().size());
    }

    @Test
    public void testWithMetricAndDimensionNames() throws Exception {
        QueryMetricReq queryMetricReq = new QueryMetricReq();
        queryMetricReq.setMetricNames(Arrays.asList("停留时长", "访问次数"));
        queryMetricReq.setDimensionNames(Arrays.asList("用户", "部门"));
        SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getFakeUser());
        Assert.assertNotNull(queryResp.getResultList());
        Assert.assertEquals(6, queryResp.getResultList().size());
    }

    @Test
    public void testWithDomainId() throws Exception {
        QueryMetricReq queryMetricReq = new QueryMetricReq();
        queryMetricReq.setDomainId(1L);
        queryMetricReq.setMetricNames(Arrays.asList("stay_hours", "pv"));
        queryMetricReq.setDimensionNames(Arrays.asList("user_name", "department"));
        SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getFakeUser());
        Assert.assertNotNull(queryResp.getResultList());
        Assert.assertEquals(6, queryResp.getResultList().size());

        queryMetricReq.setDomainId(3L);
        queryMetricReq.setMetricNames(Arrays.asList("stay_hours", "pv"));
        queryMetricReq.setDimensionNames(Arrays.asList("user_name", "department"));
        assertThrows(IllegalArgumentException.class,
                () -> queryByMetric(queryMetricReq, User.getFakeUser()));
    }

    @Test
    public void testWithMetricAndDimensionIds() throws Exception {
        QueryMetricReq queryMetricReq = new QueryMetricReq();
        queryMetricReq.setDomainId(1L);
        queryMetricReq.setMetricIds(Arrays.asList(1L, 3L));
        queryMetricReq.setDimensionIds(Arrays.asList(1L, 2L));
        SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getFakeUser());
        Assert.assertNotNull(queryResp.getResultList());
        Assert.assertEquals(6, queryResp.getResultList().size());
    }

    private SemanticQueryResp queryByMetric(QueryMetricReq queryMetricReq, User user) throws Exception {
        QueryStructReq convert = metricService.convert(queryMetricReq);
        return semanticLayerService.queryByReq(convert.convert(true), user);
    }


    @Test
    void queryMetric() throws Exception {
        QueryMetricReq queryMetricReq = new QueryMetricReq();
        queryMetricReq.setDomainId(10L);
        queryMetricReq.setMetricIds(Lists.newArrayList(55L));
        queryMetricReq.setDimensionIds(Lists.newArrayList(190L,200L));
        queryMetricReq.setLimit(100L);
        DateConf dateConf = new DateConf();
        dateConf.setUnit(3);
        dateConf.setPeriod(Constants.MONTH);
        dateConf.setDateMode(DateConf.DateMode.BETWEEN);
        dateConf.setStartDate("2024-07-01");
        dateConf.setEndDate("2024-09-03");
        dateConf.setGroupByDate(true);
        queryMetricReq.setDateInfo(dateConf);
        // 查询条件
        List<Filter> filters = Lists.newArrayList();
        Filter filter = new Filter("test_modal_HospitalName", FilterOperatorEnum.EQUALS, "成都普瑞眼科医院");
        filters.add(filter);
        queryMetricReq.setFilters(filters);

        SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getFakeUser());

        Assert.assertNotNull(queryResp.getResultList());
    }

    @Test
    void queryMonthMetric() throws Exception {
        QueryMetricReq queryMetricReq = new QueryMetricReq();
        queryMetricReq.setDomainId(10L);
        queryMetricReq.setMetricIds(Lists.newArrayList(30L));
        queryMetricReq.setLimit(1000L);
        DateConf dateConf = new DateConf();
        dateConf.setUnit(7);
        dateConf.setPeriod(Constants.DAY);
        dateConf.setDateMode(DateConf.DateMode.BETWEEN);
        dateConf.setEndDate("2024-07-01");
        dateConf.setEndDate("2024-08-31");
        dateConf.setGroupByDate(true);
        queryMetricReq.setDateInfo(dateConf);
        System.out.println(JSON.toJSONString(queryMetricReq));
        SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getFakeUser());
        System.out.println(JSON.toJSONString(queryResp));
        Assert.assertNotNull(queryResp);
    }

    @Test
    void queryCompositeMetric() throws Exception {
        //QueryMetricReq(domainId=10, metricIds=[39], metricNames=[], dimensionIds=[], dimensionNames=[], filters=[], dateInfo={"dateMode":BETWEEN,"startDate":"2024-08-10","endDate":"2024-08-16","dateList":[],"unit":7,"period":"DAY","text":"null"}, limit=1000)
        QueryMetricReq queryMetricReq = new QueryMetricReq();
        queryMetricReq.setDomainId(13L);
        queryMetricReq.setMetricIds(Lists.newArrayList(86L));
        queryMetricReq.setLimit(100L);
        DateConf dateConf = new DateConf();
        dateConf.setUnit(7);
        dateConf.setPeriod(Constants.DAY);
        dateConf.setDateMode(DateConf.DateMode.BETWEEN);
        dateConf.setStartDate("2024-08-10");
        dateConf.setEndDate("2024-08-16");
        dateConf.setGroupByDate(true);
        queryMetricReq.setDateInfo(dateConf);
        SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getFakeUser());
        Assert.assertNotNull(queryResp);

    }


    @Test
    void queryFieldMetric() throws Exception
    {
        QueryMetricReq queryMetricReq = new QueryMetricReq();
        queryMetricReq.setDomainId(17L);
        queryMetricReq.setMetricIds(Lists.newArrayList(57L));
        queryMetricReq.setLimit(100L);
        DateConf dateConf = new DateConf();
        dateConf.setUnit(7);
        dateConf.setPeriod(Constants.DAY);
        dateConf.setDateMode(DateConf.DateMode.BETWEEN);
        dateConf.setStartDate("2024-08-10");
        dateConf.setEndDate("2024-08-16");
        dateConf.setGroupByDate(true);
        queryMetricReq.setDateInfo(dateConf);
        SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getFakeUser());
        Assert.assertNotNull(queryResp);
    }

}
