package com.malk.cloudpure.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.aliwork.YDService;
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("lanyun")
public class TLYController {

    @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);
        // OA组件name, 匹配宜搭组件ID
        if ("出差".equals(type)) {
            Map<String, String> compsId_main = UtilMap.map("出差类型, 预算, 出差天数, 出差事由, 出差备注", "textField_lygo4abp, numberField_lygo9owt, numberField_lygo4abs, textareaField_lygo9owv, textareaField_lygo9ox1");
            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-210DA087671044F8A5CD72F0E9E89060SZ8Q", compsId_main, compsId_itinerary, "itinerary");
        }
        if ("加班".equals(type)) {
            Map<String, String> compsId_main = UtilMap.map("加班人, 加班类型, 开始时间, 结束时间, 时长, 甲方付费, 加班原因", "employeeField_lygnp948, textField_lygnetwa, textField_lygwcloa, textField_lygwclob, numberField_lygnetwe, textField_lygnetwf, textareaField_lygnetwg");
            Map<String, String> compsId_itinerary = UtilMap.map("加班时间, overtimeDuration", "textField_lygwclo8, numberField_lygnetwd");
            compsId_main.put("明细", "tableField_lygnetwc"); // 子表组件
            syncYD(processInstanceId, "FORM-B33388047A42479BB6387F9E0B453588EZ4P", compsId_main, compsId_itinerary, "everyDayDuration");
        }
        if ("请假".equals(type)) {
            Map<String, String> compsId_main = UtilMap.map("DDHolidayField, 请假事由, 代班人", "textField_lyh0xukm / textField_lyh0xukn / numberField_lygo4abs / radioField_lyh0xuko / textField_lygo4abp, textareaField_lygo4abt, employeeField_lygo4abu");
            syncYD(processInstanceId, "FORM-FB29F35DF0A04DC2A5F2860E9593C9C6XCMT", compsId_main, null, "");
        }
        if ("调班".equals(type)) {
            Map<String, String> compsId_main = UtilMap.map("申请类型, 原班次名称, 原考勤时间, 新班次考勤时间, 新班次有效时长, 处理状态", "selectField_lygnsggb, textField_lygnsgg6, textField_lygnsgg7, textField_lygnsgg8, textField_lygnsgg9, selectField_lygnsgga");
            syncYD(processInstanceId, "FORM-777EB143B87D45F2ACB228A024290E1A9GSF", compsId_main, null, "");

        }
        return McR.success();
    }

    /// dingtalk
    final String APP_EKY = "dingfwn4kpmb4g3dy4fj";
    final String APP_SECRET = "OwdkUc9nvBivpwsg0AiaEcyWLtZ678fskqBJwP7B5CQNrycIoyKuWslFTCOOaZG4";
    /// aliwork
    final String APP_TYPE = "APP_ERBDTFS82HOVBPL3NFH0";
    final String SYSTRM_TOKEN = "RRB66F91T97H1WN89QZYC47PKLZO2ZQOUMOQLP";

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

        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();
        Map formData = UtilMap.map("employeeField_ltxqs53k, departmentSelectField_lu20ayky, dateField_ltxqs53j, textField_lygnetw9", Arrays.asList(userId), 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.start);
    }

    /**
     * 审批回调
     */
    @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();
    }


    @Autowired
    private YDService ydService;

    @GetMapping("test")
    McR test() {


//        long beginTime = UtilDateTime.parseDateTime("2024-06-01 00:00:00").getTime();
//        long finishTime = UtilDateTime.parseDateTime("2024-07-17 00:00:00").getTime();
//
//        Map extInfo = UtilMap.map("statuses", Arrays.asList("COMPLETED"));
//        List<String> dataList = ddClient_workflow.getInstanceIds_all(ddClient.getAccessToken(), "PROC-6E40CB5E-F2AE-4CE6-9864-F5C3848D0C7E", beginTime, finishTime, extInfo);


        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-210DA087671044F8A5CD72F0E9E89060SZ8Q")
                .systemToken(SYSTRM_TOKEN)
                .appType(APP_TYPE)
                .build());
        for (Map map : dataList) {

            if (UtilMap.isBlankString(map, "selectField_lyo1uao4")) {
                ydClient.operateData(YDParam.builder()
                        .formInstanceId(UtilMap.getString(map, "instanceId"))
                        .updateFormDataJson(JSON.toJSONString(UtilMap.map("selectField_lyo1uao4, selectField_lyo1zprd", "否", "否")))
                        .build(), YDConf.FORM_OPERATION.update);
            }
        }
        return McR.success();
    }
}


