package com.awspaas.user.apps.donenow_ctt.controller;

import com.actionsoft.bpms.bo.design.cache.BOCache;
import com.actionsoft.bpms.bo.design.model.BOItemModel;
import com.actionsoft.bpms.bo.design.model.BOModel;
import com.actionsoft.bpms.bo.engine.BO;
import com.actionsoft.bpms.bpmn.engine.model.run.delegate.ProcessInstance;
import com.actionsoft.bpms.commons.database.RowMap;
import com.actionsoft.bpms.commons.mvc.view.ResponseObject;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.server.bind.annotation.Controller;
import com.actionsoft.bpms.server.bind.annotation.Mapping;
import com.actionsoft.bpms.util.DBSql;
import com.actionsoft.sdk.local.SDK;
import com.actionsoft.sdk.local.api.Logger;
import com.awspaas.user.apps.donenow_ctt.service.contractService;
import org.apache.commons.lang3.StringUtils;

import java.sql.Connection;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 合同创建时，使用的接口
 */
@Controller
public class contractCreateController {
    private static final Logger contractLogger = SDK.getLogAPI().getLogger(contractCreateController.class);//记录日志

    /**
     * 提交合同
     * @param uc
     * @param bindid
     * @return
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.contract_submit")
    public ResponseObject contractSubmit(UserContext uc, String bindid) {

        contractLogger.info("contractLogger.info 合同提交后---------------" + bindid);

        Map<String, Object> result = contractService.getInstance().SaveContract(uc, bindid, true);//保存合同


        if (result.getOrDefault("success", false).equals(true)) {


        } else {
            return ResponseObject.newErrResponse("保存失败！");
        }


        return ResponseObject.newOkResponse("保存成功！");
    }

    /**
     * 获取合同详情
     * @param uc
     * @param bindid
     * @return
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.get_contractapply")
    public ResponseObject getContractApply(UserContext uc, String bindid) {

        RowMap contractDetail = DBSql.getMap("SELECT ID,BINDID,PROCESSDEFID FROM BO_EU_DNCTT_CONTRACT WHERE BINDID=? ", new Object[]{bindid});
        if (contractDetail == null || contractDetail.isEmpty())
            contractDetail = DBSql.getMap("SELECT ID,BINDID,PROCESSDEFID FROM BO_EU_DNCTT_CONTRACT_APPLY WHERE BINDID=? ", new Object[]{bindid});

        ResponseObject responseObject = ResponseObject.newOkResponse();

        responseObject.setData(contractDetail);

        return responseObject;
    }

    /**
     * 删除合同
     * @param uc
     * @param bindid
     * @return
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.contract_delete")
    public ResponseObject contractDelete(UserContext uc, String bindid, String id) throws SQLException {

        int cnt = DBSql.getInt("SELECT COUNT(0) FROM BO_EU_DNPRO_PROJECT WHERE CONTRACT_ID=? AND CLOSED=0", new Object[]{id});
        if (cnt > 0) {
            return ResponseObject.newErrResponse("该合同关联了" + cnt + "个项目，无法删除！");
        }
        cnt = DBSql.getInt("SELECT COUNT(0) FROM BO_EU_DNSDK_TASK WHERE CONTRACT_ID=? ", new Object[]{id});
        if (cnt > 0) {
            return ResponseObject.newErrResponse("该合同关联了" + cnt + "个任务，无法删除！");
        }
        cnt = DBSql.getInt("SELECT COUNT(0) FROM BO_EU_DNCRM_INSTALLED_PRODUCT WHERE CONTRACT_ID=? AND CLOSED=0", new Object[]{id});
        if (cnt > 0) {
            return ResponseObject.newErrResponse("该合同关联了" + cnt + "个产品，无法删除！");
        }
        cnt = DBSql.getInt("SELECT COUNT(0) FROM BO_EU_DNCTT_CONTRACT_COST WHERE CONTRACT_ID=? AND CLOSED=0", new Object[]{id});
        if (cnt > 0) {
            return ResponseObject.newErrResponse("该合同关联了" + cnt + "个合同成本，无法删除！");
        }
        cnt = DBSql.getInt("SELECT COUNT(0) FROM BO_EU_DNCRM_ACCOUNT_DEDUCTION WHERE CONTRACT_ID=? ", new Object[]{id});
        if (cnt > 0) {
            return ResponseObject.newErrResponse("该合同关联了" + cnt + "个已计费条目，无法删除！");
        }
        cnt = DBSql.getInt("SELECT COUNT(0) FROM BO_EU_DNSDK_WORK_ENTRY WHERE CONTRACT_ID=? ", new Object[]{id});
        if (cnt > 0) {
            return ResponseObject.newErrResponse("该合同关联了" + cnt + "个工时，无法删除！");
        }

        //如果服务已经审批并提交，则不能删除
        //合同初始费用审批
        cnt = DBSql.getInt("SELECT COUNT(0) FROM BO_EU_DNCTT_CONTRACT WHERE (ID=? OR BINDID=?) AND SETUP_FEE!=0 AND SETUP_FEE IS NOT NULL AND CLOSED=0", new Object[]{id, bindid});
        if (cnt > 0) {
            return ResponseObject.newErrResponse("该合同合同初始费用已审批并提交，无法删除！");
        }

        cnt = DBSql.getInt("SELECT COUNT(0) FROM BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST WHERE (CONTRACT_ID=? OR BINDID=?) AND APPROVE_AND_POST_DATE IS NOT NULL ", new Object[]{id, bindid});
        if (cnt > 0) {
            return ResponseObject.newErrResponse("该合同服务已审批并提交，无法删除！");
        }

        cnt = DBSql.getInt("SELECT COUNT(0) FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE (CONTRACT_ID=? OR BINDID=?) AND APPROVE_AND_POST_DATE IS NOT NULL ", new Object[]{id, bindid});
        if (cnt > 0) {
            return ResponseObject.newErrResponse("该合同服务已审批并提交，无法删除！");
        }


        Connection conn = null;
        try {
            conn = DBSql.open();
            conn.setAutoCommit(false);

            Map<String, Object> params = new HashMap<>();
            params.put("CONTRACT_ID", id);
            params.put("BINDID", bindid);
            //软删除
            updateContractCLOSED(uc, "BO_EU_DNCTT_CONTRACT_RATE", params, conn);
            updateContractCLOSED(uc, "BO_EU_DNCTT_CONTRACT_MILESTONE", params, conn);
            updateContractCLOSED(uc, "BO_EU_DNCTT_CONTRACT_SERVICE", params, conn);
            updateContractCLOSED(uc, "BO_EU_DNCTT_CONTRACT_COST_DEFAULT", params, conn);

            updateContractCLOSED(uc, "BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST", params, conn);
            updateContractCLOSED(uc, "BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD", params, conn);

            updateContractCLOSED(uc, "BO_EU_DNCTT_CONTRACT_SERVICE_BUNDLE_SERVICE", " CONTRACT_SERVICE_ID IN (SELECT ID FROM BO_EU_DNCTT_CONTRACT_SERVICE WHERE (CONTRACT_ID=:CONTRACT_ID OR BINDID=:BINDID)) ", params, conn);

            updateContractCLOSED(uc, "BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST_BUNDLE_SERVICE", " CONTRACT_SERVICE_ADJUST_ID IN (SELECT ID FROM BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST WHERE (CONTRACT_ID=:CONTRACT_ID OR BINDID=:BINDID))  ", params, conn);


            updateContractCLOSED(uc, "BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST_BUNDLE_SERVICE", " CONTRACT_SERVICE_ADJUST_ID IN (SELECT ID FROM BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST WHERE (CONTRACT_ID=:CONTRACT_ID OR BINDID=:BINDID)) ", params, conn);

            updateContractCLOSED(uc, "BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE", " CONTRACT_SERVICE_PERIOD_ID IN (SELECT ID FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE (CONTRACT_ID=:CONTRACT_ID OR BINDID=:BINDID))  ", params, conn);

            BO contractBO = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT", id);
            if (contractBO != null) {
                contractBO.set("CLOSED", 1);
                dn.recordFormChanges.record(uc, contractBO, "删除合同");
                SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT", contractBO, conn);
            }
            if (contractBO == null || contractBO.getBindId().equals(bindid) == false) {
                contractBO = SDK.getBOAPI().getByProcess("BO_EU_DNCTT_CONTRACT", bindid);
                if (contractBO != null) {
                    contractBO.set("CLOSED", 1);
                    dn.recordFormChanges.record(uc, contractBO, "删除合同");
                    SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT", contractBO, conn);
                }
            }

            conn.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            if (conn != null && !conn.isClosed()) conn.rollback();
        } finally {
            if (conn != null) DBSql.close(conn);
        }
        return ResponseObject.newOkResponse();
    }


    /**
     * 关闭合同相关
     * @param uc
     * @param boName
     * @param params
     * @param conn
     */
    private void updateContractCLOSED(UserContext uc, String boName, String SqlWhere, Map<String, Object> params, Connection conn) {
        //获取需要删除的数据

        BOModel boModel = BOCache.getInstance().getModelByEntityName(boName);
        BOItemModel CLOSED = boModel.getItem("CLOSED");

        if (CLOSED != null && CLOSED.getName().equals("CLOSED")) {
            SqlWhere += " AND CLOSED=0";
        }

        List<BO> boList = SDK.getBOAPI().query(boName).addQuerySqlWhere(SqlWhere, params).list();
        for (BO bo : boList) {
            //记录删除日志
            dn.recordFormChanges.deleteBeforeRecord(uc, boName, bo.getId(), "删除", conn);
            SDK.getBOAPI().remove(boName, bo.getId(), conn);
        }
    }

