package yangtz.cs.liu.campus.service.impl.purchase;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.TaskEntityImpl;
import org.activiti.engine.runtime.ProcessInstance;
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.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import yangtz.cs.liu.activiti.service.IProcessService;
import yangtz.cs.liu.campus.domain.purchase.SchoolPurchase;
import yangtz.cs.liu.campus.domain.purchase.SchoolPurchaseDetails;
import yangtz.cs.liu.campus.mapper.purchase.SchoolPurchaseDetailMapper;
import yangtz.cs.liu.campus.mapper.purchase.SchoolPurchaseMapper;
import yangtz.cs.liu.campus.mapper.teacher.SchoolTeacherLeaveMapper;
import yangtz.cs.liu.campus.service.purchase.ISchoolPurchaseService;
import yangtz.cs.liu.campus.vo.purchase.SchoolPurchaseDetailsVo;
import yangtz.cs.liu.campus.vo.purchase.PurchaseVo;
import yangtz.cs.liu.campus.vo.purchase.SchoolPurchaseVo;
import yangtz.cs.liu.wechat.vo.common.WorkFlowVo;

import javax.annotation.Resource;

import static com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNull;
import static com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank;
import static com.core.constant.ProcessCommon.PENDING;
import static com.core.constant.ProcessCommon.SUSPENDSTATE_PENDING;
import static com.core.constant.ProcessDefinition.DEPARTMENTBUDGET;
import static com.core.constant.ProcessDefinition.PURCHASEREQUEST;
import static com.core.constant.ProcessVariables.*;
import static com.ruoyi.common.utils.SecurityUtils.getUserId;
import static com.ruoyi.common.utils.SecurityUtils.getUsername;
import static com.ruoyi.common.utils.StringUtils.isNotNull;
import static com.ruoyi.common.utils.StringUtils.substring;
import static yangtz.cs.liu.campus.constant.ProcessState.APPROVAL;
import static yangtz.cs.liu.campus.constant.ProcessState.SAVE;

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

/**
 * 采购业务层处理
 */
@Service
public class SchoolPurchaseServiceImpl extends ServiceImpl<SchoolPurchaseMapper, SchoolPurchase> implements ISchoolPurchaseService {
    @Autowired
    private SchoolPurchaseMapper schoolPurchaseMapper;
    @Autowired
    private SchoolPurchaseDetailMapper detailMapper;
    @Resource
    private IdentityService identityService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private IProcessService processService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private SchoolTeacherLeaveMapper schoolTeacherLeaveMapper;

    /**
     * 新增采购申请
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSchoolPurchase(PurchaseVo purchase) {
        SchoolPurchase schoolPurchase = new SchoolPurchase();
        BeanUtils.copyProperties(purchase,schoolPurchase);
        schoolPurchase.setState(SAVE);
        schoolPurchase.setApplyId(getUserId());
        schoolPurchase.setApplyUser(getUsername());
        schoolPurchase.insert();
        int flag = schoolPurchaseMapper.insert(schoolPurchase);
        if(flag > 0){
            if(isNotNull(purchase.getList()) || purchase.getList().size() >0){
                //增子表
                for(SchoolPurchaseDetailsVo details : purchase.getList()){
                    //子表各数据为空时或为""时不可新增空数据
                    if(details.getAssetsTypeName().equals("") && details.getAssetsName().equals("")
                            && details.getAssetsSpecs().equals("") && isNull(details.getAssetsNumbers())
                            && details.getAssetsUnit().equals("") && isNull(details.getAssetsPrice())
                            && isNull(details.getTotalPrice()) && details.getRemark().equals("")){
                        continue;
                    }
                    SchoolPurchaseDetails entity = new SchoolPurchaseDetails();
                    details.setPurchaseId(schoolPurchase.getId());
                    details.insert();
                    BeanUtils.copyProperties(details,entity);
                    detailMapper.insert(entity);
                }
            }
        }
        return flag;
    }

    /**
     * 修改采购申请
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int editSchoolPurchase(PurchaseVo purchase) {
        SchoolPurchase schoolPurchase = new SchoolPurchase();
        BeanUtils.copyProperties(purchase,schoolPurchase);
        schoolPurchase.update();
        int flag = schoolPurchaseMapper.updateById(schoolPurchase);
        if(flag > 0){
            LambdaQueryWrapper<SchoolPurchaseDetails> lqw = new LambdaQueryWrapper<>();
            lqw.eq(SchoolPurchaseDetails::getPurchaseId,purchase.getId());
            detailMapper.delete(lqw);
            if(isNotNull(purchase.getList()) || purchase.getList().size() >0){
                //增子表
                for(SchoolPurchaseDetailsVo details : purchase.getList()){
                    //子表各数据为空时或为""时不可新增空数据
                    if(details.getAssetsTypeName().equals("") && details.getAssetsName().equals("")
                            && details.getAssetsSpecs().equals("") && isNull(details.getAssetsNumbers())
                            && details.getAssetsUnit().equals("") && isNull(details.getAssetsPrice())
                            && isNull(details.getTotalPrice()) && details.getRemark().equals("")){
                        continue;
                    }
                    SchoolPurchaseDetails entity = new SchoolPurchaseDetails();
                    details.setPurchaseId(schoolPurchase.getId());
                    details.insert();
                    BeanUtils.copyProperties(details,entity);
                    detailMapper.insert(entity);
                }
            }
        }
        return flag;
    }

    /**
     * 新增
     * @param schoolPurchase
     * @return
     */
    @Override
    public int addPurchase(SchoolPurchase schoolPurchase) {

        return schoolPurchaseMapper.insert(schoolPurchase);
    }

