package com.malk.server.aliwork;

import com.alibaba.fastjson.JSON;
import com.malk.utils.UtilMap;
import com.malk.utils.UtilString;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Data
@Component
@ConfigurationProperties(prefix = "aliwork")
@Slf4j
public class YDConf {

    private String appType;

    private String systemToken;

    /**
     * 一个切片数量上限
     */
    public static final Integer UPPER_LIMIT = 30000;

    /**
     * 一个分页数量上限
     */
    public static final Integer PAGE_SIZE_LIMIT = 100;


    /**
     * 子表详情接口的内联上限及分页大小；内联数量等于该值时需分页查询全量。
     */
    public static final Integer PAGE_SIZE_DETAILS = 50;

    /**
     * 宜搭开放平台 API 基础地址（新版）
     */
    public static final String BASE_V1 = "https://api.dingtalk.com/v1.0/yida";
    public static final String BASE_V2 = "https://api.dingtalk.com/v2.0/yida";


    /**
     * 接口访问账号 [不能触发待办与消息通知, 业务规则亦不能]
     * -
     * 非管理员账号只可以查询, 不检验权限
     * 操作数据需要管理员账号, 或宜搭平台
     */
    public static final String PUB_ACCOUNT = "yida_pub_account";

    ////////////////////////// 新版本API //////////////////////////

    /**
     * 查询表单
     */
    public enum FORM_QUERY {

        retrieve_list,              // 全局查询, 不包含子表单
        retrieve_list_all,          // 全局查询, 包含子表单
        multi_retrieve_id,

        retrieve_id,                // 单个ID查询 todo 若秘钥不匹配, 返回空, 添加报错说明

        retrieve_search_process,            // 流程列表
        retrieve_search_form,               // 表单列表

        retrieve_search_process_id,         // 流程列表
        retrieve_search_form_id,             // 表单列表

        retrieve_details,                   // 子表数据[表单]
        retrieve_changed,               // 变更记录
        retrieve_definition,        // 表单定义

        retrieve_forms, // 表单列表
        retrieve_approval_record, // 审批记录
    }

    /**
     * 表单操作
     */
    public enum FORM_OPERATION {
        create,
        delete,                     // 传入为body, 文档为param
        update,

        // fixme: 不支持新增字段更新, 若有可先更新版本后执行 [无版本和更新json参数];
        // ppExt: start / create, noExecuteExpression 默认值是 true, 若需要触发配置消息通知, 设置为 false
        upsert,                     // insertOrUpdate
        upsert_v2,                  // 新版本 searchCondition 条件精准匹配
        multi_create,               // 批量操作
        delete_batch,               // 批量删除
        multi_update,               // 批量更新
        start,                      // 发起流程
        batchSave,                  // 批量创建

        remarks,  // 评论
    }

    /**
     * 关联表单处理
     *
     * @param formType: "receipt" 跳转为表单【若是流程，则权限体系会失效，但也会显示审批节点】; formType: "process" 为流程
     * @apiNote ppExt 接口更新, 传入jsonString或List都可以. 返回数据都是两层json解析, 组件 + _id格式
     */
    public List<Map> associationForm(String formUuid, String formInstanceId, String title, String subTitle, boolean isProcess) {
        return associationForm(appType, formUuid, formInstanceId, title, subTitle, isProcess);
    }

    // todo 部门ID写入需要是string集合\数组, 封装
    public static List<Map> associationForm(String appType, String formUuid, String formInstanceId, String title, String subTitle, boolean isProcess) {
        String formType = isProcess ? "process" : "receipt";
        return Arrays.asList(UtilMap.map("appType, formUuid, instanceId, title, subTitle, formType", appType, formUuid, formInstanceId, title, subTitle, formType));
    }

