package com.malk.server.aliwork;

import com.alibaba.fastjson.JSONObject;
import com.malk.base.BaseDto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.groups.Default;
import java.util.List;

/**
 * 表单接口适用于流程: 查询和更新以及删除 [参数校验参考CatchException]
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class YDParam extends BaseDto {

    /**
     * 接口参数
     */
    @NotNull(message = "应用编码不能为空")
    private String appType;

    @Null(message = "应用秘钥无需传递")
    private String systemToken;

    // 默认宜搭平台, 有操作数据权限
    @Builder.Default
    private String userId = YDConf.PUB_ACCOUNT;

    @NotNull(message = "表单编码不能为空", groups = {Create.class, Retrieve_Condition.class, Definition.class, Create_Process.class, Retrieve_Condition_Update.class})
    private String formUuid;

    /// FIXME: 表单/流程组件查询
    private String searchFieldJson;

    @Builder.Default
    private Integer currentPage = 1;

    @Builder.Default
    private Integer pageSize = YDConf.PAGE_SIZE_LIMIT;

    // 流程暂不支持排序
    private String dynamicOrder;

    // 修改开始时间, ppExt: 需要同时传递开始和就结束才会生效; 其次日期格式yyyy-MM-dd, 但默认是0点, 结束日期建议加1
    private String modifiedFromTimeGMT;

    // 修改结束时间, ppExt: 需要同时传递开始和就结束才会生效; 其次日期格式yyyy-MM-dd, 但默认是0点, 结束日期建议加1
    private String modifiedToTimeGMT;

    @NotNull(message = "实例ID不能为空", groups = {Update.class, Delete.class, Retrieve_FormInstId.class})
    private String formInstId;

    @NotNull(message = "更新内容不能为空", groups = {Update.class, Update_ProcessInstanceId.class, Retrieve_Condition_Update.class})
    private String updateFormDataJson;

    @NotNull(message = "流程编码不能为空", groups = Create_Process.class)
    private String processCode;

    // todo: 成员组件未匹配, 接口可以新增 [系统会忽略], 导入会提示无法匹配
    @NotNull(message = "新增内容不能为空", groups = {Create.class, Create_Process.class})
    public String formDataJson;

    @NotNull(message = "实例ID不能为空", groups = {Update_ProcessInstanceId.class, Delete_ProcessInstanceId.class, Retrieve_ProcessInstanceId.class})
    private String processInstanceId;

    @NotNull(message = "实例ID不能为空", groups = Retrieve_ProcessInstanceIds.class)
    private String processInstanceIds;

    /// RUNNING / NEW / PAUSED / TERMINATED / COMPLETED / ERROR / CANCELED
    private String instanceStatus;

    /// disagree / agree
    private String approvedResult;

    /**
     * 格式化赋值: 内部使用
     */
    public void setDynamicOrder(String dynamicOrder) {
        this.dynamicOrder = dynamicOrder;
    }

    public void setDynamicOrder(String rule, String... compIds) {
        for (String compId : compIds) {
            JSONObject orderJson = new JSONObject();
            orderJson.put(compId, rule);
            this.dynamicOrder = orderJson.toJSONString();
        }
    }

    /// 查询创建时间, 钉钉版本接口 [旧版本接口不支持]
    private String createFromTimeGMT;
    private String createToTimeGMT;


    /**
     * 自定义参数
     */
    private String compIdSerial; // 流水号排序字段

    /**
     * 钉钉新版本接口
     */
    @Builder.Default
    private Integer pageNumber = 1;

    private String formInstanceId;

    // formInstanceId 为新版本实例id字段
    public String getFormInstanceId() {
        if (StringUtils.isBlank(formInstanceId)) {
            return formInstId;
        }
        return formInstanceId;
    }

    /// FIXME: 表单/流程全局查询
    private String searchCondition;

    // 全局条件查询列表数据 FIXME: 若是查询组件也传searchFieldJson格式
    public String getSearchCondition() {
        if (StringUtils.isBlank(searchCondition)) {
            return searchFieldJson;
        }
        return searchCondition;
    }

    // 查询列表可查询多个指定实例ID | 批量删除 [上限50] | 批量更新
    private List<String> formInstanceIdList;

    // 是否需要宜搭表单组件格式的实例数据
    private boolean needFormInstanceValue = false;

    // 查询明细数据列表, 默认仅返回前50
    private String tableFieldId;

    // 附件转临时免登地址
    private String fileUrl;
    // 临时地址失效时间, 默认10分钟, 最大值24小时
    @Builder.Default
    private Integer timeout = 600000;

    /**
     * 批量删除
     */

    // 是否需要宜搭服务端异步执行该任务
    @Builder.Default
    private boolean asynchronousExecution = false;

    // 是否需要触发表单绑定的校验规则、关联业务规则和第三方服务回调
    @Builder.Default
    private boolean executeExpression = false;

    // 是否不触发表单绑定的校验规则、关联业务规则和第三方服务回调。
    @Builder.Default
    private boolean noExecuteExpression = true;

    // 是否忽略空值。
    @Builder.Default
    private boolean ignoreEmpty = true;

    // 是否使用最新的表单schema版本。
    @Builder.Default
    private boolean useLatestFormSchemaVersion = true;

    // 使用最新的表单版本进行更新。
    @Builder.Default
    private boolean useLatestVersion = false;

    /**
     * 评论
     */
    private String atUserId;

    private String content;


    /**
     * 分组校验
     *
     * @RequestBody @Validated(YDParam.Create.class) YDParam ydParam
     */

    public interface Create extends Default {

    }

    public interface Create_Process extends Default {

    }

    public interface Retrieve_Condition extends Default {

    }

    public interface Retrieve_Condition_Update extends Default {

    }

    public interface Retrieve_FormInstId extends Default {

    }

    public interface Retrieve_ProcessInstanceId extends Default {

    }

    public interface Retrieve_ProcessInstanceIds extends Default {

    }

    public interface Update extends Default {

    }

    public interface Update_ProcessInstanceId extends Default {

    }

    public interface Delete extends Default {

    }

    public interface Delete_ProcessInstanceId extends Default {

    }

    public interface Definition extends Default {

    }
}
