package com.zkqy.system.service.impl;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.zkqy.common.utils.DateUtils;
import com.zkqy.common.utils.SecurityUtils;
import com.zkqy.system.entity.CommonEntity;
import com.zkqy.system.entity.DragTableStatistic;
import com.zkqy.system.entity.TableSql;
import com.zkqy.system.entity.vo.DragTableVo;
import com.zkqy.system.mapper.CommonMapper;
import com.zkqy.system.mapper.TableSqlMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zkqy.system.mapper.DragTableStatisticMapper;
import com.zkqy.system.service.IDragTableStatisticService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

/**
 * 动态表格统计Service业务层处理
 *
 * @author zkqy
 * @date 2023-10-27
 */
@Service
public class DragTableStatisticServiceImpl implements IDragTableStatisticService {
    @Autowired
    private DragTableStatisticMapper dragTableStatisticMapper;

    @Resource
    private TableSqlMapper tableSqlMapper;

    @Resource
    private CommonMapper commonMapper;

    @Override
    public DragTableStatistic selectDragTableStatisticById(Long id) {
        return dragTableStatisticMapper.selectDragTableStatisticById(id);
    }

    @Override
    public List<DragTableStatistic> selectDragTableStatisticList(DragTableStatistic dragTableStatistic) {
        return dragTableStatisticMapper.selectDragTableStatisticList(dragTableStatistic);
    }

    // SQL 条件的开始
    public static final String SQL_START = "CONCAT(";

    // SQL 超级查询常量
    public static final String SQL_MIDDLE = "IFNULL( #{VAL}, '' )";

    // sqlserver || DM 数据类型的超级查询常量
    public static final String SQL_DM_SERVER_MIDDLE = "COALESCE( #{VAL}, '' )";

    // SQL 条件的结束
    public static final String SQL_END = "LIKE '%#{val}%'";

    @Override
    @Transactional
    public int batchInsertDragTableStatistic(DragTableVo vo) {
        vo.getDragTableStatisticList().forEach(s -> {
            s.setCreateBy(SecurityUtils.getUserId().toString());
        });
        List<String> searchFieldList = new ArrayList<>();
        vo.getSearchFieldList().forEach(item -> {
            if (item.getConditionType().equals("SuperQuery")) {  // 当前表格的查询条件是超级查询
                searchFieldList.add(item.getConditionField());
            }
        });

        // 拼接sql查询条件
        String SQL = "";
        switch (SecurityUtils.getDatabaseType().toUpperCase()) {
            case "MYSQL":
                SQL += SQL_START;
                for (int i = 0; searchFieldList.size() > i; i++) {
                    SQL += SQL_MIDDLE.replace("#{VAL}", searchFieldList.get(i));
                    SQL += searchFieldList.size() - 1 == i ? ")" : ",\n";
                }
                break;
            case "DM":
            case "SQLSERVER":
                SQL += SQL_START;
                for (int i = 0; searchFieldList.size() > i; i++) {
                    SQL += SQL_DM_SERVER_MIDDLE.replace("#{VAL}", searchFieldList.get(i));
                    SQL += searchFieldList.size() - 1 == i ? ",'')" : ",\n";
                }
                break;
            case "ORACLE":
                for (int i = 0; searchFieldList.size() > i; i++) {
                    SQL += searchFieldList.get(i);
                    SQL += (searchFieldList.size() - 1 == i ? " " : "||");
                }
                break;
        }
        SQL += SQL_END;
        String where = vo.getDtTableName() + ".del_flag = '0' AND " + SQL;
        vo.getTableSqlList().stream().forEach(t -> t.setTableCondition(where));
        tableSqlMapper.batchInsertTableSql(vo.getTableSqlList());
        return dragTableStatisticMapper.batchInsertDragTableStatistic(vo.getDragTableStatisticList());
    }


