package com.cim.idm.service.Impl;

import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.framework.util.time.TimeUtils;
import com.cim.idm.service.QueryService;
import com.cim.idm.utils.PageResult;
import com.cim.idm.wmsextend.generic.errorHandler.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service("pdaQueryService")
public class QueryServiceImpl implements QueryService {
    /**
     * 执行查询并返回结果列表
     *
     * @param queryId 查询标识符，用于指定具体的查询
     * @param version 查询版本，用于指定查询的不同版本
     * @param bindMap 查询参数绑定，包含查询所需的参数
     * @return 查询结果列表，每个结果以Map形式表示，键为列名，值为数据值
     */
    @Override
    public List<Map<String, Object>> getQueryResult(String queryId, String version, Map bindMap) throws CustomException {
        long startDate = new Date().getTime();

        String usrSql = "SELECT queryString FROM BS_CustomQuery WHERE queryId = ? and version = ? ";
        String[] args = new String[] { queryId, version };
        List<Map<String,Object>> resultList = IDMFrameServiceProxy.getSqlTemplate().queryForList(usrSql, args);

        if (resultList.size() == 0) {
            throw new CustomException("没有找到匹配的查询语句，" + "queryId：" + queryId + "，version：" + version);
        }

        Map<String,Object> queryMap =  resultList.get(0);
        String dbSql = queryMap.get("queryString").toString();
        dbSql = dbSql.replaceFirst(";\\s*$", "");

        List<Map<String,Object>> sqlResultList = new ArrayList<Map<String,Object>>();
        try {
            if (bindMap != null)
                log.info(">> 查询SQL = [" + dbSql + "] ，入参 = [" + bindMap.toString() + "]");
            else
                log.info(">> 查询SQL = [" + dbSql + "] ，入参 = []");

            sqlResultList = IDMFrameServiceProxy.getSqlTemplate().queryForList(dbSql, bindMap);
        } catch (Exception e) {
            log.error(String.valueOf(e));
            throw new CustomException("SQLException：" + e.getCause());
        }

        long bpelTime = new Date().getTime() - startDate;
        if(bpelTime > 3000){
            String sql = "insert into temp_querybpelinfo(queryid,version,transactionid,bpeltime) values(?,?,?,?) ";
            IDMFrameServiceProxy.getSqlTemplate().update(sql, queryId,version,Long.toString(startDate),Long.toString(bpelTime));
        }

        try
        {
            usrSql = "UPDATE BS_CustomQuery SET USEFLAG = ?, LASTUSETIMEKEY = ? WHERE QUERYID = ? AND VERSION = ? ";
            Object[] useFlagArgs = new String[] { "Y", new TimeUtils().getCurrentEventTimeKey(), queryId, version };
            IDMFrameServiceProxy.getSqlTemplate().update(usrSql, useFlagArgs);
        }
        catch (Exception e)
        {
            log.error(String.valueOf(e));
        }

        return sqlResultList;
    }

