package com.malk.service.aliwork;


import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;

import java.util.List;
import java.util.Map;

public interface YDService {

    // todo: 批量创建接口异常; 查询子表超过50自动查询全量; 查询表单全部数据, 避免第一次重复查询优化, 添加直接返回formData, 兼容formInstId;  upsert方法

    // todo 0402 批量更新 / 删除

    /**
     * 操作数据 [异步]
     */
    Object operateData(YDParam param, YDConf.FORM_OPERATION type);

    /**
     * 操作数据 [异步] 谷原
     */
    Object operateData2(Map data, Map update, YDParam param, YDConf.FORM_OPERATION type);

    /**
     * 操作数据 [异步] 能辉
     */
    Object operateData3(Map data, Map update, YDParam param, YDConf.FORM_OPERATION type);

    /**
     * 查询数据 [子表] todo 参数控制
     * <p>
     * .formUuid("FORM-TD966Z81I9ODTCY66GH345S03VW03JJF6EQLL5")
     * .formInstanceId(data.get("formInstanceId").toString())
     * .tableFieldId("tableField_llqe7fgb")
     */
    List<Map> queryDetails(YDParam ydParam);

    /**
     * 查询全部 [主表] todo 合并formData, 或data, putAll
     * <p>
     * .stream().map(item -> {
     * item.putAll( (Map) item.get("formData"));
     * return item;
     * }).collect(Collectors.toList());
     */
    List<Map> queryAllFormData(YDParam YDParam);

    // todo: 宜搭大数据量处理会有异常, 可结合排序, 或失败记录进行处理 (避免更新后, 数据重新查询排序导致未全量同步)
    List<Map> queryFormData_all(YDParam YDParam);

    // ppExt: 查询100后再进分页, 且转为formData内数据, todo Process待完成 [bug]
    List<Map> queryFormData_all_advance(YDParam ydParam, YDConf.FORM_QUERY type);

    /**
     * 查询宜搭数据
     */
    List<Map> queryDataList_FormData(String formUuid, Map conditions);

    /**
     * 查询宜搭数据 [精确匹配]
     */
    List queryFormData(String formUuid, String conditions);

    /**
     * 字段复制 [服务注册传递参数都是 string 格式]
     * -
     * fixme: 服务注册
     * 1. 在提交校验，因为数据还未执行, 除 #{_yida_all_data} 外，绝大部分字段都是为空，且若是子表字段数据:会拆为为单一字段,数据为该字段下明细数据数组
     * 2. 但在在业务规则内配置，可以正常获取. 若是子表单, 除返回提交下该字段明细数据数组外, 也会返回子表组件, 及子表内对应的数据 [可有效避免触发何查询操作]
     * 业务规则场景: 若是写入关联表单，自关联后，通过自动化传递。若是数据全表复制，可获取全量数据进行写入操作
     * ppExt: 组件格式
     * 1. { "cur": "目标表, 主表组件ID[包含子表组件ID]", "src": "当前表, 主表组件ID[包含子表组件ID]", "子表组件ID + cur/src": "子表内的组件ID" }
     * 2. 所有组件通过英文逗号 + 空格区分, 子表组件为避免组件id相同但子表内组件不一致的情况, 在单独子表组件ID后添加 src/cur 区分来源
     */
    Object copyFormData(Map data);

    /**
     * 全表复制 [两张表组件完全一致]
     */
    Object mirrorFormData(String instanceId, String formUuid, String processCode, Map updateData, String updateInstanceId);

    /**
     * upsert方法 [todo: 优化 批量的数据兼容]
     *
     * @param lambda 查询数据回调, 传递查询结果list, 接收回调返回map传递钉到formData内, 若返回为空则不支持Upsert
     */
    Object upsertFormData(String formUuid, Map condition, Map formData, UpsertLambda lambda);

    /**
     * ppExt 函数式编程：Stream类、Lambda表达式和函数接口（Functional Inteface）
     * -
     * 自定义Lambda是为了更好的代码提示和数据类型定义: @FunctionalInterface，该接口为函数接口，一个函数接口只能存在一个方法
     * 特别注意，非异步情况下，和网络请求一致，回调默认同步等待【回调方式可自定义：如兼容并发可有，同步单次回调、同步累积回调、并发异步执行、并发累积回调】
     * 函数编程的最大好处，是可传入执行逻辑，而无需等待全部数据结果，尤其并发和异步情况下【异步效果优于Future】
     * -
     * 结合异步与并发, @Async说明和配置详见core/AsyncConfig
     */
    @FunctionalInterface
    interface UpsertLambda {
        Map dataList(List<Map> list);
    }

}