    @Override
    @Transactional
    public int batchInsertGroupDragTableStatistic(DragTableVo vo) {
        vo.getDragTableStatisticList().stream().
                forEach(s -> {
                    s.setCreateBy(SecurityUtils.getUserId().toString());
                });
        // 拼接sql查询条件
        String SQL = "";
        switch (SecurityUtils.getDatabaseType().toUpperCase()) {
            case "MYSQL":
                //有拼接的统计条件值
                for (int i = 0; vo.getSearchFieldList().size() > i; i++) {
                    if (vo.getConditionDefaultValueMap() != null && vo.getConditionDefaultValueMap().size() > 0) {
                        SQL += " AND" + vo.getSearchFieldList().get(i) + "=" + vo.getConditionDefaultValueMap().get(vo.getSearchFieldList().get(i));
                    }
                }
                break;
            case "DM":
            case "SQLSERVER":
                break;
            case "ORACLE":
                break;
        }
        String where = vo.getDtTableName() + ".del_flag = '0'" + SQL;
        vo.getTableSqlList().stream().forEach(t -> t.setTableCondition(where));
        vo.getTableSqlList().forEach(item -> {
            item.setDelFlag("0");
        });
//        tableSqlMapper.batchInsertTableSql();
        vo.getTableSqlList().forEach(item -> tableSqlMapper.insertTableSql(item));

        vo.getDragTableStatisticList().forEach(item->{
            dragTableStatisticMapper.insertDragTableStatistic(item);
        });
        return 1;
    }


    @Override
    @Transactional
    public void updateDragTableStatistic(DragTableVo vo) {
        // 拼接sql查询条件
        List<String> searchFieldList = new ArrayList<>();
        vo.getSearchFieldList().forEach(item -> {
            if (item.getConditionType().equals("SuperQuery")) {  // 当前表格的查询条件是超级查询
                searchFieldList.add(item.getConditionField());
            }
        });
        String SQL = "";
        switch (SecurityUtils.getDatabaseType().toUpperCase()) {
            case "MYSQL":
                SQL += SQL_START;
                for (int i = 0; searchFieldList.size() > i; i++) {
                    SQL += SQL_MIDDLE.replace("#{VAL}", searchFieldList.get(i));
                    SQL += searchFieldList.size() - 1 == i ? ")" : ",\n";
                }
                break;
            case "DM":
            case "SQLSERVER":
                SQL += SQL_START;
                for (int i = 0; searchFieldList.size() > i; i++) {
                    SQL += SQL_DM_SERVER_MIDDLE.replace("#{VAL}", searchFieldList.get(i));
                    SQL += searchFieldList.size() - 1 == i ? ",'')" : ",\n";
                }
                break;
            case "ORACLE":
                for (int i = 0; searchFieldList.size() > i; i++) {
                    SQL += searchFieldList.get(i);
                    SQL += (searchFieldList.size() - 1 == i ? " " : "||");
                }
                break;
        }
        SQL += SQL_END;
        String sql = vo.getDtTableName() + ".del_flag = '0' AND " + SQL;
        LinkedList<DragTableStatistic> addList = new LinkedList<>();
        LinkedList<DragTableStatistic> editList = new LinkedList<>();
        List<Long> numList = new ArrayList<>();
        vo.getDragTableStatisticList().stream().forEach(s -> {
            if (s.getId() == null) {
                s.setCreateById(SecurityUtils.getUserId());
                s.setCreateBy(SecurityUtils.getUsername());
                s.setCreateTime(DateUtils.getNowDate());
                addList.add(s);//新添加的
            } else {
                s.setUpdateById(SecurityUtils.getUserId());
                s.setUpdateBy(SecurityUtils.getUsername());
                s.setUpdateTime(DateUtils.getNowDate());
                editList.add(s); //修改的
            }
            numList.add(s.getId());
        });
        //select Statistic ids
        List<Long> allIds = dragTableStatisticMapper.selectIdsByTableKey(vo.getTableKey());
        allIds.removeAll(numList); //把所有的统计都给干掉
        //remove Statistic
        if (allIds.size() > 0) {
            dragTableStatisticMapper.deleteDragTableStatisticByIds(allIds);
        }
        //add Statistic
        if (addList.size() > 0) {
            dragTableStatisticMapper.batchInsertDragTableStatistic(addList);
        }
        //update Statistic
        if (editList.size() > 0) {
            editList.stream().forEach(e -> dragTableStatisticMapper.updateDragTableStatistic(e));
        }
        // select Statistic sqlKey
        List<String> allSqlKey = dragTableStatisticMapper.selectSqlKeyByTableKey(vo.getTableKey());

        if (vo.getTableSqlList().size() > 0) {
            vo.getTableSqlList().stream().forEach(t -> {
                t.setCreateById(SecurityUtils.getUserId());
                t.setCreateBy(SecurityUtils.getUsername());
                t.setCreateTime(DateUtils.getNowDate());
                t.setTableCondition(sql);
            });
            if (allSqlKey.size() > 0) {
                //remove tableSql
                tableSqlMapper.deleteTableSqlBySqlKeys(allSqlKey);
            }
            //add tableSql
            tableSqlMapper.batchInsertTableSql(vo.getTableSqlList());
        } else {
            if (allSqlKey.size() > 0) {
                //remove tableSql
                tableSqlMapper.deleteTableSqlBySqlKeys(allSqlKey);
            }
        }

    }

