package cn.gtmap.estateplat.config.service.impl;

import cn.gtmap.estateplat.config.core.service.*;
import cn.gtmap.estateplat.config.service.ProjectChecklimitFiledService;
import cn.gtmap.estateplat.config.utils.Constants;
import cn.gtmap.estateplat.config.utils.PlatformUtil;
import cn.gtmap.estateplat.core.support.mybatis.mapper.EntityMapper;
import cn.gtmap.estateplat.model.server.core.*;
import cn.gtmap.estateplat.utils.CommonUtil;
import com.google.common.collect.Lists;
import com.gtis.config.AppConfig;
import com.gtis.plat.service.SysWorkFlowInstanceService;
import com.gtis.plat.vo.PfWorkFlowInstanceVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.Table;
import java.util.*;

/**
 * @version 1.0, 2017/6/30.
 * @auto <a href="mailto:zhouwanqing@gtmap.cn">zhouwanqing</a>
 * @description
 */
@Service
public class ProjectChecklimitFiledServiceImpl implements ProjectChecklimitFiledService {
    @Autowired
    SysWorkFlowInstanceService sysWorkFlowInstanceService;
    @Autowired
    BdcXmService bdcXmService;
    @Autowired
    BdcZdGlService bdcZdGlService;
    @Autowired
    PlatformUtil platformUtil;
    @Autowired
    QllxService qllxService;
    @Autowired
    TableService tableService;
    @Autowired
    EntityMapper entityMapper;
    @Autowired
    WorkFlowService workFlowService;
    @Autowired
    BdcXtLimitfieldService bdcXtLimitfieldService;

