package com.malk.guyuan.controller;

import com.alibaba.fastjson.JSON;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.common.McR;
import com.malk.service.aliwork.YDClient;
import com.malk.service.dingtalk.DDClient;
import com.malk.service.dingtalk.DDClient_Workflow;
import com.malk.utils.UtilDateTime;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 错误抛出与拦截详见 CatchException
 */
@Slf4j
@RestController
@RequestMapping("/oa/")
public class NhOaTLYController {

    @Autowired
    private DDClient ddClient;

    @Autowired
    private YDClient ydClient;

    @Autowired
    private DDClient_Workflow ddClient_workflow;

    /**
     * 推送审批
     */
    @PostMapping("do-approve")
    public McR doApprove(String processInstanceId, String type) {

        log.info("推送审批, {} {}", type, processInstanceId);
        Map formData=new HashMap();
        // OA组件name, 匹配宜搭组件ID
        formData.put("selectField_m0qg3qz0","审批中");
        Map<String, String> compsId_main = UtilMap.map("出差事由, 出差天数, 外部人员, 出差备注, 出行人（同行人）", "textareaField_lygo9owv, numberField_lygo4abs, textField_m0naj26h, textareaField_lygo9ox1, employeeField_lygo9ox2");
        if ("出差1".equals(type)) {
            formData.put("selectField_m0naj267","出差批准及订票申请");
        }else if ("出差2".equals(type)) {
            formData.put("selectField_m0naj267","出差返程及回家订票申请");
            compsId_main.put("已在外出差及驻地天数","numberField_m0naj26f");
        }else{
            return McR.error("201","类型错误！");
        }

        Map<String, String> compsId_itinerary = UtilMap.map("交通工具, 单程往返, 出发城市, 目的城市, 开始时间, 结束时间, 时长", "textField_lygo9oww, textField_lygo9owx, textField_lygo9owy, textField_lygo9owz, textField_lygvu31i, textField_lygvu31j, numberField_lygo9ox0");
        compsId_main.put("出差明细", "tableField_lygo9owu"); // 子表组件
        syncYD(processInstanceId, "FORM-BD5B7CCC28124B808B9DAD98F153CEDACB79", compsId_main, compsId_itinerary, "itinerary",formData);
        return McR.success();
    }

    /**
     * 推送审批
     */
    @GetMapping("approved")
    public McR approved(String processInstanceId, String result) {

        log.info("审批完成, {} {}", result, processInstanceId);
        List<Map> formList = (List<Map>) ydClient.queryData(YDParam.builder()
                .appType(APP_TYPE)
                .systemToken(SYSTRM_TOKEN)
                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_lyh4y3th",processInstanceId)))
                .formUuid("FORM-BD5B7CCC28124B808B9DAD98F153CEDACB79")
                .build(), YDConf.FORM_QUERY.retrieve_list).getData();
        if(formList!=null&&formList.size()>0){
            ydClient.operateData(YDParam.builder()
                    .appType(APP_TYPE)
                    .systemToken(SYSTRM_TOKEN)
                    .formInstanceId(UtilMap.getString(formList.get(0),"formInstanceId"))
                    .updateFormDataJson(JSON.toJSONString(UtilMap.map("selectField_m0qg3qz0",result)))
                    .build(), YDConf.FORM_OPERATION.update);
        }
        return McR.success();
    }

    /// dingtalk
    final String APP_EKY = "dingbde12wxlamjrfze4";
    final String APP_SECRET = "h1jDsG2Bem2cjpVkxgHtUi_zF3wV8VGM6QJM19-FcnMLfJc4JmgOIQPQSg5yv3Tl";
    /// aliwork
    final String APP_TYPE = "APP_Y5KGBSIKJGG6ZQBTNKSZ";
    final String SYSTRM_TOKEN = "GFA66U91QQDMO11Y7N7YC7MA6U0M236VMM2YLBO11";