    @Override
    @Transactional
    public void updateGroupDragTableStatistic(DragTableVo vo) {

        vo.getDragTableStatisticList().stream().
                forEach(s -> {
                    s.setUpdateById(SecurityUtils.getUserId());
                    s.setUpdateBy(SecurityUtils.getUsername());
                    s.setUpdateTime(DateUtils.getNowDate());
                    ;
                });
        // 拼接sql查询条件
        String SQL = "";
        switch (SecurityUtils.getDatabaseType().toUpperCase()) {
            case "MYSQL":
                for (int i = 0; vo.getSearchFieldList().size() > i; i++) {
                    if (vo.getConditionDefaultValueMap() != null && vo.getConditionDefaultValueMap().size() > 0) {
                        SQL += " AND " + vo.getSearchFieldList().get(i) + "=" + vo.getConditionDefaultValueMap().get(vo.getSearchFieldList().get(i));
                    }
                }
                break;
            case "DM":
            case "SQLSERVER":
            case "ORACLE":
                break;
        }
        String sql = vo.getDtTableName() + ".del_flag = '0'" + SQL;
        LinkedList<DragTableStatistic> addList = new LinkedList<>();
        LinkedList<DragTableStatistic> editList = new LinkedList<>();
        List<Long> numList = new ArrayList<>();
        vo.getDragTableStatisticList().stream().forEach(s -> {
            if (s.getId() == null) {
                s.setCreateById(SecurityUtils.getUserId());
                s.setCreateBy(SecurityUtils.getUsername());
                s.setCreateTime(DateUtils.getNowDate());
                addList.add(s);//新添加的
            } else {
                s.setUpdateById(SecurityUtils.getUserId());
                s.setUpdateBy(SecurityUtils.getUsername());
                s.setUpdateTime(DateUtils.getNowDate());
                editList.add(s); //修改的
            }
            numList.add(s.getId());
        });
        //select Statistic ids
        List<Long> allIds = dragTableStatisticMapper.selectIdsByTableKey(vo.getTableKey());
        allIds.removeAll(numList); //把所有的统计都给干掉
        //remove Statistic
        if (allIds.size() > 0) {
            dragTableStatisticMapper.deleteDragTableStatisticByIds(allIds);
        }
        //add Statistic
        if (addList.size() > 0) {
            dragTableStatisticMapper.batchInsertDragTableStatistic(addList);
        }
        //update Statistic
        if (editList.size() > 0) {
            editList.stream().forEach(e -> dragTableStatisticMapper.updateDragTableStatistic(e));
        }
        // select Statistic sqlKey
        List<String> allSqlKey = dragTableStatisticMapper.selectSqlKeyByTableKey(vo.getTableKey());

        if (vo.getTableSqlList().size() > 0) {
            vo.getTableSqlList().stream().forEach(t -> {
                t.setCreateById(SecurityUtils.getUserId());
                t.setCreateBy(SecurityUtils.getUsername());
                t.setCreateTime(DateUtils.getNowDate());
                t.setUpdateById(SecurityUtils.getUserId());
                t.setUpdateBy(SecurityUtils.getUsername());
                t.setUpdateTime(DateUtils.getNowDate());
                t.setTableCondition(sql);
            });
            if (allSqlKey.size() > 0) {
                //remove tableSql
                tableSqlMapper.deleteTableSqlBySqlKeys(allSqlKey);
            }
            //add tableSql
            tableSqlMapper.batchInsertTableSql(vo.getTableSqlList());
        } else {
            if (allSqlKey.size() > 0) {
                //remove tableSql
                tableSqlMapper.deleteTableSqlBySqlKeys(allSqlKey);
            }
        }

    }


