package com.huigou.topsun.base.bsnMessage.appliction.impl;

import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.data.query.model.QueryModel;
import com.huigou.topsun.base.bsnMessage.appliction.BsnMessageApplication;
import com.huigou.topsun.base.bsnMessage.domain.*;
import com.huigou.topsun.base.bsnMessage.domain.query.BsnMessageQueryRequest;
import com.huigou.topsun.base.bsnMessage.repository.BsnMessageExecuteRepository;
import com.huigou.topsun.base.bsnMessage.repository.BsnMessageRejectRepository;
import com.huigou.topsun.base.bsnMessage.repository.BsnMessageSponsorRepository;
import com.huigou.topsun.sap.nonProdApply.domain.SapNonProdApplyDept;
import com.huigou.uasp.bmp.bizconfig.model.ObjectKindEnum;
import com.huigou.uasp.bmp.common.application.BaseApplication;
import com.huigou.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Sort;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 专项任务整合及输出
 */
@Service("bsnMessageApplication")
public class BsnMessageApplicationImpl extends BaseApplication implements BsnMessageApplication {

    @Autowired
    BsnMessageExecuteRepository messageExecuteRepository;
    @Autowired
    BsnMessageRejectRepository messageRejectRepository;
    @Autowired
    BsnMessageSponsorRepository messageSponsorRepository;


    @Override
    public String keepTasks(BsnMessageSponsor bsnMessageSponsor) {
        //删除对应表单已有的任务
        BsnMessageSponsor sponsor = this.getSponsorByBId(bsnMessageSponsor.getBusinessId());
        if (sponsor != null) {
            BsnMessageExecute systemExecute = this.getSystemExecuteByMsId(sponsor.getId());
            sponsor.addExecute(systemExecute);
            this.deleteBsnMessageSponsor(sponsor);
        }
        //封装任务发布人自己的审批任务
        BsnMessageExecute execute = new BsnMessageExecute();
        execute.setUpdateDate(new Date());
      //  execute.setTaskExecute(this.getOperator().getUserId());
        execute.setTaskDescribe("各单位已完成[发起人审核]");
        execute.setBusinessCode("system");
        execute.setActive(ActiveStatus.SAVED.getValue());
        bsnMessageSponsor.addExecute(execute);
        return this.saveBsnMessageSponsor(bsnMessageSponsor);
    }

    @Override
    public void publishTasks(String bId) {
        BsnMessageSponsor sponsor = messageSponsorRepository.findByBusinessId(bId);
        if (sponsor == null) {
            throw new RuntimeException("不存在该业务");
        }
        List<BsnMessageExecute> executes = this.getExecutesByMsId(sponsor.getId());
        for (BsnMessageExecute execute :executes) {
            execute.setActive(ActiveStatus.UNFINISHED.getValue());
            if  ("INIT_DPT".equals(execute.getBusinessCode())){  //是产品推送的 把待办去掉
                execute.setActive(ActiveStatus.FINISHED.getValue());
            }
        }
        this.saveBsnMessageExecute(executes);
    }


    @Override
    public void keepAndPublishTasks(BsnMessageSponsor bsnMessageSponsor) {
        for (BsnMessageExecute execute :bsnMessageSponsor.getExecutes()) {
            execute.setActive( ActiveStatus.UNFINISHED.getValue());
        }
        this.keepTasks(bsnMessageSponsor);
    }

    @Override
    public void authorizeTasks(String bId) {
        BsnMessageSponsor sponsor = this.getSponsorByBId(bId);
        sponsor.setStatus(2);
        for (BsnMessageExecute execute : sponsor.getExecutes()) {
            execute.setActive(ActiveStatus.FINISHED.getValue());
        }
        this.saveBsnMessageSponsor(sponsor);
    }

