package com.hs.api.service.Impl;

import com.hs.api.common.exceptions.DBConfigurationError;
import com.hs.api.mapper.SerPageBlockRsMapper;
import com.hs.api.mapper.SerPageMapper;
import com.hs.api.model.SerPage;
import com.hs.api.model.SerPageBlockRs;
import com.hs.api.model.respmodel.BlockValue;
import com.hs.api.service.AsynBlockValuesService;
import com.hs.api.service.BlockValuesService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CountDownLatch;

@Service
public class BlockValuesServiceImpl implements BlockValuesService {

    @Resource
    private SerPageBlockRsMapper serPageBlockRsMapper;
    @Resource
    private SerPageMapper serPageMapper;
    @Resource
    private AsynBlockValuesService asynBlockValuesServiceImpl;


    @Override
    public List<BlockValue> getBlockValuesByPageCode(Integer pageCode, Integer disease, Integer doctor, Integer department, Integer time) throws InterruptedException {
        /**
         * 1.根据pageCode,disease,doctor,department,time查询所有对应的pageId
         *   查询要求为pageCode为当前pageCode，相同pageId的所有数据有且仅有DIM_ID为
         *   disease,doctor,department,time中不为null的对应id
         * 2.根据pageId获取所有block
         * 3.根据block拼接表名及where语句
         */
        List<BlockValue> list = new ArrayList<>();

        int count = 0;
        String inField = "";
        String whereClause = "where 1=1";
        if (disease != null) {
            whereClause += String.format(" and disease='%s'", disease);
            inField += "'disease',";
            count++;
        }
        if (doctor != null) {
            whereClause += String.format(" and doctor='%s'", doctor);
            inField += "'doctor',";
            count++;
        }
        if (department != null) {
            whereClause += String.format(" and department='%s'", department);
            inField += "'department',";
            count++;
        }
        if (time != null) {
            whereClause += String.format(" and time='%s'", time);
            inField += "'time',";
            count++;
        }
        if (count > 0) {
            inField = inField.substring(0, inField.length() - 1);
        }

        List<SerPage> pageList = serPageMapper.selectByCodeAndDim(pageCode, inField, count);
        if (pageList.size() == 0) {
            throw new DBConfigurationError("页面维度配置表错误，请联系管理员");
        }

        SerPage page = pageList.get(0);

        //根据pageId查询所有板块
        List<SerPageBlockRs> pageBlocklist = serPageBlockRsMapper.selectByPageId(page.getId());
        //循环获取数据
        CountDownLatch latch = new CountDownLatch(pageBlocklist.size());
        for (SerPageBlockRs data : pageBlocklist) {
            //获取表名
            Long blockId = data.getBlockId();
            String tableName = "VAL_BLOCK_VALUES_" + blockId;
            asynBlockValuesServiceImpl.getBlockValues(list, blockId, tableName, whereClause, latch);

        }
        latch.await();

        return list;
    }

    @Override
    public List<BlockValue> getBlockValuesByPageCodeNew(Long userId, Integer pageCode, Map<String, String> dim) throws InterruptedException {
        /**
         * 1.根据pageCode查询所有对应的pageId
         *   查询要求为pageCode为当前pageCode，相同pageId的所有数据有且仅有DIM_ID为
         *   dim中键值对的数据
         * 2.根据pageId获取所有block
         * 3.根据block拼接表名及where语句
         */
        List<BlockValue> list = new ArrayList<>();

//        int count = 0;
        Set<String> inFields = dim.keySet();
//        String inField = "";
//        for (Map.Entry<String, String> entry : dim.entrySet()) {
//            inField += "'"+ SqlUtil.TransactSQLInjection(entry.getKey())+"',";
//            count++;
//        }
//        if(count > 0){
//            inField = inField.substring(0, inField.length()-1);
//        }

        for (Iterator iterator = inFields.iterator(); iterator.hasNext(); ) {
            Object obj = iterator.next();
            Object value = dim.get(obj);
            if (value instanceof String) {
                String valueNew = dim.get(obj);
                dim.put(String.valueOf(obj), valueNew.trim());
            }
            remove(value, iterator);
        }

        List<SerPage> pageList = serPageMapper.selectByCodeAndDimList(pageCode, inFields, inFields.size());
//        List<SerPage> pageList = serPageMapper.selectByCodeAndDim(pageCode, inField, count);
        if (pageList.size() == 0) {
            throw new DBConfigurationError("页面维度配置表错误，请联系管理员");
        }

        //将用户信息配置进参数
        dim.put("USER", String.valueOf(userId));

        SerPage page = pageList.get(0);

        //根据pageId查询所有板块
        List<SerPageBlockRs> pageBlocklist = serPageBlockRsMapper.selectByPageId(page.getId());
        //循环获取数据
        CountDownLatch latch = new CountDownLatch(pageBlocklist.size());
        for (SerPageBlockRs data : pageBlocklist) {
            //获取表名
            Long blockId = data.getBlockId();
//            String tableName = "VAL_BLOCK_VALUES_" + pageCode + "_" + page.getId() + "_" + blockId;
            String tableName = data.getTableName();
            Map<String, String> map = new HashMap<String, String>() {
                {
                    put("tableName", tableName);
                    put("whereSql", data.getWhereClause());
                    putAll(dim);
                }
            };
            asynBlockValuesServiceImpl.getBlockValuesNew(list, blockId, map, latch);

        }
        latch.await();

        return list;

    }

    private static void remove(Object obj, Iterator iterator) {
        if (obj instanceof String) {
            String str = (String) obj;
            if (StringUtils.isBlank(str)) {
                iterator.remove();
            }

        } else if (obj instanceof Collection) {
            Collection col = (Collection) obj;
            if (col == null || col.isEmpty()) {
                iterator.remove();
            }

        } else if (obj instanceof Map) {
            Map temp = (Map) obj;
            if (temp == null || temp.isEmpty()) {
                iterator.remove();
            }

        } else if (obj instanceof Object[]) {
            Object[] array = (Object[]) obj;
            if (array == null || array.length <= 0) {
                iterator.remove();
            }
        } else {
            if (obj == null) {
                iterator.remove();
            }
        }
    }
}



