package com.malk.service.aliwork.impl;

import com.alibaba.fastjson.JSONObject;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.dingtalk.DDR_New;
import com.malk.service.aliwork.YDClient;
import com.malk.service.dingtalk.DDClient;
import com.malk.utils.UtilHttp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class YDClientImpl implements YDClient {

    @Autowired
    private YDConf ydConf;

    @Autowired
    private DDClient ddClient;

    // 初始化请求参数
    Map _initBodyParam(YDParam ydParam) {
        if (StringUtils.isBlank(ydParam.getUserId())) {
            ydParam.setUserId(YDConf.PUB_ACCOUNT);
        }
        // 配置宜搭请求参数: appType, systemToken
        if (StringUtils.isBlank(ydParam.getAppType()) || ydParam.getAppType().equals(ydConf.getAppType())) {
            ydParam.setAppType(ydConf.getAppType());
            ydParam.setSystemToken(ydConf.getSystemToken());
        }
        return JSONObject.parseObject(JSONObject.toJSONString(ydParam), Map.class);
    }

    // 请求地址 [拼接]
    private String getRequestUrl(String uri) {
        return "https://api.dingtalk.com/v1.0/yida" + uri;
    }

    // 请求地址 [v2]
    private String getRequestUrl_v2(String uri) {
        return "https://api.dingtalk.com/v2.0/yida" + uri;
    }

    // 请求地址 [实例]
    private String getRequestUrl(String uri, String instanceId) {
        return getRequestUrl(uri) + "/" + instanceId;
    }

    /**
     * 操作数据
     */
    @Override
    public Object operateData(YDParam ydParam, YDConf.FORM_OPERATION type) {
        DDR_New ddr_new = null;
        Map bodys = _initBodyParam(ydParam);
        switch (type) {
            case create:
                ddr_new = (DDR_New) UtilHttp.doPost(getRequestUrl("/forms/instances"), ddClient.initTokenHeader(), bodys, DDR_New.class);
                break;
            case update:
                ddr_new = (DDR_New) UtilHttp.doPut(getRequestUrl("/forms/instances"), ddClient.initTokenHeader(), bodys, DDR_New.class);
                break;
            case upsert:
                ddr_new = (DDR_New) UtilHttp.doPost(this.getRequestUrl("/forms/instances/insertOrUpdate"), this.ddClient.initTokenHeader(), bodys, DDR_New.class);
                break;
            case upsert_v2:
                ddr_new = (DDR_New) UtilHttp.doPost(this.getRequestUrl_v2("/forms/instances/insertOrUpdate"), this.ddClient.initTokenHeader(), bodys, DDR_New.class);
                break;
            case delete:
                ddr_new = (DDR_New) UtilHttp.doDelete(getRequestUrl("/forms/instances"), ddClient.initTokenHeader(), bodys, DDR_New.class);
                break;
            case start:
                ddr_new = (DDR_New) UtilHttp.doPost(getRequestUrl("/processes/instances/start"), ddClient.initTokenHeader(), bodys, DDR_New.class);
                break;
            case delete_batch:
                ddr_new = (DDR_New) UtilHttp.doPost(getRequestUrl("/forms/instances/batchRemove"), ddClient.initTokenHeader(), bodys, DDR_New.class);
                break;
            case multi_update:
                ddr_new = (DDR_New) UtilHttp.doPut(getRequestUrl("/forms/instances/components"), ddClient.initTokenHeader(), bodys, DDR_New.class);
                break;
            case batchSave:
                ddr_new = (DDR_New) UtilHttp.doPost(getRequestUrl("/forms/instances/batchSave"), ddClient.initTokenHeader(), null, _initBodyParam(ydParam), DDR_New.class);
                break;
            case remarks:
                ddr_new = (DDR_New) UtilHttp.doPost(getRequestUrl("/forms/remarks"), ddClient.initTokenHeader(), null, _initBodyParam(ydParam), DDR_New.class);
                break;

            default:
                break;
        }
        return ddr_new.getResult();
    }

    /**
     * 查询数据
     *
     * @apiNote
     */
    @Override
    public DDR_New queryData(YDParam ydParam, YDConf.FORM_QUERY type) {
        DDR_New ddr_new = null;
        Map param = _initBodyParam(ydParam);
        switch (type) {
            case retrieve_list_all:
                ddr_new = DDR_New.doPost(getRequestUrl("/forms/instances/advances/queryAll"), ddClient.initTokenHeader(), null, param);
                break;
            case retrieve_list:
                ddr_new = DDR_New.doPost(getRequestUrl("/forms/instances/advances/query"), ddClient.initTokenHeader(), null, param);
                break;
            case retrieve_id:
                ddr_new = DDR_New.doGet(getRequestUrl("/forms/instances", ydParam.getFormInstanceId()), ddClient.initTokenHeader(), param);
                break;
            case retrieve_search_process:
                ddr_new = DDR_New.doPost(getRequestUrl("/processes/instances"), ddClient.initTokenHeader(), param, param);
                break;

            case retrieve_search_process_id:
                ddr_new = DDR_New.doPost(getRequestUrl("/processes/instanceIds", ydParam.getProcessInstanceId()), ddClient.initTokenHeader(), param, param);
                break;

            case retrieve_search_form:
                ddr_new = DDR_New.doPost(getRequestUrl("/forms/instances/search"), ddClient.initTokenHeader(), null, param);
                break;

            case retrieve_search_form_id:
                ddr_new = DDR_New.doPost(getRequestUrl("/forms/instances/ids") + "/" + ydParam.getAppType() + "/" + ydParam.getFormUuid(), ddClient.initTokenHeader(), param, param);
                break;

            case retrieve_details:
                ddr_new = DDR_New.doGet(getRequestUrl("/forms/innerTables", ydParam.getFormInstanceId()), ddClient.initTokenHeader(), param);
                break;
            case retrieve_changed:
                ddr_new = DDR_New.doPost(getRequestUrl("/forms/operationsLogs/query"), ddClient.initTokenHeader(), null, param);
                break;
            case retrieve_forms:
                ddr_new = DDR_New.doGet(getRequestUrl("/forms"), ddClient.initTokenHeader(), param);
                break;

            case retrieve_approval_record:
                ddr_new = DDR_New.doGet(getRequestUrl("/processes/operationRecords"), ddClient.initTokenHeader(), param);
                break;
        }
        return ddr_new;
    }

    /**
     * 临时免登地址
     */
    @Override
    public String convertTemporaryUrl(String url, int timeout) {
        Map param = new HashMap();
        param.put("systemToken", ydConf.getSystemToken());
        param.put("userId", YDConf.PUB_ACCOUNT);
        param.put("fileUrl", url);          // URL在param上时, 需要编码 [UtilHttp已经做了编码] - URLEncoder.encode(url, "UTF-8")
        param.put("timeout", timeout);      // 默认1分钟, 最大24小时 [毫秒]
        return (String) DDR_New.doGet("https://api.dingtalk.com/v1.0/yida/apps/temporaryUrls/" + ydConf.getAppType(), ddClient.initTokenHeader(), param).getResult();
    }

    @Override
    public String convertTemporaryUrl(String url) {
        return convertTemporaryUrl(url, 60000);
    }
}
