package com.ym.mec.education.service.impl;

import com.google.common.collect.Lists;
import com.ym.mec.education.base.BaseResponse;
import com.ym.mec.education.base.PageResponse;
import com.ym.mec.education.entity.SysRole;
import com.ym.mec.education.entity.SysUser;
import com.ym.mec.education.req.ApprovalReq;
import com.ym.mec.education.resp.ApprovalResp;
import com.ym.mec.education.service.ApprovalService;
import com.ym.mec.education.service.ISysRoleService;
import com.ym.mec.education.service.ISysUserService;
import org.apache.commons.lang3.StringUtils;
import org.snaker.engine.IQueryService;
import org.snaker.engine.access.Page;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.core.AccessService;
import org.snaker.engine.core.OrderService;
import org.snaker.engine.entity.HistoryOrder;
import org.snaker.engine.entity.HistoryTask;
import org.snaker.engine.entity.Task;
import org.snaker.engine.entity.WorkItem;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @program: mec
 * @description: 教务审批
 * @author: xw
 * @create: 2019-10-11 15:35
 */
@Service
public class ApprovalServiceImpl implements ApprovalService {

    @Autowired
    private IQueryService queryService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private ISysRoleService roleService;

    @Override
    public PageResponse<ApprovalResp> getProcessingList(ApprovalReq approvalReq) {
        if (Objects.isNull(approvalReq.getUserId())) {
            return PageResponse.errorParam();
        }
        Page<WorkItem> page = new Page();
        page.setPageNo(approvalReq.getPageNo());
        page.setPageSize(approvalReq.getPageSize());
        QueryFilter queryFilter = new QueryFilter();
        queryFilter.setOperator(approvalReq.getUserId().toString());
        queryService.getWorkItems(page, queryFilter);
        return PageResponse.success(workItem2Approval(page));
    }

    @Override
    public PageResponse<ApprovalResp> getProcessedList(ApprovalReq approvalReq) {
        if (Objects.isNull(approvalReq.getUserId())) {
            return PageResponse.errorParam();
        }
        Page<WorkItem> page = new Page();
        page.setPageNo(approvalReq.getPageNo());
        page.setPageSize(approvalReq.getPageSize());
        QueryFilter queryFilter = new QueryFilter();
        queryFilter.setOperator(approvalReq.getUserId().toString());
        queryService.getHistoryWorkItems(page, queryFilter);
        return PageResponse.success(workItem2Approval(page));
    }

    @Override
    public PageResponse<ApprovalResp> getLaunchList(ApprovalReq approvalReq) {
        if (Objects.isNull(approvalReq.getUserId())) {
            return PageResponse.errorParam();
        }
        Page<HistoryOrder> page = new Page();
        page.setPageNo(approvalReq.getPageNo());
        page.setPageSize(approvalReq.getPageSize());
        QueryFilter queryFilter = new QueryFilter();
        queryFilter.setOperator(approvalReq.getUserId().toString());
        if (StringUtils.isNotBlank(approvalReq.getApprovalType())) {
            queryFilter.setDisplayName(approvalReq.getApprovalType());
        }
        queryService.getHistoryOrders(page, queryFilter);
        Page<ApprovalResp> pageResult = new Page();
        BeanUtils.copyProperties(page, pageResult);
        List<ApprovalResp> list = new ArrayList<>(page.getResult().size());
        if (!CollectionUtils.isEmpty(page.getResult())) {
            page.getResult().forEach(item -> {
                ApprovalResp approvalResp = initApprovalResp(item.getVariable(), userService.getById(item.getCreator()));
                approvalResp.setOrderId(item.getId()).setApprovalType(item.getProcessName()).setApprovalDate(item.getCreateTime())
                    .setOrderState(item.getOrderState());
                list.add(approvalResp);
            });
        }
        pageResult.setResult(list);
        return PageResponse.success(pageResult);
    }