    @Override
    public int deleteDragTableStatisticByTableKey(String tableKey) {
        return dragTableStatisticMapper.deleteDragTableStatisticByTableKey(tableKey);
    }

    @Override
    public void deleteDragTableStatisticByTableKeys(List<String> tableKeys) {
        dragTableStatisticMapper.deleteDragTableStatisticByTableKeys(tableKeys);
    }


    @Override
    public Map<String, Object> getInfoBySqlKey(String tableKey) {
        Map<String, Object> map = new HashMap<>();
        DragTableStatistic dragTableStatistic = new DragTableStatistic();
        dragTableStatistic.setTableKey(tableKey);
        List<DragTableStatistic> dragTableStatisticList = dragTableStatisticMapper.selectDragTableStatisticList(dragTableStatistic);
        map.put("dragTableStatisticList", dragTableStatisticList);
        return null;
    }

    @Override
    public List<DragTableStatistic> getStatisticList(CommonEntity commonEntity) {
        // 根据sqlkey查询得到当前表单对应的sql
        Map<String, Object> conditions = JSONObject.parseObject(JSON.toJSONString(commonEntity.getQueryMap()));
        // 得到查询条件的值
        String queryCriteriaValue =
                conditions.containsKey("queryCriteriaValue") == true
                        ? conditions.get("queryCriteriaValue").toString() : "";
        DragTableStatistic dragTableStatistic = new DragTableStatistic();
        dragTableStatistic.setTableKey(conditions.get("tableKey").toString());
        List<DragTableStatistic> dragTableStatisticList = dragTableStatisticMapper.selectDragTableStatisticList(dragTableStatistic);
        return dragTableStatisticList.stream().map(d -> {
            TableSql tableSql = tableSqlMapper.selectTableSqlByTSqlKey(d.getSqlKey());
            // 得到需要执行的sql条件语句
            AtomicReference<String> endSQLAtomic = new AtomicReference<>(tableSql.getTableCondition());
            //查询配置信息查询统计信息
            if (commonEntity.getQueryMap() != null || commonEntity.getQueryMap().size() > 0) {
                commonEntity.getQueryMap().forEach((k, v) -> {
                    if (!k.equals("tableKey")) {
                        String replace = tableSql.getTableCondition().replace(k, "'" + v.toString() + "'");
                        tableSql.setTableCondition(replace);
                        endSQLAtomic.set(replace);
                    }
                });
            }
            String endSQL = endSQLAtomic.get().replace("#{val}", queryCriteriaValue);
            String sql = "";
            if (StringUtils.hasLength(d.getStatisticObject())) {
                sql = tableSql.getTableSql() + " where " + endSQL + " and " + d.getStatisticField() + " like'" + d.getStatisticObject() + "'";
            } else {
                sql = tableSql.getTableSql() + " where " + endSQL;
            }
            List<CommonEntity> commonEntities = commonMapper.queryTableList(sql);
            d.setResult(commonEntities.get(0) == null ? 0 : commonEntities.get(0).getResultMap().get("result"));
            return d;
        }).collect(Collectors.toList());
    }
}