    private void updateContractCLOSED(UserContext uc, String boName, Map<String, Object> params, Connection conn) {
        //获取需要删除的数据

        BOModel boModel = BOCache.getInstance().getModelByEntityName(boName);
        BOItemModel CLOSED = boModel.getItem("CLOSED");
        String whereSql = "";
        if (CLOSED != null && CLOSED.getName().equals("CLOSED")) {
            whereSql = " AND CLOSED=0";
        }

        List<BO> boList = SDK.getBOAPI().query(boName).addQuerySqlWhere(" (CONTRACT_ID=:CONTRACT_ID OR BINDID=:BINDID) " + whereSql, params).list();
        for (BO bo : boList) {
            //记录删除日志
            dn.recordFormChanges.deleteBeforeRecord(uc, boName, bo.getId(), "删除", conn);
            SDK.getBOAPI().remove(boName, bo.getId(), conn);
        }
    }


    /**
     * 合同产品删除
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.contract_cost_delete", desc = "合同产品删除")
    public ResponseObject deleteContractProduct(UserContext uc, String costIds) {
        if (StringUtils.isBlank(costIds)) return ResponseObject.newErrResponse("请选择要删除的条目！");

        String[] costIdArr = costIds.split(",");
        String sql = "SELECT * FROM BO_EU_DNCTT_CONTRACT_COST WHERE ID IN(";
        for (int i = 0; costIdArr.length > i; i++) {
            sql += "?,";
        }
        sql = sql.substring(0, sql.length() - 1) + ")";
        List<RowMap> costList = DBSql.getMaps(sql, Arrays.stream(costIdArr).toArray());

        List<String> errorList = new ArrayList<>();
        for (RowMap cost : costList) {
            //1、判断是否拣货
            if (DBSql.getInt("SELECT COUNT(ID) FROM BO_EU_DNCTT_CONTRACT_COST_PRODUCT WHERE CONTRACT_COST_ID=?", new Object[]{cost.getString("ID")}) > 0) {
                errorList.add(cost.getString("NAME") + "已拣货");
            }
            //2、判断是否创建采购单
            if (DBSql.getInt("SELECT COUNT(ID) FROM BO_EU_DNIVT_ORDER_PRODUCT WHERE CONTRACT_COST_ID=?", new Object[]{cost.getString("ID")}) > 0) {
                errorList.add(cost.getString("NAME") + "已创建采购单");
            }
        }

        if (errorList.size() > 0) {
            return ResponseObject.newErrResponse(StringUtils.join(errorList, "、") + "，无法删除！");
        }

        for (RowMap cost : costList) {
            SDK.getProcessAPI().deleteById(cost.getString("BINDID"), uc.getUID());
        }
        return ResponseObject.newOkResponse();
    }

    /**
     * 删除合同服务
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.contract_service_delete", desc = "删除合同服务")
    public ResponseObject deleteContractService(UserContext uc, String serviceIds) {
        String[] costIdArr = serviceIds.split(",");

        String selSql = "SELECT * FROM BO_EU_DNCTT_CONTRACT_SERVICE WHERE ID IN(";
        for (int i = 0; costIdArr.length > i; i++) {
            selSql += "?,";
        }
        selSql = selSql.substring(0, selSql.length() - 1) + ")";
        List<RowMap> serviceList = DBSql.getMaps(selSql, Arrays.stream(costIdArr).toArray());

        //已审批的合同服务不能删除
        for (RowMap service : serviceList) {
            if (DBSql.getInt("SELECT count(1) FROM BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD WHERE APPROVE_AND_POST_USER_ID IS NOT NULL AND LENGTH(APPROVE_AND_POST_USER_ID)>1 AND APPROVE_AND_POST_DATE IS NOT NULL and CONTRACT_ID=? and CONTRACT_SERVICE_ID=? ", new Object[]{service.get("CONTRACT_ID"), service.get("ID")}) > 0) {
                return ResponseObject.newErrResponse("已审批合同服务，无法删除！");
            }
        }

        for (RowMap service : serviceList) {
            //删除关联的服务调整
            List<String> csaIdList = DBSql.getList("select ID from BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST where CONTRACT_ID=? and CONTRACT_SERVICE_ID=?", String.class, new Object[]{service.get("CONTRACT_ID"), service.get("ID")});

            for (String csaId : csaIdList) {
                DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST_BUNDLE_SERVICE where CONTRACT_SERVICE_ADJUST_ID=? ", new Object[]{csaId});
            }

            DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST where  CONTRACT_ID=? and CONTRACT_SERVICE_ID=?", new Object[]{service.get("CONTRACT_ID"), service.get("ID")});

            //删除关联的服务周期
            List<String> cspIdList = DBSql.getList("select ID from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD where  CONTRACT_ID=? and OBJECT_ID=? and CONTRACT_SERVICE_ID=?", String.class, new Object[]{service.get("CONTRACT_ID"), service.get("OBJECT_ID"), service.get("ID")});
            for (String cspId : cspIdList) {
                DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD_BUNDLE_SERVICE where CONTRACT_SERVICE_PERIOD_ID=? ", new Object[]{cspId});
            }
            DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD where CONTRACT_ID=? and OBJECT_ID=? and CONTRACT_SERVICE_ID=?", new Object[]{service.get("CONTRACT_ID"), service.get("OBJECT_ID"), service.get("ID")});

            DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE where  ID=?", new Object[]{service.get("ID")});

            DBSql.update("delete from BO_EU_DNCTT_CONTRACT_SERVICE_EDIT where  CONTRACT_SERVICE_ID=?", new Object[]{service.get("ID")});
        }

        return ResponseObject.newOkResponse();
    }

    /**
     * 编辑合同服务
     */
    @Mapping(value = "com.awspaas.user.apps.donenow_ctt.contract_service_edit")
    public ResponseObject editContractService(UserContext uc, String serviceId) {

        RowMap contractService = DBSql.getMap("SELECT * FROM BO_EU_DNCTT_CONTRACT_SERVICE WHERE ID=?", new Object[]{serviceId});
        contractService.remove("ID");
        contractService.remove("BINDID");

        ProcessInstance contractInstance = SDK.getProcessAPI().createBOProcessInstance("obj_e4b0c7ae587c406b808f3a4785f05e23", uc.getUID(), "服务调整-" + contractService.getString("NAME") + "-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));

        BO editBO = new BO();

        contractService.remove("CREATEDATE");
        contractService.remove("CREATEUSER");

        editBO.setAll(contractService);
        editBO.set("CONTRACT_SERVICE_ID", serviceId);
        editBO.set("OLD_UNIT_PRICE", contractService.get("UNIT_PRICE"));
        editBO.set("OLD_TOTAL_PRICE", contractService.get("TOTAL_PRICE"));
        editBO.set("OLD_UNIT_COST", contractService.get("UNIT_COST"));
        editBO.set("OLD_QUANTITY", contractService.get("QUANTITY"));
        editBO.set("OLD_TOTAL_COST", contractService.get("TOTAL_COST"));
        editBO.setBindId(contractInstance.getId());

        String maxEffectiveDate = DBSql.getString("SELECT MAX(EFFECTIVE_DATE) FROM BO_EU_DNCTT_CONTRACT_SERVICE_EDIT WHERE CONTRACT_ID=? and CONTRACT_SERVICE_ID=? and IS_EFFECTIVE='已执行' ", new Object[]{contractService.get("CONTRACT_ID"), serviceId});
        if (StringUtils.isBlank(maxEffectiveDate))
            maxEffectiveDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        editBO.set("EFFECTIVE_DATE", maxEffectiveDate);
        editBO.set("IS_EFFECTIVE", "未执行");
        SDK.getBOAPI().create("BO_EU_DNCTT_CONTRACT_SERVICE_EDIT", editBO, contractInstance, uc);

        String processUrl = SDK.getFormAPI().getFormURL(SDK.getPortalAPI().getPortalUrl(), uc.getSessionId(), contractInstance.getId(), null, 1, null, editBO.getId(), null, true);

        ResponseObject responseObject = ResponseObject.newOkResponse();
        responseObject.setData(processUrl);

        return responseObject;
    }

}
