package yem.wm.cm.csrm.form;


import com.alibaba.fastjson.JSONObject;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.form.FormShowParameter;
import kd.bos.form.IFormView;
import kd.bos.form.StyleCss;
import kd.bos.form.container.Tab;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.bos.threads.ThreadPool;
import kd.bos.threads.ThreadPools;
import yem.base.common.utils.YEM;
import yem.wm.cm.csrm.enums.PageIdEnum;
import yem.wm.cm.csrm.enums.TaskLogStatusEnum;
import yem.wm.cm.csrm.utils.BillCommonUtils;
import yem.wm.cm.csrm.utils.QccUtils;
import yem.wm.cm.csrm.utils.TaskUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * 企业风险评估
 *
 * @Author yunshuaiwei
 * @Date 2024/6/6 14:02
 **/
public class RiskAsseFormPlugIn extends AbstractFormPlugin {

    private final static String PAGE_KEY = "RiskAsseFormPlugIn";
    private static final String SUBMIT_TAG = "yem_qccrisk";
    private static final String SCORE_TAG = "yem_score";
    private static Long TASK_TIME;
    private static Long START_TIME = 0L;

    private static final Log log = LogFactory.getLog(RiskAsseFormPlugIn.class);

    class MyTask implements Runnable {
        private final RequestContext rc;

        private final DynamicObject data;

        private final Map<String, String> map;

        private final String searchKey;

        private final Long scorePlan;

        public MyTask(RequestContext rc, DynamicObject data, Map<String, String> map, String searchKey, Long scorePlan) {
            this.rc = rc;
            this.data = data;
            this.map = map;
            this.searchKey = searchKey;
            this.scorePlan = scorePlan;
        }