    public void rejectTasks(Map<String, Object> exMap, BsnMessageSponsor sponsor) {
        if (sponsor != null) {
            List<BsnMessageExecute> brotherExecuteAll = sponsor.getExecutes();
            Map<String, BsnMessageExecute> executeMap = new HashMap<>();
            Date date = new Date();
            for (BsnMessageExecute execute : brotherExecuteAll) {
                executeMap.put(execute.getTaskExecute(), execute);
            }
            for (String key : exMap.keySet()) {
                BsnMessageExecute execute = executeMap.get(key);
                if (execute != null) {
                    //更改驳回状态
                    execute.setActive(ActiveStatus.REJECTED.getValue());
                    //更新时间
                    execute.setUpdateDate(date);
                    //封装驳回详情
                    BsnMessageReject reject = new BsnMessageReject();
                    reject.setRejectMsg((String) exMap.get(key));
                    reject.setRejectDate(date);
                    reject.setBsnExecuteId(execute.getId());
                    execute.addReject(reject);
                    this.saveBsnMessageExecute(execute);
                }
            }
            //当前审核任务回退
            BsnMessageExecute systemExecute = this.getSystemExecuteByMsId(sponsor.getId());
            systemExecute.setActive(ActiveStatus.SAVED.getValue());
            this.saveBsnMessageExecute(systemExecute);
            //流程退回等待
            sponsor.setStatus(0);
            this.saveBsnMessageSponsor(sponsor);
        }

    }

    @Override
    public void rejectTasksByMeId(Map<String, Object> exMap, String mId) {
        BsnMessageExecute execute = messageExecuteRepository.findOne(mId);
        List<BsnMessageExecute> executes = this.getExecutesByMsId(execute.getMessageSponsorId());
        BsnMessageSponsor sponsor = messageSponsorRepository.findOne(execute.getMessageSponsorId());
        sponsor.setExecutes(executes);
        this.rejectTasks(exMap,sponsor);
    }

    @Override
    public void rejectTasksByBId(Map<String, Object> exMap, String bId) {
        BsnMessageSponsor sponsor = this.getSponsorByBId(bId);
        this.rejectTasks(exMap,sponsor);
    }

    @Override
    public void submitTask(String meId) {
        BsnMessageExecute execute = this.getExecuteByMeId(meId);
        execute.setActive(ActiveStatus.FINISHED.getValue());
        execute.setFinishedDate(new Date());
        this.saveBsnMessageExecute(execute);
    }

    //    @Override
    public Map<String, Object> circulate(String meId) {
        BsnMessageExecute execute = this.getExecuteByMeId(meId);
        Map<String, Object> paramMap = new HashMap<>();
        if (execute==null){
            return paramMap;
        }
        paramMap.put("deptCode", execute.getBusinessCode());
        paramMap.put("active", execute.getActive());
        paramMap.put("meId", execute.getId());
        paramMap.put("isReadOnly", "false");
        if ("system".equals(execute.getBusinessCode())) {
            //获取该业务流程下其他执行部门
            List<BsnMessageExecute> executeAll = this.getExecutesByMsId(execute.getMessageSponsorId());
            Map<String, String> map = executeAll.stream()
                    .collect(Collectors.toMap(BsnMessageExecute::getTaskExecute, BsnMessageExecute::getBusinessCode));
            paramMap.put("auditDeptMap", map);
        }
        return paramMap;
    }

