package com.yunzhupaas.flowable.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.flowable.entity.*;
import com.yunzhupaas.flowable.enums.NodeEnum;
import com.yunzhupaas.flowable.enums.OperatorStateEnum;
import com.yunzhupaas.flowable.model.operator.OperatorVo;
import com.yunzhupaas.flowable.model.task.FileModel;
import com.yunzhupaas.flowable.model.task.FlowModel;
import com.yunzhupaas.flowable.model.task.TaskPagination;
import com.yunzhupaas.flowable.model.templatenode.nodejson.FileConfig;
import com.yunzhupaas.flowable.model.templatenode.nodejson.NodeModel;
import com.yunzhupaas.flowable.service.*;
import com.yunzhupaas.flowable.util.OperatorUtil;
import com.yunzhupaas.flowable.util.RecordUtil;
import com.yunzhupaas.flowable.util.TaskUtil;
import com.yunzhupaas.util.DateUtil;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.workflow.service.TaskApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * 类的描述
 *
 * @author YUNZHUPAASYUNZHUPAAS开发组
 * @version 5.0.x
 * @since 2024/5/28 14:32
 */
@Component
public class TaskForFileController implements TaskApi {
    @Autowired
    private TaskService taskService;
    @Autowired
    private OperatorService operatorService;
    @Autowired
    private RecordService recordService;
    @Autowired
    private CirculateService circulateService;
    @Autowired
    private DelegateService delegateService;
    @Autowired
    private TemplateNodeService templateNodeService;
    @Autowired
    private RecordUtil recordUtil;
    @Autowired
    private OperatorUtil operatorUtil;
    @Autowired
    private TaskUtil taskUtil;

    // 获取归档信息
    @Override
    public FileModel getFileModel(String taskId) throws WorkFlowException {
        TaskEntity taskEntity = taskService.getInfo(taskId);
        if (null == taskEntity) {
            throw new WorkFlowException(MsgCode.FA001.get());
        }
        FileModel model = new FileModel();

        List<TemplateNodeEntity> nodeEntityList = templateNodeService.getList(taskEntity.getFlowId());
        TemplateNodeEntity globalEntity = nodeEntityList.stream()
                .filter(e -> StringUtil.equals(NodeEnum.global.getType(), e.getNodeType())).findFirst()
                .orElse(new TemplateNodeEntity());
        NodeModel global = JsonUtil.getJsonToBean(globalEntity.getNodeJson(), NodeModel.class);
        if (null != global) {
            FileConfig fileConfig = global.getFileConfig();
            // 归档路径
            model.setParentId(fileConfig.getParentId());

            String userId = taskEntity.getCreatorUserId();
            if (fileConfig.getPermissionType().equals(1)) {
                // 创建人
                model.setUserId(userId);
                // 分享人
                List<String> list = operatorUtil.getListOfFile(taskId);
                model.setUserList(list.stream().filter(e -> !e.equals(userId)).collect(Collectors.toList()));
            } else if (fileConfig.getPermissionType().equals(3)) {
                // 最后节点审批人
                List<String> list = operatorUtil.getListOfLast(taskId);
                if (CollectionUtil.isNotEmpty(list)) {
                    model.setUserId(list.get(0));
                    list.remove(0);
                    if (CollectionUtil.isNotEmpty(list)) {
                        model.setUserList(list);
                    }
                } else {
                    model.setUserId(userId);
                }
            } else {
                // 创建人
                model.setUserId(userId);
            }
        }

        // 文件名称
        String filename = taskEntity.getFullName();
        String datetime;
        if (null != taskEntity.getEndTime()) {
            datetime = DateUtil.dateToString(taskEntity.getEndTime(), "yyyyMMddHHmmss");
        } else {
            datetime = DateUtil.dateToString(new Date(), "yyyyMMddHHmmss");
        }
        filename += "-" + datetime;
        model.setFilename(filename + ".pdf");

        return model;
    }

    @Override
    public TaskEntity getInfoSubmit(String id, SFunction<TaskEntity, ?>... columns) {
        return taskService.getInfoSubmit(id, columns);
    }

    @Override
    public List<TaskEntity> getInfosSubmit(String[] ids, SFunction<TaskEntity, ?>... columns) {
        return taskService.getInfosSubmit(ids, columns);
    }

    @Override
    public void delete(TaskEntity taskEntity) throws Exception {
        taskService.delete(taskEntity.getId());
    }

    @Override
    public void saveOrSubmit(FlowModel flowModel) throws Exception {
        taskService.batchSaveOrSubmit(flowModel);
    }

    @Override
    public List<RecordEntity> getRecordList(String taskId) {
        return recordUtil.getList(taskId);
    }

    @Override
    public void updateIsFile(String taskId) {
        try {
            taskService.updateIsFile(taskId);
        } catch (WorkFlowException e) {
            System.out.println(e.getMessage());
        }
    }

    @Override
    public List<OperatorVo> getWaitList(TaskPagination pagination) {
        return operatorService.getList(pagination);
    }

    @Override
    public List<OperatorVo> getTrialList(TaskPagination pagination) {
        return recordService.getList(pagination);
    }

    @Override
    public List<OperatorVo> getCirculateList(TaskPagination pagination) {
        return circulateService.getList(pagination);
    }

    @Override
    public List<DelegateEntity> getDelegateList() {
        return delegateService.getList();
    }

    @Override
    public Boolean checkSign() {
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getCompletion, 0)
                .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode())
                .isNull(OperatorEntity::getSignTime);
        long count = operatorService.count(queryWrapper);
        return count > 0;
    }

    @Override
    public Boolean checkTodo() {
        QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(OperatorEntity::getCompletion, 0)
                .ne(OperatorEntity::getStatus, OperatorStateEnum.Futility.getCode())
                .isNotNull(OperatorEntity::getSignTime).isNull(OperatorEntity::getStartHandleTime);
        long count = operatorService.count(queryWrapper);
        return count > 0;
    }

    @Override
    public ActionResult launchFlow(FlowModel flowModel) {
        try {
            return taskUtil.launchFlow(flowModel);
        } catch (Exception e) {
            e.printStackTrace();
            return ActionResult.fail(e.getMessage());
        }
    }
}