    /**
     * 采购申请——加载时搜索
     * @param schoolPurchase
     * @return
     */
    @Override
    public List<SchoolPurchaseVo> queryList(String submitState,SchoolPurchase schoolPurchase) {
        /*LambdaQueryWrapper<SchoolPurchase> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SchoolPurchase::getDeptId,schoolPurchase.getDeptId());
        return schoolPurchaseMapper.selectList(lqw);*/
        List<SchoolPurchaseVo> purchaseVos =schoolPurchaseMapper.queryList(submitState, schoolPurchase);
        // 当前环节
        for (SchoolPurchaseVo leave : purchaseVos) {
            if (StringUtils.isNotBlank(leave.getInstanceId())) {
                List<Task> taskList = taskService.createTaskQuery()
                        .processInstanceId(leave.getInstanceId())
                        .list();    // 例如请假会签，会同时拥有多个任务
                if (!CollectionUtils.isEmpty(taskList)) {
                    TaskEntityImpl task = (TaskEntityImpl) taskList.get(0);
                    leave.setTaskId(task.getId());
                    if (task.getSuspensionState() == 2) {
                        leave.setTaskName("已挂起");
                        leave.setSuspendState("2");
                    } else {
                        leave.setTaskName(task.getName());
                        leave.setSuspendState("1");
                    }
                } else {
                    // 已办结或者已撤销
                    leave.setTaskName("已结束");
                }
            } else {
                leave.setTaskName("未启动");
            }
        }
        return purchaseVos;

    }

    /**
     * 采购信息——搜索
     * @param schoolPurchase
     * @return
     */
    @Override
    public List<SchoolPurchase> selectListRegister(SchoolPurchase schoolPurchase) {
        LambdaQueryWrapper<SchoolPurchase> lqw = new LambdaQueryWrapper<>();
        lqw
                .like(isNotBlank(schoolPurchase.getPurchaseName()),SchoolPurchase::getPurchaseName,schoolPurchase.getPurchaseName())
                .eq(SchoolPurchase::getState,0)
                .like(isNotBlank(schoolPurchase.getBudgetName()),SchoolPurchase::getBudgetName,schoolPurchase.getBudgetName());

        return schoolPurchaseMapper.selectList(lqw);
    }

    /**
     *
     * @param schoolPurchase 业务实体
     * @param username       提交申请人 记录到底是哪个人提交了申请
     * @param key            流程标识 用于指定到底启动的是哪个流程(申请流程 审批流程 ） 这里启动的是 申请流程
     * @param variables      变量集合 流程中指定一些变量,这里我们主要用于动态指定审批人
     * @return
     */
    @Override
    public int submitApply(SchoolPurchase schoolPurchase, String username, String key, Map<String, Object> variables) {

        String businessKey = schoolPurchase.getId().toString();
        identityService.setAuthenticatedUserId(username);

        //采购申请人
        variables.put(PURCHASEAPPLYUSERID,schoolPurchase.getApplyId());
        //处室领导
        variables.put(HANDUSERID1,schoolPurchase.getHandUserId1());
        //财务领导
        variables.put(HANDUSERID2,schoolPurchase.getHandUserId2());

        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key, businessKey, variables);
        String instanceId = processInstance.getId();