    @Override
    public BaseResponse<ApprovalResp> getLaunchInfo(ApprovalReq approvalReq) {
        if (Objects.isNull(approvalReq.getOrderId())) {
            return BaseResponse.errorParam();
        }
        HistoryOrder histOrder = queryService.getHistOrder(approvalReq.getOrderId());
        ApprovalResp approvalResp = initApprovalResp(histOrder.getVariable(), userService.getById(histOrder.getCreator()));
        approvalResp.setApprovalDate(histOrder.getCreateTime()).setOrderState(histOrder.getOrderState())
            .setOrderId(approvalReq.getOrderId());
        QueryFilter queryFilter = new QueryFilter();
        queryFilter.setOperator(histOrder.getCreator()).orderBy("create_Time desc");
        List<HistoryTask> historyTaskList = queryService.getHistoryTasks(queryFilter);
        List<Task> activeTaskList = queryService.getActiveTasks(queryFilter);
        List<ApprovalResp.ApprovalHistoryInfo> historyInfoList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(historyTaskList)) {
            historyTaskList.forEach(task -> {
                ApprovalResp.ApprovalHistoryInfo historyInfo = initApprovalHisotoryVariable(task.getVariable(), task.getOperator());
                historyInfoList.add(historyInfo);
            });
        }
        if (!CollectionUtils.isEmpty(activeTaskList)) {
            historyTaskList.forEach(task -> {
                ApprovalResp.ApprovalHistoryInfo historyInfo = initApprovalHisotoryVariable(task.getVariable(), task.getOperator());
                historyInfoList.add(historyInfo);
            });
        }
        approvalResp.setApprovalHistory(historyInfoList);
        return BaseResponse.success(approvalResp);
    }

    @Override
    public BaseResponse<ApprovalResp> cancel(ApprovalReq approvalReq) {
        if (Objects.isNull(approvalReq.getOrderId()) || Objects.isNull(approvalReq.getUserId())) {
            return BaseResponse.errorParam();
        }
        orderService.withdraw(approvalReq.getOrderId(), approvalReq.getUserId().toString());
        return BaseResponse.success("取消成功");
    }

    @Override
    public PageResponse<ApprovalResp> getCcList(ApprovalReq approvalReq) {
        if (Objects.isNull(approvalReq.getUserId())) {
            return PageResponse.errorParam();
        }
        Page<HistoryOrder> page = new Page();
        page.setPageNo(approvalReq.getPageNo());
        page.setPageSize(approvalReq.getPageSize());
        QueryFilter queryFilter = new QueryFilter();
        queryFilter.setOperator(approvalReq.getUserId().toString());
        if (Objects.nonNull(approvalReq.getStatus()) && approvalReq.getStatus() == 0) {
            //未读
            queryFilter.setState(AccessService.STATE_ACTIVE);
        }
        queryService.getCCWorks(page, queryFilter);
        Page<ApprovalResp> pageResult = new Page();
        List<ApprovalResp> list = new ArrayList<>(page.getResult().size());
        if (!CollectionUtils.isEmpty(page.getResult())) {
            page.getResult().forEach(item -> {
                ApprovalResp approvalResp = initApprovalResp(item.getVariable(), userService.getById(item.getCreator()));
                approvalResp.setOrderId(item.getId()).setApprovalType(item.getProcessName()).setApprovalDate(item.getCreateTime());
                list.add(approvalResp);
            });
        }
        pageResult.setResult(list);
        return PageResponse.success(pageResult);
    }

    private Page<ApprovalResp> workItem2Approval(Page<WorkItem> page) {
        Page<ApprovalResp> pageResult = new Page();
        BeanUtils.copyProperties(page, pageResult);
        List<ApprovalResp> list = new ArrayList<>(page.getResult().size());
        if (!CollectionUtils.isEmpty(page.getResult())) {
            page.getResult().forEach(item -> {
                SysUser user = userService.getById(item.getCreator());
                ApprovalResp approvalResp = initApprovalResp(item.getOrderVariable(), user);
                approvalResp.setApprovalType(item.getProcessName()).setApprovalDate(item.getOrderCreateTime());
                list.add(approvalResp);
            });
        }
        pageResult.setResult(list);
        return pageResult;
    }

    private ApprovalResp initApprovalResp(String variable, SysUser user) {
        ApprovalResp approvalResp = initApprovalVariable(variable);
        if (Objects.nonNull(user)) {
            Optional.ofNullable(user.getRealName()).ifPresent(name -> approvalResp.setApplicant(name));
            Optional.ofNullable(user.getAvatar()).ifPresent(img -> approvalResp.setApplicantImg(img));
        }
        return approvalResp;
    }

    private ApprovalResp initApprovalVariable(String variable) {
        ApprovalResp approvalResp = new ApprovalResp();
        if (StringUtils.isNotBlank(variable)) {
            approvalResp.setVariableJson(variable);
        }
        return approvalResp;
    }

    private ApprovalResp.ApprovalHistoryInfo initApprovalHisotoryVariable(String variable, String operator) {
        ApprovalResp.ApprovalHistoryInfo historyInfo = ApprovalResp.getApprovalHistoryInfo();
        historyInfo.setVariableJson(variable);
        SysRole role = roleService.getById(operator);
        if (Objects.nonNull(role)) {
            Optional.ofNullable(role.getRoleName()).ifPresent(roleName -> historyInfo.setOperator(roleName));
        }
        return historyInfo;
    }
}
