package com.xtd.project.activiti.service.impl;

import com.xtd.framework.web.page.PageDomain;
import com.xtd.framework.web.page.TableDataInfo;
import com.xtd.framework.web.page.TableSupport;
import com.xtd.project.activiti.domain.MyFormDataActivitiExample;
import com.xtd.project.activiti.domain.MyProcessInstance;
import com.xtd.project.activiti.domain.MyTask;
import com.xtd.project.activiti.domain.TreeVo;
import com.xtd.project.activiti.mapper.MyFormDataActivitiMapper;
import com.xtd.project.activiti.service.ProcessInstanceService;
import com.xtd.project.assets.domain.DbTableHis;
import com.xtd.project.assets.mapper.DbTableHisMapper;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.identity.User;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProcessInstanceServiceImpl implements ProcessInstanceService {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private MyFormDataActivitiMapper myFormDataActivitiMapper;

    @Autowired
    private IdentityService identityService;

    @Override
    public TableDataInfo list() {
        TableDataInfo tableDataInfo = getTableDataInfo();
        return tableDataInfo;
    }

    private TableDataInfo getTableDataInfo() {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setCode(200);
        int size = runtimeService.createProcessInstanceQuery().list().size();
        tableDataInfo.setTotal(size);
        pageNum = (pageNum - 1) * pageSize;
        List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().listPage(pageNum, pageSize);
        List<MyProcessInstance> collect = list.stream().map(x -> {
            MyProcessInstance myProcessInstance = new MyProcessInstance();
            List<Task> listTask = taskService.createTaskQuery().processInstanceId(x.getId()).list();
            String taskName = "";
            for (Task task : listTask) {
                taskName += task.getName() + "/";

            }
            if (!StringUtils.isEmpty(taskName)) {
                taskName = taskName.substring(0, taskName.length() - 1);
                myProcessInstance.setNextTask(taskName);
            }
            BeanUtils.copyProperties(x, myProcessInstance);
            return myProcessInstance;
        }).collect(Collectors.toList());
        tableDataInfo.setRows(collect);
        return tableDataInfo;
    }

    private List<TreeVo> getTreeVos() {
        List<User> users = identityService.createUserQuery().list();
        //用户树信息
        return users.stream().map(x -> {
            TreeVo childrenTreeVo = new TreeVo();
            childrenTreeVo.setValue(x.getId());
            childrenTreeVo.setLabel(x.getFirstName());
            return childrenTreeVo;
        }).collect(Collectors.toList());
    }


    @Override
    public void suspendProcess(String processInstanceId, Integer status) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().
                processInstanceId(processInstanceId).singleResult();
        if (null == processInstance) {
            throw new RuntimeException("不存在正在执行的流程实例:[ " + processInstanceId + " ]");
        }
        //挂起流程
        if (1 == status) {
            runtimeService.suspendProcessInstanceById(processInstanceId);
        }
        //激活流程
        else {
            runtimeService.activateProcessInstanceById(processInstanceId);
        }

    }


    @Override
    public void deleteProcess(String processInstanceId) {
        runtimeService.deleteProcessInstance(processInstanceId, "cascade");
        MyFormDataActivitiExample example = new MyFormDataActivitiExample();
        MyFormDataActivitiExample.Criteria criteria = example.createCriteria();
        criteria.andInstanceIdEqualTo(processInstanceId);
        myFormDataActivitiMapper.deleteByExample(example);
    }
    @Autowired
    private DbTableHisMapper dbTableHisMapper;
    @Override
    public void deleteProcess(List<String> list) {
        for (String processInstanceId : list) {
            runtimeService.deleteProcessInstance(processInstanceId, "cascade");
            MyFormDataActivitiExample example = new MyFormDataActivitiExample();
            MyFormDataActivitiExample.Criteria criteria = example.createCriteria();
            criteria.andInstanceIdEqualTo(processInstanceId);
            myFormDataActivitiMapper.deleteByExample(example);
        }

    }

    @Override
    public void transToOffice(String taskId, String userId) {
        taskService.setAssignee(taskId, userId);
        taskService.setOwner(taskId, userId);
    }

    @Override
    public void entrust(String taskId, String userId) {
        taskService.delegateTask(taskId, userId);
    }

    @Override
    public List<TreeVo> listTask(String processInstanceId) {
        List<Task> listTask = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
        List<TreeVo> collect = listTask.stream().map(x -> {
            TreeVo treeVo = new TreeVo();
            treeVo.setLabel(x.getName());
            treeVo.setValue(x.getId());
            return treeVo;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<TreeVo> listUser() {
        List<User> users = identityService.createUserQuery().list();
        //用户树信息
        return users.stream().map(x -> {
            TreeVo childrenTreeVo = new TreeVo();
            childrenTreeVo.setValue(x.getId());
            childrenTreeVo.setLabel(x.getFirstName());
            return childrenTreeVo;
        }).collect(Collectors.toList());
    }
}
