package thyyxxk.webserver.service.dictionary;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.dictionary.EmrDataMaintenanceDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.zhuyuanyisheng.EmrDataMaintenance;
import thyyxxk.webserver.utils.*;

import java.util.*;

/**
 * @author 肖蟾
 */
@Service
@Slf4j
public class EmrDataMaintenanceServer {

    private final EmrDataMaintenanceDao dao;

    public EmrDataMaintenanceServer(EmrDataMaintenanceDao dao) {
        this.dao = dao;
    }

    private static String keyParameterSubstitution(String sqlSentence, String patNo, Integer times) {
        sqlSentence = sqlSentence.replaceAll("\\$\\{PAT_NO}", " '" + patNo + "' ");
        sqlSentence = sqlSentence.replaceAll("\\$\\{TIMES}", " " + times + " ");
        return sqlSentence;
    }

    private static void createObject(Map<String, List<Map<String, Object>>> groupMap,
                                     String key, Object value,
                                     Map<String, Object> extraMap) {
        String[] keys = key.split("_");
        List<Map<String, Object>> groupChild = new ArrayList<>();
        Map<String, Object> childMap = new HashMap<>();

        if (keys.length == 4) {
            extraMap.put(StringUtil.humpToUnderline(keys[3]), value);
        }

        if (groupMap.containsKey(keys[1])) {
            childMap.putAll(groupMap.get(keys[1]).get(0));
            childMap.put(keys[2], value);
            groupChild.add(childMap);
            groupMap.replace(keys[1], groupChild);
        } else {
            childMap.put(keys[2], value);
            groupChild.add(childMap);
            groupMap.put(keys[1], groupChild);
        }
    }


    public ResultVo<Page<EmrDataMaintenance>> getElectronicMedicalRecordDataElementSql(int currentPage, int pageSize, long total) {
        Page<EmrDataMaintenance> page = new Page<>(currentPage, pageSize, total == 0);
        dao.getElectronicMedicalRecordDataElementSql(page);
        return ResultVoUtil.success(page);
    }

    public ResultVo<JSONObject> testSql(EmrDataMaintenance emr) {
        String sql = keyParameterSubstitution(emr.getSqlSentence(), emr.getPatNo(), emr.getTimes());
        log.info("sql:{}", sql);
        if (emr.getDataType().equals(0)) {
            Map<String, Object> sqlData = dao.testSql(sql);
            if (null == sqlData || sqlData.isEmpty()) {
                return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "sql没问题，但是没得数据。");
            }
            // 永远添加 住院号和住院次数
            sqlData.put("inpatient_no", emr.getPatNo());
            sqlData.put("admiss_times", emr.getTimes());

            Map<String, List<Map<String, Object>>> groupingMap = new HashMap<>();
            Map<String, Object> extraMap = new HashMap<>();
            List<String> groupKeys = new ArrayList<>();

            for (Map.Entry<String, Object> dbitem : sqlData.entrySet()) {
                Object value = dbitem.getValue();
                String key = dbitem.getKey();
                if (value != null) {
                    if (value instanceof String) {
                        sqlData.replace(key, ((String) value).trim());
                        if (key.startsWith("gy_")) {
                            groupKeys.add(key);
                            createObject(groupingMap, key, ((String) value).trim(), extraMap);
                        }
                    }
                }
            }
            sqlData.putAll(groupingMap);
            sqlData.putAll(extraMap);
            for (String item : groupKeys) {
                sqlData.remove(item);
            }
            if (StringUtil.notBlank(emr.getGroupName())) {
                String map = String.format("{\"%s\" : %s}", emr.getGroupName(), JSON.toJSONStringWithDateFormat(sqlData, DateUtil.DEFAULT_PATTERN));
                return ResultVoUtil.success(JSON.parseObject(map));
            }
            return ResultVoUtil.success(JSON.parseObject(JSON.toJSONStringWithDateFormat(sqlData, DateUtil.DEFAULT_PATTERN)));
        } else {
            List<Map<String, Object>> listMap = dao.testSqlList(sql);
            if (ListUtil.isBlank(listMap)) {
                return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "sql没问题，但是没得数据。");
            }
            Map<String, List<Map<String, Object>>> formatData = new HashMap<>(1);
            formatData.put(emr.getGroupName(), listMap);
            return ResultVoUtil.success(JSON.parseObject(JSON.toJSONStringWithDateFormat(formatData, DateUtil.DEFAULT_PATTERN)));
        }
    }


    public ResultVo<String> addData(EmrDataMaintenance emr) {
        String userCode = TokenUtil.getTokenUserId();
        dao.addData(emr.getName(), emr.getSqlSentence(), userCode, emr.getDataType());
        log.info("新增电子病历维护 ==> 操作人:{},数据:{}", userCode, JSON.toJSONString(emr));
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
    }

    public ResultVo<String> deleteById(Integer id) {
        dao.deleteById(id, TokenUtil.getTokenUserId());
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
    }

    public ResultVo<String> updateData(EmrDataMaintenance emr) {
        if (emr == null || emr.getId() == null) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有查询到id");
        }
        dao.updateData(emr, TokenUtil.getTokenUserId());
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
    }


    public ResultVo<JSONObject> getEmrInpatientData(String patNo, Integer times) throws Exception {
        List<EmrDataMaintenance> emrData = dao.getEmrInpatientData();
        JSONObject obj = new JSONObject();
        for (EmrDataMaintenance item : emrData) {
            item.setPatNo(patNo);
            item.setTimes(times);
            ResultVo<JSONObject> resultVo = testSql(item);
            if (resultVo.getCode() == ExceptionEnum.SUCCESS.getCode()) {
                if (null != resultVo.getData()) {
                    obj = EntityCopy.jsonMerge(resultVo.getData(), obj);
                }
            }
        }
        return ResultVoUtil.success(obj);
    }

}