    /**
     * @param proid  工作流项目ID
     * @param taskid 任务ID
     * @return
     * @description 根据验证信息去查看是否有错误信息
     */
    @Override
    public List<Map> validateMsg(final String taskid, final String proid) {
        //结果集合
        Set<Map> resultList = new HashSet<Map>();
        //结果map
        HashMap resultMap;
        List<String> wfDfids = new ArrayList<String>();
        List<String> actyIds = new ArrayList<String>();
        List<String> proids = new ArrayList<String>();
        String qllx = "";
        //暂时不考虑商品房共有业主流程，因为选择户太多影响效率
        if (StringUtils.isNotBlank(taskid) && StringUtils.isNotBlank(proid)) {
            BdcXm bdcXm = entityMapper.selectByPrimaryKey(BdcXm.class, proid);
            /**
             * @author <a href="mailto:sunchao@gtmap.cn">sunchao</a>
             * @description 读取配置商品房共有业主是否验证 如果是true则验证
             */
            String spfisyz = AppConfig.getProperty("spfisyz");
            if (bdcXm != null && (!StringUtils.equals(bdcXm.getSqlx(), Constants.SQLX_SPFGYSCDJ_DM) || StringUtils.equals(spfisyz, "true"))) {

                PfWorkFlowInstanceVo pfWorkFlowInstanceVo = sysWorkFlowInstanceService.getWorkflowInstance(bdcXm.getWiid());
                if (pfWorkFlowInstanceVo != null && StringUtils.isNotBlank(pfWorkFlowInstanceVo.getWorkflowDefinitionId())) {

                    String sqlxdm = bdcZdGlService.getSqlxDmByWdid(pfWorkFlowInstanceVo.getWorkflowDefinitionId());
                    List<BdcXm> bdcXmList = bdcXmService.getBdcXmListByWiid(bdcXm.getWiid());
                    if (CommonUtil.indexOfStrs(Constants.SQLX_hblc_zlc, sqlxdm) && CollectionUtils.isNotEmpty(bdcXmList)) {
                        //合并流程
                        for (BdcXm bdcXm1 : bdcXmList) {
                            String childNodeWdid = bdcZdGlService.getWdidBySqlxDm(bdcXm1.getSqlx());
                            //当前结点名称
                            String actyId = platformUtil.getPfActivityIdByTaskId(taskid);
                            String nodeName = workFlowService.getWorkflowNodeName(actyId, pfWorkFlowInstanceVo.getWorkflowDefinitionId());
                            String childNodeId = null;
                            if (StringUtils.isNotBlank(nodeName))
                                childNodeId = workFlowService.getWorkflowNodeId(nodeName, childNodeWdid);
                            if (StringUtils.isNotBlank(childNodeWdid) && StringUtils.isNotBlank(childNodeId)) {
                                wfDfids.add(childNodeWdid);
                                actyIds.add(childNodeId);
                                proids.add(bdcXm1.getProid());
                            }
                        }

                    } else if (CommonUtil.indexOfStrs(Constants.SPYZ_DQPROID_SQLX, sqlxdm)) {
                        //wfDfids.add(bdcXm.getWiid());
                        wfDfids.add(pfWorkFlowInstanceVo.getWorkflowDefinitionId());
                        actyIds.add(platformUtil.getPfActivityIdByTaskId(taskid));
                        proids.add(bdcXm.getProid());
                    } else {
                        //其他流程
                        for (BdcXm bdcXm1 : bdcXmList) {
                            if (StringUtils.isNotBlank(bdcXm1.getSqlx()) && !CommonUtil.indexOfStrs(Constants.SQLX_DRBG, bdcXm1.getSqlx())) {
                                String wdid = pfWorkFlowInstanceVo.getWorkflowDefinitionId();
                                //当前结点名称
                                String actyId = platformUtil.getPfActivityIdByTaskId(taskid);
                                if (StringUtils.isNotBlank(wdid) && StringUtils.isNotBlank(actyId)) {
                                    wfDfids.add(wdid);
                                    actyIds.add(actyId);
                                    proids.add(bdcXm1.getProid());
                                }
                            }
                        }
                    }
                }
            }

        } else {
            return Lists.newArrayList(resultList);
        }

        if (CollectionUtils.isNotEmpty(proids) && CollectionUtils.size(wfDfids) == CollectionUtils.size(actyIds) && CollectionUtils.size(actyIds) == CollectionUtils.size(proids)) {
            int k = 0;
            for (String wfDfid : wfDfids) {
                String actyId = actyIds.get(k);
                String tmpProid = proids.get(k);
                //参数map
                HashMap paraMap = new HashMap();
                paraMap.put("workflowId", wfDfid);
                paraMap.put("workflowNodeId", actyId);

                //获取项目中的qllx
                String xmCptName = "";
                if (StringUtils.isNotBlank(tmpProid)) {
                    BdcXm bdcXm = entityMapper.selectByPrimaryKey(BdcXm.class, tmpProid);
                    if (bdcXm != null) {
                        qllx = bdcXm.getQllx();
                        /**
                         * @date: 2016年3月17日 18:30
                         * @aothor ：xiahui
                         * @description ：由于独幢和多幢权利类型都为4，故需要另外加上cptName作为查询调价过滤掉多幢的
                         * 1.通过bdcXm权利类型QllxVo，并判断是否为4。
                         * 2.判断QllxVo是否属于多幢（BdcFdcqDz），多幢则cptName为bdc_fdcq_dz即BdcFdcqDz的table注解的name值
                         *   否则为bdc_fdcq即BdcFdcq的table注解的name值，此处用Annotation获取
                         */
                        QllxVo qllxVO = qllxService.makeSureQllx(bdcXm);//通过bdcXm权利类型QllxVo
                        Table table = null;
                        //判断QllxVo是否属于多幢（BdcFdcqDz）
                        if (qllxVO instanceof BdcFdcqDz) {
                            xmCptName = BdcFdcq.class.getAnnotation(Table.class).name();
                        } else if (qllxVO instanceof BdcFdcq) {
                            xmCptName = BdcFdcqDz.class.getAnnotation(Table.class).name();
                        } else {
                            if (k > 0) {
                                BdcZdQllx bdcZdQllx = bdcZdGlService.getBdcZdQllxByDm(qllx);
                                String cpt = bdcZdQllx.getTableName().toLowerCase();
                                paraMap.put("cpt", cpt);
                            }
                        }
                        //zhouwanqing 这边区分只能用排除，不然收件单和审批表的验证就不验证了
                        paraMap.put("cptName", xmCptName);
                    }
                }


                //房地产权利分多幢查询验证条件
                //获取验证的信息
                List<Map> validateList = bdcXtLimitfieldService.getWorkflowTransmitValidates(paraMap);
                //存储运行sql后的数据
                List<Map> validateDataList = new ArrayList<Map>();
                //是否已经存在错误
                boolean hasError = false;
                //第一个有问题的表单名称
                String cptName = "";
                String tableId = "";
                if (validateList != null && validateList.size() > 0) {
                    for (int i = 0; i < validateList.size(); i++) {
                        Map validateMap = validateList.get(i);
                        //判斷是否為独幢或多幢 独幢去除多幢的验证条件
                        if (StringUtils.isBlank(xmCptName)) {
                            if (StringUtils.equals("BDC_FDCQ_DZ", ((String) validateMap.get("CPT_NAME")).toUpperCase())) {
                                continue;
                            }
                        }
                        //判断是否是同一个表单
                        if (cptName != "" && !StringUtils.equals(cptName, (String) validateMap.get("CPT_NAME"))) {
                            //判断是否已经有错误了，若有没有
                            if (hasError) {
                                continue;
                            } else {
                                cptName = (String) validateMap.get("CPT_NAME");
                            }
                        }
                        //不相等 重新取数据
                        if (!StringUtils.equals(tableId, (String) validateMap.get("TABLE_ID"))) {
                            if (cptName == "") {
                                cptName = (String) validateMap.get("CPT_NAME");
                            }
                            //替换tableId
                            tableId = (String) validateMap.get("TABLE_ID");
                            //执行sql
                            String sql = StringUtils.replace((String) validateMap.get("TABLE_XMREL_SQL"), "@proid", "'" + tmpProid + "'");
                            validateDataList = tableService.runSql(PlatformUtil.initOptProperties(sql));
                        }

                        //用qllx过滤 qllx为0或空是通用验证
                        if (StringUtils.isNotBlank(CommonUtil.formatEmptyValue(validateMap.get("QLLX"))) && !"0".equals(validateMap.get("QLLX")) && !StringUtils.equals(qllx, CommonUtil.formatEmptyValue(validateMap.get("QLLX")))) {
                            continue;
                        } else {
                            //判断是否有数据  没有的话直接存入错误信息
                            if (validateDataList == null || validateDataList.size() == 0) {
                                //已产生错误，只提示一个表单的错误
                                hasError = true;
                                resultMap = new HashMap();
                                //存储错误
                                resultMap.put("error", validateMap.get("CPT_DESC") + "中" + validateMap.get("TABLE_FIELD_NAME") + "不能为空");
                                resultList.add(resultMap);
                            } else {
                                //没有存入错误
                                boolean notHasError = true;
                                //循环验证必填字段是否有值
                                for (int j = 0; j < validateDataList.size(); j++) {
                                    Map validateDataMap = validateDataList.get(j);
                                    //如果存入错误 跳出
                                    if (!notHasError) {
                                        break;
                                    }
                                    //如果没有值
                                    if (validateDataMap.get(validateMap.get("TABLE_FIELD_ID").toString().toUpperCase()) == null || StringUtils.isBlank(validateDataMap.get(validateMap.get("TABLE_FIELD_ID").toString().toUpperCase()).toString())) {
                                        //已产生错误，只提示一个表单的错误
                                        hasError = true;
                                        resultMap = new HashMap();
                                        //存储错误
                                        notHasError = false;
                                        resultMap.put("error", validateMap.get("CPT_DESC") + "中" + validateMap.get("TABLE_FIELD_NAME") + "不能为空");
                                        resultList.add(resultMap);
                                    }
                                }

                            }
                        }
                    }
                }
                k++;
            }
        }
        return Lists.newArrayList(resultList);
    }

}
