package com.malk.service.aliwork.impl;

import com.malk.server.aliwork.YDAuth;
import com.malk.server.dingtalk.DDR_New;
import com.malk.service.aliwork.YDClient_Process;
import com.malk.service.dingtalk.DDClient;
import com.malk.utils.UtilRespMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

import static com.malk.service.aliwork.impl.YDHelpers.assertResult;
import static com.malk.service.aliwork.impl.YDHelpers.body;
import static com.malk.service.aliwork.impl.YDHelpers.mergeExt;
import static com.malk.service.aliwork.impl.YDHelpers.normPage;
import static com.malk.service.aliwork.impl.YDHelpers.normPageSize;
import static com.malk.service.aliwork.impl.YDHelpers.normSearchField;
import static com.malk.service.aliwork.impl.YDHelpers.url;
import static com.malk.service.aliwork.impl.YDHelpers.validatePageSize;

/**
 * 宜搭流程原子接口实现
 *
 * <p>URL 路径参照旧 YDClientImpl 已验证 endpoint（start/search_process）；新增 endpoint 推断自
 * 宜搭开放平台惯例，实施冒烟时需对照最新官方文档确认。</p>
 *
 * <p>共用 helper 见 {@link YDHelpers}；响应类型守卫见 {@link UtilRespMapper}。</p>
 */
@Slf4j
@Service
public class YDClient_ProcessImpl implements YDClient_Process {

    @Autowired
    private DDClient ddClient;

    private Map<String, String> header(YDAuth auth) {
        if (auth.getAccessToken() != null && !auth.getAccessToken().isEmpty()) {
            Map<String, String> h = new HashMap<>();
            h.put("x-acs-dingtalk-access-token", auth.getAccessToken());
            return h;
        }
        return ddClient.initTokenHeader();
    }

    // ================================================================
    //  流程实例生命周期
    // ================================================================

    @Override
    public String startProcess(YDAuth auth, String processCode, String formUuid, String formDataJson, Map<String, Object> body_ext) {
        Map<String, Object> body = body(auth);
        body.put("processCode", processCode);
        body.put("formUuid", formUuid);
        body.put("formDataJson", formDataJson);
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/instances/start"), header(auth), null, body), "startProcess");
        return UtilRespMapper.asString(r.getResult());
    }

    @Override
    public Boolean terminateProcess(YDAuth auth, String processInstanceId, Map<String, Object> body_ext) {
        Map<String, Object> body = body(auth);
        body.put("processInstanceId", processInstanceId);
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/instances/terminate"), header(auth), null, body), "terminateProcess");
        return UtilRespMapper.asBool(r.getResult());
    }

    @Override
    public Boolean revokeProcess(YDAuth auth, String processInstanceId, Map<String, Object> body_ext) {
        Map<String, Object> body = body(auth);
        body.put("processInstanceId", processInstanceId);
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/instances/revoke"), header(auth), null, body), "revokeProcess");
        return UtilRespMapper.asBool(r.getResult());
    }

    @Override
    public Boolean redirectProcess(YDAuth auth, String processInstanceId, String targetActivityId, Map<String, Object> body_ext) {
        Map<String, Object> body = body(auth);
        body.put("processInstanceId", processInstanceId);
        body.put("targetActivityId", targetActivityId);
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/instances/redirect"), header(auth), null, body), "redirectProcess");
        return UtilRespMapper.asBool(r.getResult());
    }

    // ================================================================
    //  审批任务动作
    // ================================================================

    @Override
    public Boolean agreeTask(YDAuth auth, String processInstanceId, String taskId, String comment, Map<String, Object> body_ext) {
        Map<String, Object> body = body(auth);
        body.put("processInstanceId", processInstanceId);
        body.put("taskId", taskId);
        body.put("remark", comment);
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/tasks/agree"), header(auth), null, body), "agreeTask");
        return UtilRespMapper.asBool(r.getResult());
    }