        //同步更新企查查对应的业务数据
        @Override
        public void run() {
            try {
                RequestContext.set(rc);
                startTask(data, map, searchKey, scorePlan);
            } catch (ExecutionException | InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
    }

    @Override
    public void afterCreateNewData(EventObject e) {
        // TODO 在此添加业务逻辑
        String entityId = this.getView().getParentView().getEntityId();
        if (entityId.equals(PageIdEnum.SEARCH.getPageId())) {
            //隐藏页签控件
            this.getView().setVisible(false, "yem_tabap1");
            initData();
        }
    }

    // 加载展示数据
    private void initData() {
        IFormView view = this.getView();
        FormShowParameter formShowParameter = view.getFormShowParameter();
        String searchKey = formShowParameter.getCustomParam("searchKey");
        Long merchantId = formShowParameter.getCustomParam("merchantId");
        Boolean flag = formShowParameter.getCustomParam("flag");
        Long scorePlan = formShowParameter.getCustomParam("scorePlan");
        //已有数据
        if (flag) {
            DynamicObject scoreMerchant = BusinessDataServiceHelper.loadSingle(PageIdEnum.SCORE_MERCHANT.getPageId(),
                    new QFilter[]{new QFilter("yem_societycreditcode", QCP.equals, searchKey),
                            new QFilter("yem_scoringscheme", QCP.equals, scorePlan)});
            Map<Object, DynamicObject> objectDynamicObjectMap = BusinessDataServiceHelper.loadFromCache(new Object[]{merchantId}, PageIdEnum.MERCHANT_APPLY.getPageId());
            DynamicObject merchantApply = objectDynamicObjectMap.get(merchantId);
            if (YEM.isEmpty(scoreMerchant)) {
                Map<String, String> taskLogTable = TaskUtils.creatTaskTable(merchantApply, SCORE_TAG);
                //启动线程
                MyTask myTask = new MyTask(RequestContext.get(), merchantApply, taskLogTable, searchKey, scorePlan);
                ThreadPools.executeOnce(PAGE_KEY, myTask);
                //任务进度内嵌
                openTaskScheduleBill(view, taskLogTable.get(searchKey), merchantId, searchKey, scorePlan);
            } else {
                view.getModel().setValue("yem_keyno", merchantApply.get("yem_societycreditcode"));
                view.getModel().setValue("yem_registration", merchantApply.get("yem_societycreditcode"));
                view.getModel().setValue("yem_name", merchantApply.get("yem_nameqcc"));
                openMerchantApplyLayout(view, merchantApply.getLong("id"));
                openMerchantScoreLayout(view, scoreMerchant.getLong("id"), scoreMerchant);
                pyramidPage(view, scoreMerchant.getLong("id"));
            }
        } else {
            long currentUserId = UserServiceHelper.getCurrentUserId();
            ORM orm = ORM.create();
            DynamicObject merchantApply = orm.newDynamicObject(PageIdEnum.MERCHANT_APPLY.getPageId()); // 某个单据标识
            //是否准入
            merchantApply.set("yem_isadmit", false);
            merchantApply.set("id", merchantId);
            merchantApply.set("yem_societycreditcode", searchKey);
            merchantApply.set("creator", currentUserId);
            merchantApply.set("billstatus", "A");
            SaveServiceHelper.saveOperate(PageIdEnum.MERCHANT_APPLY.getPageId(), new DynamicObject[]{merchantApply}, OperateOption.create());
            Map<String, String> taskLogTable = TaskUtils.creatTaskTable(merchantApply, SUBMIT_TAG);
            //启动线程
            MyTask myTask = new MyTask(RequestContext.get(), merchantApply, taskLogTable, searchKey, scorePlan);
            ThreadPools.executeOnce(PAGE_KEY, myTask);
            //任务进度内嵌
            openTaskScheduleBill(view, taskLogTable.get(searchKey), merchantId, searchKey, scorePlan);
        }
    }

    /**
     * 打开客商申请布局页
     *
     * @Author yunshuaiwei
     * @Date 2024/6/6 10:40
     **/
    private void openMerchantApplyLayout(IFormView view, Long merchantId) {
        Map<String, Object> maps = new HashMap<>();
        maps.put("merchantId", merchantId);
        BillCommonUtils.openTargetInContainerBill(view, maps, PageIdEnum.MERCHANT_APP_LAYOUT.getPageId(), "yem_flexpanelap11");
    }

    /**
     * 打开评分单布局
     *
     * @Author yunshuaiwei
     * @Date 2024/6/27 11:50
     **/
    private void openMerchantScoreLayout(IFormView view, Long scoreId, DynamicObject scoreMerchant) {
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> tagMap = new HashMap<>();
        tagMap.put("text", map);
        DynamicObject scoringScheme = scoreMerchant.getDynamicObject("yem_scoringscheme");
        map.put("zh_CN", scoringScheme.getString("name"));
        view.updateControlMetadata("yem_tabpageap2", tagMap);
        //显示页签控件
        view.setVisible(true, "yem_tabap1");
        Map<String, Object> maps = new HashMap<>();
        maps.put("scoreId", scoreId);
        maps.put("scorePlan", scoringScheme.getLong("id"));
        BillCommonUtils.openTargetInContainerBill(view, maps, PageIdEnum.SCORE_MERCHANT_LAYOUT.getPageId(), "yem_flexpanelap5");
    }

    /**
     * 内嵌金字塔页签
     *
     * @Author yunshuaiwei
     * @Date 2024/6/28 9:17
     **/
    private void pyramidPage(IFormView view, Long id) {
        view.setVisible(false, "yem_tabpageap");
        Tab tab = view.getControl("yem_tabap");
        //切换金字塔页签
        tab.activeTab("yem_tabpageap1");
        StyleCss styleCss = new StyleCss();
        styleCss.setWidth("100%");
        styleCss.setHeight("100%");
        Map<String, Object> maps = new HashMap<>();
        maps.put("id", id);
        BillCommonUtils.openTargetInContainerBill(view, maps, PageIdEnum.SCORE_PYRAMID.getPageId(), "yem_flexpanelap4", styleCss);
    }

    /**
     * 打开任务进度内嵌表
     * scorePlan：评分方案ID
     *
     * @Author yunshuaiwei
     * @Date 2024/6/6 11:39
     **/
    private void openTaskScheduleBill(IFormView view, String taskLogId, Long merchantId, String searchKey, Long scorePlan) {
        HashMap<String, Object> maps = new HashMap<>();
        StyleCss styleCss = new StyleCss();
        styleCss.setWidth("100%");
        styleCss.setHeight("100%");
        maps.put("taskLogId", taskLogId);
        maps.put("merchantId", merchantId);
        maps.put("searchKey", searchKey);
        maps.put("scorePlan", scorePlan);
        maps.put("billNo", PageIdEnum.CM_PYRAMID.getPageId());
        BillCommonUtils.openTargetInContainerBill(view, maps, PageIdEnum.MULTI_TASK.getPageId(), "yem_flexpanelap3", styleCss);
    }

    /**
     * 启动任务项
     *
     * @Author yunshuaiwei
     * @Date 2024/6/19 16:53
     **/
    public void startTask(DynamicObject merchantApply, Map<String, String> stringMap, String searchKey, Long scorePlan) throws ExecutionException, InterruptedException {
        //获取社会信用代码
        String taskId = stringMap.get(searchKey);
        //任务日志任务项
        DynamicObject task = BusinessDataServiceHelper.loadSingle(taskId, PageIdEnum.TASK_ITEM_LOG.getPageId());
        DynamicObjectCollection taskEntry = task.getDynamicObjectCollection("yem_entryentity");
        START_TIME = System.currentTimeMillis();
        HashMap<String, Object> paramType = new HashMap<>();
        paramType.put("merchantApply", merchantApply);
        //任务日志分录任务项
        paramType.put("loads", taskEntry);
        //设置默认评分方案
        paramType.put("scorPlanId", scorePlan);
        paramType.put("rc", RequestContext.get());
        taskExecute(paramType);
        //修改时间
        task.set("yem_totaltime", timeFormat(System.currentTimeMillis() - START_TIME));
        SaveServiceHelper.save(new DynamicObject[]{task});
    }

    /**
     * 执行任务项
     *
     * @Author yunshuaiwei
     * @Date 2024/6/6 15:54
     **/
    public void taskExecute(Map<String, Object> paramType) {
        ThreadPool executorService = ThreadPools.getOrCreateFixedThreadPool(String.valueOf(UUID.randomUUID()), 5);
        // 定义任务列表
        List<Callable<Map<String, Object>>> tasks = TaskUtils.creatTaskList(paramType);
        if (YEM.isNotEmpty(tasks)) {
            //执行线程任务
            for (Callable<Map<String, Object>> task : tasks) {
                Future<Map<String, Object>> future = executorService.submit(task);
                try {
                    // 等待任务完成并获取结果
                    TASK_TIME = System.currentTimeMillis();
                    Map<String, Object> result = future.get();
                    if (YEM.isEmpty(result)) {
                        log.error(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()) + "Taskerror任务执行失败！！！");
                    } else if ((Boolean) result.get("flag")) {
                        DynamicObject load = (DynamicObject) result.getOrDefault("load", "");
                        QccUtils.updateStatus(load, TaskLogStatusEnum.FINISHED.getStatus(), System.currentTimeMillis() - TASK_TIME, "");
                    }
                } catch (InterruptedException | ExecutionException e) {
                    log.error(e);
                    throw new RuntimeException(e);
                }
            }
            // 关闭线程
            executorService.close();
        }
    }