    /**
     * 读取关联表单: ppExt 两层解析后才是List, 若是赋值取值转一层, 宜搭也可进行写入
     * - 赋值说明 -
     * 若是同一个应用，appType与formUuid为空（不指定下formUuid可为错误，但appType只能为空），点击页面链接会自动匹配；
     * 若是跨应用实例，则不能通过导入，需要通过接口指定appType
     */
    public static List<Map> associationForm(String associations) {
        if (UtilString.isBlankCompatNull(associations)) {
            return new ArrayList<>();
        }
        return (List<Map>) JSON.parse(String.valueOf(JSON.parse(String.valueOf(associations))));
    }

    /**
     * 高级筛选: ppExt 通过表单\流程 search 宜搭目前下拉框也会被模糊匹配, 为避免事后过滤, 使用高级查询; 且高级查询支持同一个字段多条件
     */
    public static Map searchCondition_TextFiled(String compId, Object value, String operator) {
        return UtilMap.map("key, value, type, operator, componentName", compId, value, "TEXT", operator, "TextField");
    }

    // todo text组件是否可用于select
    public static Map searchCondition_processInstanceStatus(List status) {
        return UtilMap.map("key, value, type, operator, componentName", "processInstanceStatus", status, "ARRAY", "in", "SelectField");
    }

    /**
     * 组件格式化取值 [取值] todo 明细表递归, 循环传递入参
     */
    public static Object getDataByCompId(Map formData, String compId_cur) {
        if (compId_cur.contains("associationFormField_")) {
            // 服务注册 #{_yida_all_data} 直接组件Id
            if (!formData.containsKey(compId_cur)) {
                // 接口返回数据, 关联组件ID, 不会返回组件id字段
                compId_cur = compId_cur + "_id";
            }
            return JSON.parse(String.valueOf(formData.get(compId_cur)));
        } else if (compId_cur.contains("employeeField_")) {
            if (!formData.containsKey(compId_cur + "_id")) {
                // 服务注册 #{_yida_all_data} 返回JsonString userid 数组
                return JSON.parse(String.valueOf(formData.get(compId_cur)));
            } else {
                // 成员组件, 接口返回组件id返回为姓名, _id返回是userId
                return formData.get(compId_cur + "_id");
            }
        }
        return formData.get(compId_cur);
    }

    ////////////////////////// 老版本API //////////////////////////

    /**
     * 表单接口适用于流程: 查询和更新以及删除
     */
    private static String formatApiForm(String uri) {
        return "/yida_vpc/form/" + uri + ".json";
    }

    private static String formatApiProcess(String uri) {
        return "/yida_vpc/process/" + uri + ".json";
    }

    /**
     * 接口地址: 表单
     */
    public static final String API_FORM_CREATE = formatApiForm("saveFormData");
    public static final String API_FORM_DELETE = formatApiForm("deleteFormData");
    public static final String API_FORM_UPDATE = formatApiForm("updateFormData");
    public static final String API_FORM_DETAIL = formatApiForm("getFormDataById");
    public static final String API_FORM_QUERY_ID = formatApiForm("searchFormDataIds");
    public static final String API_FORM_QUERY_DATA = formatApiForm("searchFormDatas");

    public static final String API_FORM_DEFINITION = "/yida_vpc/formDesign/getFormComponentDefinationList.json";

    /**
     * 接口地址: 流程
     */
    public static final String API_PROCESS_CREATE = formatApiProcess("startInstance");
    public static final String API_PROCESS_DELETE = formatApiProcess("deleteInstance");
    public static final String API_PROCESS_UPDATE = formatApiProcess("updateInstance");
    public static final String API_PROCESS_DETAIL = formatApiProcess("getInstanceById");
    public static final String API_PROCESS_BATCH_DETAIL = formatApiProcess("getInstancesByIds");
    public static final String API_PROCESS_QUERY_ID = formatApiProcess("getInstanceIds");
    public static final String API_PROCESS_QUERY_DATA = formatApiProcess("getInstances");

    /**
     * 其它接口
     */
    public static final String API_OPEN_URL = "/yida_vpc/file/getOpenUrl.json";
}