    @Override
    public Boolean disagreeTask(YDAuth auth, String processInstanceId, String taskId, String comment, Map<String, Object> body_ext) {
        Map<String, Object> body = body(auth);
        body.put("processInstanceId", processInstanceId);
        body.put("taskId", taskId);
        body.put("remark", comment);
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/tasks/disagree"), header(auth), null, body), "disagreeTask");
        return UtilRespMapper.asBool(r.getResult());
    }

    @Override
    public Boolean redirectTask(YDAuth auth, String processInstanceId, String taskId, String toUserId, String comment, Map<String, Object> body_ext) {
        Map<String, Object> body = body(auth);
        body.put("processInstanceId", processInstanceId);
        body.put("taskId", taskId);
        body.put("toUserId", toUserId);
        body.put("remark", comment);
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/tasks/redirect"), header(auth), null, body), "redirectTask");
        return UtilRespMapper.asBool(r.getResult());
    }

    @Override
    public Boolean ccTask(YDAuth auth, String processInstanceId, String taskId, List<String> toUserIds, String comment, Map<String, Object> body_ext) {
        Map<String, Object> body = body(auth);
        body.put("processInstanceId", processInstanceId);
        body.put("taskId", taskId);
        body.put("toUserIds", toUserIds);
        body.put("remark", comment);
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/tasks/cc"), header(auth), null, body), "ccTask");
        return UtilRespMapper.asBool(r.getResult());
    }

    @Override
    public Boolean commentTask(YDAuth auth, String processInstanceId, String taskId, String comment, Map<String, Object> body_ext) {
        Map<String, Object> body = body(auth);
        body.put("processInstanceId", processInstanceId);
        body.put("taskId", taskId);
        body.put("remark", comment);
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/tasks/comment"), header(auth), null, body), "commentTask");
        return UtilRespMapper.asBool(r.getResult());
    }

    // ================================================================
    //  流程与任务查询
    // ================================================================

    @Override
    public Map<String, Object> getProcess(YDAuth auth, String processInstanceId, Map<String, Object> body_ext) {
        Map<String, Object> param = mergeExt(body(auth), body_ext);
        DDR_New r = assertResult(
                DDR_New.doGet(url("/processes/instances/" + processInstanceId), header(auth), param),
                "getProcess"
        );
        return UtilRespMapper.asMap(r.getResult());
    }

    @Override
    public Map<String, Object> searchProcesses(YDAuth auth, String formUuid, String processCode, String searchFieldJson,
                                               Integer currentPage, Integer pageSize, Map<String, Object> body_ext) {
        validatePageSize(pageSize);
        Map<String, Object> body = body(auth);
        body.put("formUuid", formUuid);
        body.put("processCode", processCode);
        body.put("searchFieldJson", normSearchField(searchFieldJson));
        body.put("currentPage", normPage(currentPage));
        body.put("pageSize", normPageSize(pageSize));
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/instances"), header(auth), null, body), "searchProcesses");
        return UtilRespMapper.asMap(r.getResult());
    }

    @Override
    public List<String> listProcessIds(YDAuth auth, String formUuid, String processCode, String searchFieldJson,
                                       Integer currentPage, Integer pageSize, Map<String, Object> body_ext) {
        Map<String, Object> body = body(auth);
        body.put("formUuid", formUuid);
        body.put("processCode", processCode);
        body.put("searchFieldJson", normSearchField(searchFieldJson));
        body.put("currentPage", normPage(currentPage));
        body.put("pageSize", normPageSize(pageSize));
        body = mergeExt(body, body_ext);
        DDR_New r = assertResult(DDR_New.doPost(url("/processes/instanceIds"), header(auth), null, body), "listProcessIds");
        return UtilRespMapper.asStringList(r.getResult());
    }

    @Override
    public List<Map<String, Object>> listApprovalRecords(YDAuth auth, String processInstanceId, Map<String, Object> body_ext) {
        Map<String, Object> param = body(auth);
        param.put("processInstanceId", processInstanceId);
        param = mergeExt(param, body_ext);
        DDR_New r = assertResult(DDR_New.doGet(url("/processes/operationRecords"), header(auth), param), "listApprovalRecords");
        return UtilRespMapper.asMapList(r.getResult());
    }
}