    /**
     * 企查查数据对接返回结果处理
     *
     * @Author yunshuaiwei
     * @Date 2024/6/12 15:53
     **/
    private void qccReturnProcess(Map<String, Object> result) {
        //应取企查查返回的数据
        JSONObject companyInfo = (JSONObject) result.get("data");
        if (YEM.isEmpty(companyInfo)) {
            this.getView().showTipNotification("企查查中未查询到该企业。");
            return;
        }
        //2. 从返回信息中获取统一社会信用代码
        String keyNo = companyInfo.getString("yem_keyno");
        String name = companyInfo.getString("name");
        String registration = companyInfo.getString("yem_registration");
        this.getView().getModel().setValue("yem_name", name);
        this.getView().getModel().setValue("yem_registration", registration);
        this.getView().getModel().setValue("yem_keyno", keyNo);
    }

    /**
     * 时间格式化
     *
     * @Date 2024/6/19 16:52
     **/
    private static String timeFormat(long ms) {
        long diffInSeconds = ms / 1000;
        long hours = diffInSeconds / 3600;
        long minutes = (diffInSeconds % 3600) / 60;
        long seconds = diffInSeconds % 60;
        long millis = ms % 1000;
        // 使用String.format来格式化输出，确保每部分都是两位数（不足的话前面补0）
        return String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, millis);
    }
}