    @Override
    public Map<String, Object> queryExecuteBsnMessage() {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "queryExecuteBsnMessage");
        QueryModel queryModel = new QueryModel();
        queryModel.setSql(queryDescriptor.getSql());
        queryModel.setPageIndex(1);
        queryModel.setPageSize(10);
        queryModel.setSortFieldName("updateDate");
        queryModel.setSortOrder("desc");
        queryModel.putParam("taskExecute", this.getOperator().getUserId());
        queryModel.putParam("addText", "[驳回]");
        return this.sqlExecutorDao.executeSlicedQuery(queryModel);
    }

    @Override
    public Map<String, Object> queryExecuteBsnMessage(BsnMessageQueryRequest query) {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "queryExecuteBsnMessage");
       // QueryModel queryModel = new QueryModel();
        QueryModel queryModel = this.sqlExecutorDao.getQueryModel(queryDescriptor, query);
        queryModel.setSql(queryDescriptor.getSql());

        if (StringUtil.isNotBlank(query.getTaskDescribe())) {
            queryModel.addCriteria("  and  t.task_describe like:taskDescribe");
            queryModel.putLikeParam("taskDescribe", query.getTaskDescribe());
        }
        if (StringUtil.isNotBlank(query.getTitle())) {
            queryModel.addCriteria("  and ad.maktx like:title");
            queryModel.putLikeParam("title", query.getTitle());
        }
        queryModel.setSortFieldName("updateDate");
        queryModel.setSortOrder("desc");

        queryModel.putParam("taskExecute", this.getOperator().getUserId());
        queryModel.putParam("addText", "[驳回]");
        return this.sqlExecutorDao.executeSlicedQuery(queryModel);
    }

    @Override
    public List<BsnMessageSponsor> queryFinishBsnMessageSponsor() {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "queryFinishBsnMessageSponsor");
        return this.sqlExecutorDao.queryToList(queryDescriptor.getSql(), BsnMessageSponsor.class, this.getOperator().getUserId());
    }


    @Override
    public BsnMessageExecute isExecutesReady(String msId) {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "queryIsExecutesReady");
        return this.sqlExecutorDao.queryToObject(queryDescriptor.getSql(), BsnMessageExecute.class, msId, msId);
    }


    public String saveBsnMessageSponsor(BsnMessageSponsor entity) {
        String keyId = messageSponsorRepository.save(entity).getId();
        if (isNotEmpty(entity.getExecutes())) {
            entity.getExecutes().forEach(item -> item.setMessageSponsorId(keyId));
            messageExecuteRepository.save(entity.getExecutes());
        }
        return keyId;
    }

    @Override
    public void saveBsnMessageExecute(List<BsnMessageExecute> all) {
        messageExecuteRepository.save(all);
    }

    public String saveBsnMessageExecute(BsnMessageExecute entity) {
        String keyId = messageExecuteRepository.save(entity).getId();
        if (isNotEmpty(entity.getRejects())) {
            entity.getRejects().forEach(item -> item.setBsnExecuteId(keyId));
            messageRejectRepository.save(entity.getRejects());
        }
        return keyId;
    }


    public void deleteBsnMessageSponsor(BsnMessageSponsor entity) {
        if (isNotEmpty(entity.getExecutes())) {
            List<BsnMessageExecute> list=entity.getExecutes();
            for (BsnMessageExecute bsnMessageExecute:list) {
                if (bsnMessageExecute!=null){
                    messageExecuteRepository.delete(bsnMessageExecute);
                }
            }
        }
        messageSponsorRepository.delete(entity);
    }


    /**
     * 获取流程下的执行人，不含审批任务
     *
     * @param msId
     * @return
     */
    public List<BsnMessageExecute> getExecutesByMsId(String msId) {
        List<BsnMessageExecute> exList = messageExecuteRepository.findAllByMessageSponsorId(msId);
        Iterator<BsnMessageExecute> iterator = exList.iterator();
        while (iterator.hasNext()) {
            BsnMessageExecute execute = iterator.next();
            if ("system".equals(execute.getBusinessCode())) {
                iterator.remove();
            }
        }
        return exList;
    }


    public BsnMessageExecute getExecuteByMeId(String mId) {
        return messageExecuteRepository.findOne(mId);
    }

    //获取审批任务
    public BsnMessageExecute getSystemExecuteByMsId(String msId) {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "querySystemExecute");
        return this.sqlExecutorDao.queryToObject(queryDescriptor.getSql(), BsnMessageExecute.class, msId);
    }

    @Override
    public List<BsnMessageReject> getRejectDetail(String meId) {
        Sort sort = new Sort(Sort.Direction.DESC, "rejectDate");
        return messageRejectRepository.findAllByBsnExecuteId(meId, sort);
    }


    public BsnMessageSponsor getSponsorByBId(String bId) {
        BsnMessageSponsor sponsor = messageSponsorRepository.findByBusinessId(bId);
        if (sponsor != null) {
            List<BsnMessageExecute> executeList = this.getExecutesByMsId(sponsor.getId());
            sponsor.setExecutes(executeList);
        }
        return sponsor;
    }

    public boolean isNotEmpty(List<?> list) {
        return list != null && !list.isEmpty();
    }



}
