package com.highdatas.mdm.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.highdatas.mdm.entity.Flows;
import com.highdatas.mdm.entity.Maintain;
import com.highdatas.mdm.entity.MaintainDetail;
import com.highdatas.mdm.entity.TUser;
import com.highdatas.mdm.pojo.*;
import com.highdatas.mdm.service.*;
import com.highdatas.mdm.service.act.*;
import com.highdatas.mdm.util.DbUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author kimi
 * @description
 * @date 2019-12-17 10:48
 */

@Service
public class ActivitiServiceImpl implements ActivitiService{
    @Autowired
    IdentityService identityService;
    @Autowired
    IMaintainService maintainService;

    @Autowired
    IMaintainDetailService maintainDetailService;

    @Autowired
    TaskService taskService;

    @Autowired
    IFlowsService flowsService;


    @Autowired
    HistoryService historyService;

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    RuntimeService runtimeService;
    @Autowired
    IMaintainFieldService maintainFieldService;

    private TUser user;
    /**
     *
     * @description:  启动流程
     * @param  key 流程key
     * @param  session 请求session
     * @param  maintainId 版本id
     * @param  type 业务类型
     * @return: flows 流程实例
     *
     */
    @Override
    public Flows start(String key, HttpSession session, String maintainId, ActivitiBusinessType type) {
        return start(key, session, maintainId, type, null);
    }

    /**
     *
     * @description:  启动流程
     * @param  key 流程key
     * @param  session 请求session
     * @param  maintainId 版本id
     * @param  type 业务类型
     * @param  params 参数类型
     * @return: flows 流程实例
     *
     */
    @Override
    public Flows start(String key, HttpSession session, String maintainId, ActivitiBusinessType type, Map<String, Object> params) {

        identityService.setSession( session);
        Flows flows = new Flows();
        String id = UUID.randomUUID().toString().replaceAll("-", "");
        flows.setId(id);
        flows.setBusinessId(maintainId);
        flows.setBusinessType(type);
        flows.setStatus(ActivitiStatus.working);
        HashMap<String, Object> variableMap = new HashMap<>();
        if (params != null) {
            variableMap.putAll(params);
        }
        variableMap.put("reason", "申请审批");

        String workflowId = identityService.startProcess(id, key, null, variableMap);
        flows.setWorkflowId(workflowId);
        flows.setCreateTime(new Date());
        TUser user = null;
        if (session != null) {
            user = (TUser) session.getAttribute("user");
        }else  {
            user = this.user;
        }
        if (user == null) {
            return null;
        }

        String user_id = user.getUserId();
        flows.setUserId(user_id);
        boolean inserted = flowsService.insert(flows);
        if (inserted) {
            return flows;
        } else {
            return null;
        }
    }
    /**
     *
     * @description:  获取待审批列表
     * @param  tableName 表名
     * @param  session 请求session
     * @param  pageNo 页数
     * @param  pageSize 每页条数
     * @return: result 待处理流程list
     *
     */
    @Override
    public Result todoTask(HttpSession session, String tableName, Integer pageNo, Integer pageSize) {
        taskService.setSession(session);
        List<String> todoTask = taskService.getTodoTask();
        if (todoTask.size() == 0) {
            return Result.success(CodeMsg.SUCCESS);
        }

        Wrapper<Flows> flowsWrapper = new EntityWrapper<Flows>().in("workflow_id", todoTask).ne("business_type", ActivitiBusinessType.exists);
        flowsWrapper.orderBy("create_time desc");
        List<Flows> records = flowsService.selectList(flowsWrapper);

        List<Flows> result = new ArrayList<>();

        if (!StringUtils.isEmpty(tableName)) {

            List<Flows> maintainList = records.stream()
                    .filter(flows -> flows.getBusinessType().equals(ActivitiBusinessType.maintain))
                    .filter(flows -> (!flows.getStatus().equals(ActivitiStatus.open) || !flows.getStatus().equals(ActivitiStatus.close)))
                    .filter(flows -> maintainService.selectById(flows.getBusinessId()) != null)
                    .filter(flows -> maintainService.selectById(flows.getBusinessId()).getTableName().equalsIgnoreCase(tableName)).collect(Collectors.toList());
            List<Flows> collect = records.stream()
                    .filter(flows -> flows.getBusinessType().equals(ActivitiBusinessType.field))
                    .filter(flows -> (!flows.getStatus().equals(ActivitiStatus.open) || !flows.getStatus().equals(ActivitiStatus.close)))
                    .filter(flows -> maintainFieldService.selectById(flows.getBusinessId()) != null)
                    .filter(flows -> maintainFieldService.selectById(flows.getBusinessId()).getTableName().equalsIgnoreCase(tableName)).collect(Collectors.toList());
            records = new ArrayList<>();

            records.addAll(maintainList);
            records.addAll(collect);
        }
        Page page = new Page(records.size());
        page.setPageNo(pageNo);
        if (pageSize != null) {
            page.setPageSize(pageSize);
        }
        records = records.stream().skip(page.getBeginRecordNo_1()).limit(pageSize).collect(Collectors.toList());

        for (Flows flow : records) {
            String userId = flow.getUserId();
            TUser user = DbUtils.getUserById(userId);
            if (user == null) {
                continue;
            }
            flow.setUserId(user.getUserName());

            String businessId = flow.getBusinessId();
            int recordCount = maintainDetailService.selectCount(new EntityWrapper<MaintainDetail>().eq("parent_id", businessId));

            if (!StringUtils.isEmpty(tableName)) {
                Maintain maintain = maintainService.selectById(businessId);
                if (maintain == null) {
                    continue;
                }
                if (!maintain.getTableName().equalsIgnoreCase(tableName)) {
                    continue;
                }
                flow.setRecordCount(recordCount);
            }
            result.add(flow);
        }

        com.baomidou.mybatisplus.plugins.Page<Flows> flowPages = new com.baomidou.mybatisplus.plugins.Page<>();
        flowPages.setRecords(records);
        flowPages.setSize(pageSize);
        flowPages.setCurrent(pageNo);
        flowPages.setTotal(page.getRecordCount());
        return Result.success(flowPages);
    }

    /**
     *
     * @description:  保存用户信息到流程服务里
     * @param  user 用户信息
     * @return: void
     *
     */

    @Override
    public void setUser(TUser user) {
        this.user = user;
        identityService.setUser(user);
        taskService.setUser(user);
        historyService.setUser(user);
        runtimeService.setUser(user);
        repositoryService.setUser(user);
    }
    /**
     *
     * @description:  获取用户信息到流程服务里
     * @return: void
     *
     */
    @Override
    public TUser getUser() {
        return this.user;
    }
}