        //与我们的业务表开始建立关系
        schoolPurchase.setInstanceId(instanceId);
        //审批中
        schoolPurchase.setState(APPROVAL);
        schoolPurchase.setTjzt("1");
        int i = schoolPurchaseMapper.updateById(schoolPurchase);
        SchoolPurchase purchase = schoolPurchaseMapper.selectById(schoolPurchase.getId());
        //转vo
        SchoolPurchaseVo schoolPurchaseVo = new SchoolPurchaseVo();
        BeanUtils.copyProperties(purchase,schoolPurchaseVo);
        //当前登录人待办任务集合
        String userId = SecurityUtils.getLoginUser().getUser().getUserId().toString();
        List<Task> taskList = processService.findAssigneeTasks(userId, PURCHASEREQUEST);
        for (Task task : taskList) {
            TaskEntityImpl taskImpl = (TaskEntityImpl) task;
            //拿到当前任务id
            String processInstanceId = taskImpl.getProcessInstanceId();
            //拿到流程定义对象
            ProcessInstance processInstance1 = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            //业务id(我们当时新增的时候指定了businessKey为id)
            String businessKey1 = processInstance1.getBusinessKey();
            if (businessKey1.equals(businessKey)){
                schoolPurchaseVo.setTaskId(taskImpl.getId());
            }
        }
        String taskId = schoolPurchaseVo.getTaskId();
        Map<String,Object> variables1 = new HashMap<>();
        variables1.put("comment","同意");
        variables1.put("pass","true");
        processService.completeTask(taskId, instanceId, variables1);
        return i;
    }

    /**
     * 代办列表
     * @param key
     * @param entity
     * @param userId
     * @return
     */
    @Override
    public List<SchoolPurchaseVo> toDoList(String key, SchoolPurchase entity, String userId) {
        List<SchoolPurchaseVo> list = new ArrayList<>();
        //当前登录人待办任务集合
        List<Task> taskList = processService.findAssigneeTasks(userId, key);
        for (Task task : taskList) {
            TaskEntityImpl taskImpl = (TaskEntityImpl) task;
            //拿到当前任务id
            String processInstanceId = taskImpl.getProcessInstanceId();
            //拿到流程定义对象
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            //业务id(我们当时新增的时候指定了businessKey为id)
            String businessKey = processInstance.getBusinessKey();
            //通过id查询出我们业务对象
            SchoolPurchase schoolPurchase = schoolPurchaseMapper.selectById(new Long(businessKey));
            if (StringUtils.isNull(schoolPurchase)) {
                continue;
            }
            SchoolPurchaseVo schoolPurchaseVo = new SchoolPurchaseVo();
            BeanUtils.copyProperties(schoolPurchase, schoolPurchaseVo);
            schoolPurchaseVo.setTaskId(taskImpl.getId());
            if (SUSPENDSTATE_PENDING.equals(taskImpl.getSuspensionState())) {
                //挂起
                schoolPurchaseVo.setTaskName(PENDING);
            } else {
                schoolPurchaseVo.setTaskName(taskImpl.getName());
            }
            list.add(schoolPurchaseVo);
        }
        List<SchoolPurchaseVo> resList = list.stream().sorted(Comparator.comparing(SchoolPurchaseVo::getApplyTime).reversed()).collect(Collectors.toList());
        return resList;
    }

    /**
     * 已办列表
     * @param key
     * @param entity
     * @param userId
     * @return
     */
    @Override
    public List<SchoolPurchaseVo> DoneList(String key, SchoolPurchase entity, String userId) {
        List<SchoolPurchaseVo> list = new ArrayList<>();
        //当前登录人完成的历史集合
        List<HistoricTaskInstance> hisList = processService.findDoneTasks(userId, key);
        for (HistoricTaskInstance instance : hisList) {
            //流程实例key
            String processInstanceId = instance.getProcessInstanceId();
            HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .singleResult();
            //业务id
            String businessKey = processInstance.getBusinessKey();
            //通过id查询出我们业务对象
            SchoolPurchase schoolPurchase = schoolPurchaseMapper.selectById(new Long(businessKey));


            if (StringUtils.isNull(schoolPurchase)) {
                continue;
            }
            //转vo
            SchoolPurchaseVo schoolPurchaseVo = new SchoolPurchaseVo();
            BeanUtils.copyProperties(schoolPurchase, schoolPurchaseVo);
            list.add(schoolPurchaseVo);

        }
        List<SchoolPurchaseVo> resList = list.stream().sorted(Comparator.comparing(SchoolPurchaseVo::getApplyTime).reversed()).collect(Collectors.toList());
        return resList;
    }

    //待办和已办
    @Override
    public List<SchoolPurchaseVo> findTasks(String key, String userId) {
        List<SchoolPurchaseVo> list = new ArrayList<>();
        //当前登录人待办任务集合
        List<Task> taskList = processService.findAssigneeTasks(userId, key);
        for (Task task : taskList) {
            TaskEntityImpl taskImpl = (TaskEntityImpl) task;
            //拿到当前任务id
            String processInstanceId = taskImpl.getProcessInstanceId();
            //拿到流程定义对象
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            //业务id(我们当时新增的时候指定了businessKey为id)
            String businessKey = processInstance.getBusinessKey();
            //通过id查询出我们业务对象
            SchoolPurchase schoolPurchase = schoolPurchaseMapper.selectById(new Long(businessKey));
            if (StringUtils.isNull(schoolPurchase)) {
                continue;
            }
            SchoolPurchaseVo schoolPurchaseVo = new SchoolPurchaseVo();
            BeanUtils.copyProperties(schoolPurchase, schoolPurchaseVo);
            schoolPurchaseVo.setTaskId(taskImpl.getId());
            if (SUSPENDSTATE_PENDING.equals(taskImpl.getSuspensionState())) {
                //挂起
                schoolPurchaseVo.setTaskName(PENDING);
            } else {
                schoolPurchaseVo.setTaskName(taskImpl.getName());
            }
            list.add(schoolPurchaseVo);
        }
        //当前登录人完成的历史集合
        List<HistoricTaskInstance> hisList = processService.findDoneTasks(userId, key);
        for (HistoricTaskInstance instance : hisList) {
            //流程实例key
            String processInstanceId = instance.getProcessInstanceId();
            HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .singleResult();
            //业务id
            String businessKey = processInstance.getBusinessKey();
            //通过id查询出我们业务对象
            SchoolPurchase schoolPurchase = schoolPurchaseMapper.selectById(new Long(businessKey));
            if (StringUtils.isNull(schoolPurchase)) {
                continue;
            }
            //转vo
            SchoolPurchaseVo schoolPurchaseVo = new SchoolPurchaseVo();
            BeanUtils.copyProperties(schoolPurchase, schoolPurchaseVo);
            list.add(schoolPurchaseVo);
        }
        List<SchoolPurchaseVo> resList = list.stream().sorted(Comparator.comparing(SchoolPurchaseVo::getApplyTime).reversed()).collect(Collectors.toList());
        return resList;
    }

    /**
     * 待办事项列表搜索
     * @param handUserId
     * @return
     */
    @Override
    public List<SchoolPurchase> findPurchaseName(Long handUserId) {

        return schoolPurchaseMapper.findPurchaseName(handUserId);
    }

    @Override
    public WorkFlowVo purchaseFlows(Long id) {
        SchoolPurchase schoolPurchase = schoolPurchaseMapper.selectById(id);
        String instanceId = schoolPurchase.getInstanceId();
        List<String> messages= schoolTeacherLeaveMapper.selectComment(instanceId);
        WorkFlowVo workFlowVo = new WorkFlowVo();
        List<String> newMessages = new ArrayList<>();
        List<String> handleUserName = new ArrayList<>();
        for (String message : messages) {
            String substring = substring(message, 1, 3);
            newMessages.add(substring);
        }
        handleUserName.add(schoolPurchase.getHandUserName1());
        handleUserName.add(schoolPurchase.getHandUserName2());
        workFlowVo.setComment(newMessages);
        workFlowVo.setHandUserName(handleUserName);
        /*******************通过用户id查询用户的职务*****************************/
        return workFlowVo;
    }

    /**
     * 资金使用明细列表
     * @param schoolPurchase
     * @return
     */
    @Override
    public List<SchoolPurchaseVo> selectPurchaseList(SchoolPurchase schoolPurchase) {
        return schoolPurchaseMapper.selectPurchaseList(schoolPurchase);
    }
}