    /**
     * 执行查询并返回分页结果
     *
     * @param queryId  查询标识符，用于指定具体的查询
     * @param version  查询版本，用于指定查询的不同版本
     * @param bindMap  查询参数绑定，包含查询所需的参数
     * @param pageNum  页码，表示请求的页面编号
     * @param pageSize 页面大小，表示每页包含的记录数
     * @return 查询结果的分页对象，包含页码、页面大小及查询结果列表
     */
    @Override
    public PageResult<Map<String, Object>> getQueryResultPage(String queryId, String version, Map bindMap, int pageNum, int pageSize) throws CustomException {
        long startDate = new Date().getTime();

        String usrSql = "SELECT queryString FROM BS_CustomQuery WHERE queryId = ? and version = ? ";
        String[] args = new String[] { queryId, version };
        List<Map<String,Object>> resultList = IDMFrameServiceProxy.getSqlTemplate().queryForList(usrSql, args);

        if (resultList.size() == 0) {
            throw new CustomException("没有找到匹配的查询语句，" + "queryId：" + queryId + "，version：" + version);
        }

        Map<String,Object> queryMap =  resultList.get(0);
        String dbSql = queryMap.get("queryString").toString();
        dbSql = dbSql.replaceFirst(";\\s*$", "");

        String countSql = "SELECT count(*) AS COUNT FROM ( " + dbSql + " )";
        List<Map<String,Object>> sqlCountList = IDMFrameServiceProxy.getSqlTemplate().queryForList(countSql, bindMap);
        BigDecimal sum = (BigDecimal) sqlCountList.get(0).get("COUNT");
        Integer totleNum = sum.intValue();

        dbSql = "SELECT * FROM (SELECT webFirst.*, ROWNUM rnum FROM ( " + dbSql + " ) webFirst) webSecond WHERE webSecond.rnum > :STARTROW AND webSecond.rnum <= :ENDROW";
        bindMap.put("STARTROW", (pageNum - 1) * pageSize);
        bindMap.put("ENDROW", pageNum * pageSize);

        int sumPage = totleNum/pageSize;
        if(totleNum%pageSize > 0) {
            sumPage = sumPage + 1;
        }
        log.info("总页数 sumPage => " + sumPage);

        List<Map<String,Object>> sqlResultList = new ArrayList<Map<String,Object>>();
        PageResult<Map<String,Object>> pageInfo = new PageResult<Map<String,Object>>();
        try {
            if (bindMap != null)
                log.info(">> 查询SQL = [" + dbSql + "] ，入参 = [" + bindMap.toString() + "]");
            else
                log.info(">> 查询SQL = [" + dbSql + "] ，入参 = []");
            sqlResultList = IDMFrameServiceProxy.getSqlTemplate().queryForList(dbSql, bindMap);
            pageInfo = new PageResult<Map<String,Object>>(sqlResultList, sumPage, totleNum,pageNum);
        } catch (Exception e) {
            log.error(String.valueOf(e));
            throw new CustomException("SQLException：" + e.getCause());
        }

        long bpelTime = new Date().getTime() - startDate;
        if(bpelTime > 3000){
            String sql = "insert into temp_querybpelinfo(queryid,version,transactionid,bpeltime) values(?,?,?,?) ";
            IDMFrameServiceProxy.getSqlTemplate().update(sql, queryId,version,Long.toString(startDate),Long.toString(bpelTime));
        }

        try
        {
            usrSql = "UPDATE BS_CustomQuery SET USEFLAG = ?, LASTUSETIMEKEY = ? WHERE QUERYID = ? AND VERSION = ? ";
            Object[] useFlagArgs = new String[] { "Y", new TimeUtils().getCurrentEventTimeKey(), queryId, version };
            IDMFrameServiceProxy.getSqlTemplate().update(usrSql, useFlagArgs);
        }
        catch (Exception e)
        {
            log.error(String.valueOf(e));
        }

        return pageInfo;
    }

    public PageResult<Map<String,Object>> getQueryResultPage(String dbSql, Map bindMap, int pageNum, int pageSize) {
        long startDate = new Date().getTime();

        String countSql = "SELECT count(*) AS COUNT FROM ( " + dbSql + " )";
        List<Map<String,Object>> sqlCountList = IDMFrameServiceProxy.getSqlTemplate().queryForList(countSql, bindMap);
        BigDecimal sum = (BigDecimal) sqlCountList.get(0).get("COUNT");
        Integer totleNum = sum.intValue();

        dbSql = "SELECT * FROM (SELECT webFirst.*, ROWNUM rnum FROM ( " + dbSql + " ) webFirst) webSecond WHERE webSecond.rnum > :STARTROW AND webSecond.rnum <= :ENDROW";
        bindMap.put("STARTROW", (pageNum - 1) * pageSize);
        bindMap.put("ENDROW", pageNum * pageSize);

        int sumPage = totleNum/pageSize;
        if(totleNum%pageSize > 0) {
            sumPage = sumPage + 1;
        }
        log.info("总页数 sumPage => " + sumPage);

        List<Map<String,Object>> sqlResultList = new ArrayList<Map<String,Object>>();
        PageResult<Map<String,Object>> pageInfo = new PageResult<Map<String,Object>>();
        try {
            if (bindMap != null)
                log.info(">> 查询SQL = [" + dbSql + "] ，入参 = [" + bindMap.toString() + "]");
            else
                log.info(">> 查询SQL = [" + dbSql + "] ，入参 = []");
            sqlResultList = IDMFrameServiceProxy.getSqlTemplate().queryForList(dbSql, bindMap);
            pageInfo = new PageResult<Map<String,Object>>(sqlResultList, sumPage, totleNum,pageNum);
        } catch (Exception e) {
            try {
                throw new CustomException("SQLException：" + e.getCause());
            } catch (CustomException ex) {
                throw new RuntimeException(ex);
            }
        }


        return pageInfo;
    }
}