    /// 同步OA单据到宜搭
    public void syncYD(String processInstanceId, String formUuid, Map<String, String> compsId_main, Map<String, String> compsId_itinerary, String compId_sub_oa,Map formData) {

        String token = ddClient.getAccessToken(APP_EKY, APP_SECRET);

        Map processData = ddClient_workflow.getProcessInstanceId(token, processInstanceId);
        List<Map> formComponentValues = (List<Map>) processData.get("formComponentValues");

        String userId = String.valueOf(processData.get("originatorUserId"));
        long cDate = UtilDateTime.parse(UtilMap.getString(processData, "createTime"), "yyyy-MM-dd'T'HH:mm").getTime();
        formData.putAll(UtilMap.map("employeeField_ltxqs53k, departmentSelectField_lu20ayky, departmentSelectField_m0naj26d, dateField_ltxqs53j, textField_lygnetw9", Arrays.asList(userId), Arrays.asList(processData.get("originatorDeptId")), Arrays.asList(processData.get("originatorDeptId")), cDate, UtilMap.getString(processData, "businessId")));

        for (String name : compsId_main.keySet()) {
            String compId = compsId_main.get(name);
            // 判定是否子表 [宜搭]
            if (compId.startsWith("tableField_")) {
                List<Map> details = new ArrayList<>();
                // 兼容明细组件, 存在多条情况 [加班跨天才有有明细]
                Optional optional = formComponentValues.stream().filter(item -> compId_sub_oa.equals(item.get("bizAlias"))).findAny();
                if (!optional.isPresent()) {
                    continue;
                }
                String schedule = UtilMap.getString((Map) optional.get(), "value");
                List<Map> itineraryList = ((List<Map>) JSON.parse(schedule));
                // 循环明细数据
                for (Map itinerary : itineraryList) {
                    List<Map> rowValue = (List<Map>) itinerary.get("rowValue");
                    Map rowData = new HashedMap();
                    // 循环子表组件
                    for (String subName : compsId_itinerary.keySet()) {
                        log.info("子表字段, {}", subName);
                        //  加班单跨天 [子表label为空]
                        rowData.put(compsId_itinerary.get(subName), rowValue.stream().filter(item -> subName.equals(item.get("bizAlias")) || subName.equals(item.get("label"))).findAny().get().get("value"));
                    }
                    details.add(rowData);
                }
                formData.put(compId, details);
                continue;
            }
            log.info("主表字段, {}", name);
            // 请假套件: 开始时间 / 结束时间 / 时长 / 单位 / 请假类型
            if ("DDHolidayField".equals(name)) {
                Optional optional = formComponentValues.stream().filter(item -> "DDHolidayField".equals(item.get("componentType"))).findAny();
                if (optional.isPresent()) {
                    String[] ids = compId.split(" / ");
                    List vas = (List) JSON.parse(UtilMap.getString((Map) optional.get(), "value"));
                    for (int i = 0; i < ids.length; i++) {
                        formData.put(ids[i], vas.get(i));
                    }
                }
                continue;
            }
            Map formComp = formComponentValues.stream().filter(item -> name.equals(item.get("name"))).findAny().get();
            Object value = formComp.get("value");
            // 成员组件, 数据处理
            if ("InnerContactField".equals(formComp.get("componentType")) && formComp.containsKey("value")) {
                List<Map> empInfos = (List<Map>) JSON.parse(String.valueOf(formComp.get("extValue")));
                List<String> emplsId = new ArrayList<>();
                for (Map empInfo : empInfos) {
                    emplsId.add(String.valueOf(empInfo.get("emplId")));
                }
                value = emplsId; // 成员多选
            }
            formData.put(compId, value);
        }

        // 用于审批回传
        List<Map> tasks = UtilMap.getList(processData, "tasks");
        formData.put("textField_lygvvyd9", tasks.get(0).get("taskId"));
        formData.put("textField_lygvvyda", tasks.get(0).get("userId"));
        formData.put("textField_lyh4y3th", processInstanceId);
        formData.put("selectField_lyo1uao4", "否"); // 出差是否报销, 否
        formData.put("selectField_lyo1zprd", "是"); // 同步存量数据, 否

        log.info("审批数据, {}", JSON.toJSONString(formData));
        ydClient.operateData(YDParam.builder()
                .appType(APP_TYPE)
                .systemToken(SYSTRM_TOKEN)
                .formUuid(formUuid)
                .formDataJson(JSON.toJSONString(formData))
                .userId(userId)
                .build(), YDConf.FORM_OPERATION.create);
    }

    /**
     * 审批回调
     */
    @PostMapping("approved")
    public McR approved(String processInstanceId, String userId, String taskId, String result) {
        log.info("审批回调, {} {}", processInstanceId, result);
        String accessToken = ddClient.getAccessToken(APP_EKY, APP_SECRET);
//        ddClient_workflow.executeRunningApprove(accessToken, processInstanceId, userId, taskId, result, "", null);
        return McR.success();
    }

    /**
     * 删除/撤销
     */
    @PostMapping("terminate")
    public McR terminate(String processInstanceId, String userId) {
        log.info("删除/撤销, {} {}", processInstanceId, userId);

        String accessToken = ddClient.getAccessToken(APP_EKY, APP_SECRET);
        ddClient_workflow.terminateRunningApprove(accessToken, processInstanceId, true, "发起人撤销", userId);
        return McR.success();
    }
}