package com.usoftchina.bi.server.service.chart;

import com.usoftchina.bi.core.base.RepCode;
import com.usoftchina.bi.core.base.RepEntity;
import com.usoftchina.bi.core.utils.CalculationJudgeUtil;
import com.usoftchina.bi.core.utils.CollectionUtils;
import com.usoftchina.bi.server.dao.chart.ChartsConfigMapper;
import com.usoftchina.bi.server.dao.chart.ShowChartsMapper;
import com.usoftchina.bi.server.model.bo.*;
import com.usoftchina.bi.server.model.vo.configVo.LineConfigInfo;
import com.usoftchina.bi.server.model.vo.dataVo.ChartsDataInfo;
import com.usoftchina.bi.core.jdbc.DynamicDataSourceContextHolder;
import com.usoftchina.bi.server.utils.ScreenUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service
public class ShowLineService {
    @Autowired
    ShowChartsMapper showChartsMapper;
    @Autowired
    TimeConverterUtil timeConverterUtil;
    @Autowired
    ChartsConfigMapper chartsConfigMapper;
    @Autowired
    GetChartsDataUtilService getChartsDataUtilService;
    @Autowired
    ScreenUtil screenUtil;
    @Autowired
    ChartsUtilService chartsUtilService;

    /*
    Line数据展示
     */
    public RepEntity showLine(LineConfigInfo lineConfigInfo, String token, int dashId){
        ChartsDataInfo chartsDataInfo = new ChartsDataInfo();
        TimeReture timeReture = new TimeReture();
        if (lineConfigInfo == null || "".equals(lineConfigInfo)){
            return new RepEntity(RepCode.Null);
        }
        int id = lineConfigInfo.getId();
        //获取列配置
        ChartsColumnConfig chartsColumn = chartsConfigMapper.getChartsColumn(id);
        if (chartsColumn == null || "".equals(chartsColumn)){
            return new RepEntity(RepCode.Null);
        }
        String style = chartsColumn.getChartStyle();
        String config = chartsColumn.getChartConfig();
        chartsDataInfo.setChartsColumnConfig(chartsColumn);


        String tableName = chartsUtilService.getSqlStr(token, id, dashId);
        if ("".equals(tableName)){
            return new RepEntity(RepCode.NoAuthority);
        }

        int baseId = getChartsDataUtilService.getBaseId(id);

        try{
            if (!DynamicDataSourceContextHolder.isContainsDataSource(baseId)) {
                return new RepEntity(RepCode.DataSourceNull);
            } else {
                DynamicDataSourceContextHolder.setDataSourceType(baseId);
            }

        String xColumn = lineConfigInfo.getxAxis().getColumnRename();
        String yColumn = lineConfigInfo.getyAxis().getColumnRename();

        String xAxisType = lineConfigInfo.getxAxis().getShowDataType();
        List<String> groupBy = lineConfigInfo.getGroups();

        if (xColumn == null || "".equals(xColumn) || yColumn == null || "".equals(yColumn)){
            return new RepEntity(RepCode.nullAxis);
        }

        String yType = lineConfigInfo.getyAxis().getShowDataType();
        String yAxisType = CalculationJudgeUtil.Judge(yType);



        List<LineSeriesMap> value = new ArrayList<LineSeriesMap>();
        List<LineSeries> serieses = new ArrayList<LineSeries>();    //生成柱状图的系列
        List<String> xAxisData = new ArrayList<String>();  //X轴自己用

        //取筛选列表
        List<Screen> screens = lineConfigInfo.getFilters();
        ScreenStr scr = new ScreenStr();
        String screen = "";               //正常筛选条件
        String screenToColumn = "";       //跟目标列相同的筛选条件
        String screenToColumnS = "";       //跟目标列相同的筛选条件
        if ("".equals(screens) || screens == null || screens.size() == 0){
            screen = "";
        }else {
            scr = screenUtil.screensUtil(screens, xColumn, xAxisType);
            screen = scr.getRet();
            screenToColumn = scr.getWithColumnRet();
            StringBuilder sb = new StringBuilder(screenToColumn);
            if (screenToColumn != null && !("".equals(screenToColumn))){
                screenToColumnS = screenToColumn + " " + screen;               //and
                screenToColumn = String.valueOf(sb .replace(1, 5, "where "));
                screen = screenToColumn + " " + screen;         //where
            } else {
                StringBuilder sb1 = new StringBuilder(screen);
                screenToColumnS = screen;
                screen = String.valueOf(sb1 .replace(1, 5, "where "));
            }
        }

        //X轴
        //判断是否为日期类型
            timeReture = timeConverterUtil.timeConverter(xColumn, tableName, xAxisType, screen, lineConfigInfo.getMaxCount());
            xAxisData = timeReture.getValues();
            chartsDataInfo.setTooMany(timeReture.isOverdose());

        if ("".equals(xAxisData) || xAxisData == null || xAxisData.size() == 0){
            return new RepEntity(RepCode.Null);
        }

        //无分组时Y值
        value = showChartsMapper.getTimeValues(yAxisType, yColumn, tableName, xColumn, screen);
        LineSeries series = new LineSeries();
        series.setMdata(value);

        serieses.add(series);

        //有分组
        if (groupBy.size() != 0){
            serieses.remove(0);
            Iterator itGroup = groupBy.iterator();  //分组数

            //遍历分组
            while (itGroup.hasNext()){
                String groupByName = (String) itGroup.next();
                List<String> groupsData = showChartsMapper.getGroups(groupByName,tableName, screenToColumnS, lineConfigInfo.getMaxCount()); //查询每个分组系列
                Iterator itGroupsData = groupsData.iterator();
                if (groupsData.size() > lineConfigInfo.getMaxCount()){
                    chartsDataInfo.setTooMany(true);
                }
                String groupsName = (String)itGroupsData.next();

                List<LineSeriesGroupMap> lineSeriesGroupMapList = showChartsMapper.getGroupsValuesTime(yAxisType, yColumn, tableName, groupByName, groupsName, xColumn, "'YYYY-MM-DD'");
                Map<String, List<LineSeriesGroupMap>> lineSeriesGroupMap = CollectionUtils.groupBy(lineSeriesGroupMapList, LineSeriesGroupMap::getGroup);
                Iterator<Map.Entry<String, List<LineSeriesGroupMap>>> it = lineSeriesGroupMap.entrySet().iterator();
                List<LineSeriesMap> lineSeriesMapList = null;
                while (it.hasNext()) {
                    Map.Entry<String, List<LineSeriesGroupMap>> entry = it.next();
                    LineSeries lineSeries = new LineSeries();
                    lineSeries.setName(entry.getKey());
                    lineSeriesMapList = new ArrayList<>();
                    copyProperties(entry.getValue(), lineSeriesMapList);
                    lineSeries.setMdata(lineSeriesMapList);
                    serieses.add(lineSeries);
                }
            }
        }

        chartsDataInfo.setSerieses(serieses);

        }catch (Exception e){
            e.printStackTrace();
            if (e.getCause().getMessage().contains("ORA-00904:")) {
                return new RepEntity(RepCode.erro.getCode(), "数据源" + e.getCause().getMessage().replace("ORA-00904:", "").replaceAll("标识符", "列"), null);
            }
            return new RepEntity(RepCode.erro.getCode(), e.getCause().getMessage(), null);
        }finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }

        return new RepEntity(RepCode.success, chartsDataInfo);
    }

    /**
     * LineSeriesGroupMap 转 LineSeriesMap
     * @param source
     * @param target
     */
    private void copyProperties(List<LineSeriesGroupMap> source, List<LineSeriesMap> target){
        if (!CollectionUtils.isEmpty(source)) {
            for (LineSeriesGroupMap lineSeriesGroupMap : source) {
                target.add(new LineSeriesMap(lineSeriesGroupMap.getDate(), lineSeriesGroupMap.getValue()));
            }
        }
    }


}
