
package org.jeecg.modules.workFlow.flowlong.engine.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.jeecg.modules.workFlow.flowlong.engine.assist.Assert;
import org.jeecg.modules.workFlow.flowlong.engine.assist.DateUtils;
import org.jeecg.modules.workFlow.flowlong.engine.core.enums.TaskState;
import org.jeecg.modules.workFlow.flowlong.engine.core.enums.TaskType;
import org.jeecg.modules.workFlow.flowlong.engine.model.NodeModel;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;

/**
 * 历史任务实体类
 *

 */
@Getter
@Setter
@ToString
public class FlwHisTask extends FlwTask {
    /**
     * 调用外部流程定义ID
     */
    protected Long callProcessId;
    /**
     * 调用外部流程实例ID
     */
    protected Long callInstanceId;
    /**
     * 完成时间
     */
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    protected Date finishTime;
    /**
     * 任务状态 0，活动 1，跳转 2，完成 3，拒绝 更多查看 {@link TaskState}
     */
    protected Integer taskState;
    /**
     * 处理耗时
     */
    protected Long duration;

    public FlwHisTask setTaskState(TaskState taskState) {
        this.taskState = taskState.getValue();
        return this;
    }

    public FlwHisTask setTaskState(Integer taskState) {
        Assert.isNull(TaskState.get(taskState), "插入的实例状态异常 [taskState=" + taskState + "]");
        this.taskState = taskState;
        return this;
    }

    public static FlwHisTask of(FlwTask flwTask, TaskState taskState) {
        return of(flwTask).setTaskState(taskState);
    }

    public static FlwHisTask of(FlwTask flwTask) {
        FlwHisTask hisTask = new FlwHisTask();
        hisTask.id = flwTask.getId();
        hisTask.tenantId = flwTask.getTenantId();
        hisTask.createId = flwTask.getCreateId();
        hisTask.createBy = flwTask.getCreateBy();
        hisTask.createTime = flwTask.getCreateTime();
        hisTask.instanceId = flwTask.getInstanceId();
        hisTask.parentTaskId = flwTask.getParentTaskId();
        hisTask.taskName = flwTask.getTaskName();
        hisTask.taskKey = flwTask.getTaskKey();
        hisTask.taskType = flwTask.getTaskType();
        hisTask.performType = flwTask.getPerformType();
        hisTask.actionUrl = flwTask.getActionUrl();
        hisTask.variable = flwTask.getVariable();
        hisTask.assignorId = flwTask.getAssignorId();
        hisTask.assignor = flwTask.getAssignor();
        hisTask.expireTime = flwTask.getExpireTime();
        hisTask.remindTime = flwTask.getRemindTime();
        hisTask.remindRepeat = flwTask.getRemindRepeat();
        hisTask.viewed = flwTask.getViewed();
        return hisTask;
    }

    public static FlwHisTask ofCallInstance(NodeModel nodeModel, FlwInstance instance) {
        FlwHisTask flwHisTask = new FlwHisTask();
        flwHisTask.setTenantId(instance.getTenantId());
        flwHisTask.setCreateId(instance.getCreateId());
        flwHisTask.setCreateBy(instance.getCreateBy());
        flwHisTask.setCreateTime(instance.getCreateTime());
        flwHisTask.setInstanceId(instance.getParentInstanceId());
        flwHisTask.setTaskName(nodeModel.getNodeName());
        flwHisTask.setTaskKey(nodeModel.getNodeKey());
        flwHisTask.setCallProcessId(instance.getProcessId());
        flwHisTask.setCallInstanceId(instance.getId());
        flwHisTask.setTaskType(nodeModel.getType());
        return flwHisTask;
    }

    /**
     * 根据历史任务产生撤回的任务对象
     * <p>
     * 创建人信息保留
     * </p>
     *
     * @return 任务对象
     */
    public FlwTask undoTask(TaskType taskType) {
        FlwTask flwTask = this.cloneTask(this.createId, this.createBy);
        flwTask.taskType(taskType);
        return flwTask;
    }

    /**
     * 计算流程实例处理耗时
     */
    public void calculateDuration() {
        this.finishTime = DateUtils.getCurrentDate();
        this.duration = DateUtils.calculateDateDifference(this.createTime, this.finishTime);
    }
}
