package nckd.jimin.jyyy.bd.webapi;

import com.alibaba.fastjson.JSONArray;
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.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.openapi.common.custom.annotation.ApiController;
import kd.bos.openapi.common.custom.annotation.ApiParam;
import kd.bos.openapi.common.custom.annotation.ApiPostMapping;
import kd.bos.openapi.common.result.CustomApiResult;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.basedata.BaseDataServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.util.StringUtils;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 插件说明：API接口插件，提供给MDM下发，新增或更新客户至星瀚系统
 */
@ApiController(
        desc = "供应商同步接口，提供给MDM下发",
        value = "nckd-jyyy"
)
public class SynSupplierApiPlugin implements Serializable {
    private static final long serialVersionUID = -3085981137362495579L;
    private static final Log logger = LogFactory.getLog(SynSupplierApiPlugin.class);
    //默认组织ID
    protected static final Long DEFAULT_ORG_ID = 100000L;
    private static final String ENTITY_SUPPLIER = "bd_supplier";

    //所有核算组织map
    private static Map<String, String> allKdOrgName = null;
    private static Map<String, Long> allKdOrgId = null;
    private static List<Long> allOrgIds = null;

    //默认组织
    private static DynamicObject defaultOrg = null;
    //默认供应商状态
    private static DynamicObject supplierStatus = null;
    //默认创建人
    private static DynamicObject createUser = null;
    //供应商分组
    private static DynamicObject supplierGroup = null;
    //默认币别
    private static DynamicObject defaultCurrency = null;

    /**
     *
     * @param bp
     * @return
     */
    @ApiPostMapping("synSupplierForMDM")
    public CustomApiResult<JSONObject> synSupplierForMDM(
            @Valid @ApiParam(value = "供应商信息") JSONArray bp) {

        if(bp == null){
            return returnResult("E", "分发失败，参数不能为空", null);
        } else if(!(bp instanceof JSONArray)){
            return returnResult("E", "分发失败，参数不是JSONArray格式", null);
        }

        //设置全局默认值
        setDefaultValue();

        JSONArray responseData = new JSONArray();

        boolean isAllSuccess = true;

        for(int i = 0; i < bp.size(); i++){
            JSONObject inputData = bp.getJSONObject(i);

            String mdId = inputData.getString("mdId");
            String mdCode = inputData.getString("mdCode");
            String mdDescription = inputData.getString("mdDescription");

            Map<String, String> returnMsg = synSupplier(inputData);

            JSONObject response = new JSONObject();
            response.put("mdId", mdId);
            response.put("mdCode", mdCode);
            response.put("mdDescription", mdDescription);

            if("0000".equals(returnMsg.get("code"))){
                response.put("status", "S");
                response.put("message", "分发成功");
            } else {
                response.put("status", "E");
                response.put("message", "分发失败：" + (returnMsg.get("msg") == null ? "异常" : returnMsg.get("msg").toString()));

                isAllSuccess = false;
            }

            responseData.add(response);
        }

        if(isAllSuccess) {
            return returnResult("S", "分发成功", responseData);
        } else {
            return returnResult("E", "部分分发失败，详情见responseData参数", responseData);
        }
    }

    //全局变量设置默认值
    private void setDefaultValue(){
        //默认创建组织
        defaultOrg = BusinessDataServiceHelper.loadSingle(DEFAULT_ORG_ID, "bos_org");

        QFilter orgFilter = new QFilter("fisaccounting", QCP.equals, "1");
        orgFilter.and(new QFilter("enable", QCP.equals, "1"));
        orgFilter.and(new QFilter("status", QCP.equals, "C"));

        allKdOrgId = new HashMap<>();
        allKdOrgName = new HashMap<>();
        allOrgIds = new ArrayList<>();

        DynamicObject[] orgList = BusinessDataServiceHelper.load("bos_org", "id, number, name", orgFilter.toArray());
        for(DynamicObject org : orgList){
            allKdOrgId.put(org.getString("number"), org.getLong("id"));
            allKdOrgName.put(org.getString("number"), org.getString("name"));

            allOrgIds.add(org.getLong("id"));
        }

        //供应商状态：
        QFilter qFilter  = new QFilter("number", QCP.equals, "ZCGYS");
        supplierStatus = BusinessDataServiceHelper.loadSingleFromCache("bd_supplierstatus", "id, number, name", qFilter.toArray());

        //默认创建人
        createUser = BusinessDataServiceHelper.loadSingle(RequestContext.get().getCurrUserId(), "bos_user");

        //供应商分组
        qFilter = new QFilter("number", QCP.equals, "001");
        qFilter.and(new QFilter("enable", QCP.equals, "1"));
        qFilter.and(new QFilter("status", QCP.equals, "C"));
        supplierGroup = BusinessDataServiceHelper.loadSingleFromCache("bd_suppliergroup", "id, number, name, standard", qFilter.toArray());

        //币别
        qFilter = new QFilter("number", QCP.equals, "CNY");
        defaultCurrency = BusinessDataServiceHelper.loadSingle("bd_currency", qFilter.toArray());
    }

    /**
     * 同步供应商
     * @param jsonData
     * @return
     */
    private Map<String, String> synSupplier(JSONObject jsonData){
        Map<String, String> returnMap = new HashMap<>();

        //供应商编码
        String supplierNumber = jsonData.getString("mdCode");
        //供应商名称
        String supplierName = jsonData.getString("mdDescription");
        //数据来源
        String dataSource = jsonData.getString("dataSource");
        if(StringUtils.isEmpty(dataSource)){
            dataSource = "mdm";
        }

        if(StringUtils.isEmpty(supplierNumber)){
            returnMap.put("code", "500");
            returnMap.put("msg", "供应商编码为空！");

            return returnMap;
        }

        if(StringUtils.isEmpty(supplierName)){
//            supplierName = supplierNumber;

            returnMap.put("code", "500");
            returnMap.put("msg", "供应商名称为空！");

            return returnMap;
        }

        //增加分配公司校验
        JSONArray assignOrgArray = jsonData.getJSONArray("venBukrsE");
        if(assignOrgArray != null && assignOrgArray.size() > 0) {
            boolean needSyn = false;
            for (int index = 0; index < assignOrgArray.size(); index++) {
                JSONObject assignOrg = assignOrgArray.getJSONObject(index);

                String orgCode = assignOrg.getString("venBukrsCode");
                if (allKdOrgId.containsKey(orgCode)) {
                    needSyn = true;
                    break;
                }
            }

            if(!needSyn){
                returnMap.put("code", "0000");
                returnMap.put("msg", "未匹配到分配公司，不做同步！");

                logger.info("mdm supplier syn：" + supplierNumber + "未匹配到分配公司，不做同步！");

                return returnMap;
            }
        } else {
            returnMap.put("code", "0000");
            returnMap.put("msg", "公司信息为空，不做同步！");

            logger.info("mdm supplier syn：" + supplierNumber + "未匹配到分配公司，不做同步！");

            return returnMap;
        }

        //供应商类型：法人企业1，非法人企业2，非企业单位3，个人4，个体户5
        String type = "1";
        //社会信用识别码societycreditcode
        String uniqueCode = jsonData.getString("bpUscc");

        boolean isUpdate = false;
        Long supplierId = 0L;
        Date curDate = new Date();

        QFilter qFilter = new QFilter("createorg", QCP.equals, DEFAULT_ORG_ID);
        qFilter.and(new QFilter("societycreditcode", QCP.equals, uniqueCode));

        DynamicObject supplier = BusinessDataServiceHelper.loadSingleFromCache(ENTITY_SUPPLIER, qFilter.toArray());
        if (supplier == null) {
            supplier = BusinessDataServiceHelper.newDynamicObject(ENTITY_SUPPLIER);
            supplier.set("status", "A");
            supplier.set("createtime", curDate);
        } else {
            supplierId = supplier.getLong("id");
            isUpdate = true;
        }

        supplier.set("nckd_datasource", "mdm");
        supplier.set("societycreditcode", uniqueCode);
        supplier.set("type", type);
        supplier.set("number", supplierNumber);
        supplier.set("name", supplierName);

        //管控策略：1、逐级分配；2、自由分配；5、全局共享；6、管控范围内共享；7、私有
        supplier.set("ctrlstrategy", 2);

        //使用状态：0、禁用；1、可用
        supplier.set("enable", "1");

        //业务职能：1、采购；2、结算；3、付款；4、收货
        supplier.set("bizfunction", ",1,2,3,4,");


        if(supplierStatus != null) {
            supplier.set("supplier_status", supplierStatus);
        }

        supplier.set("creator", createUser);
        supplier.set("createorg", defaultOrg);
        supplier.set("org", defaultOrg);

        supplier.set("group", supplierGroup);

        //子分录--默认分类（支持多分类）
        DynamicObjectCollection groupstandardCol = supplier.getDynamicObjectCollection("entry_groupstandard");
        //先清除分类
        groupstandardCol.clear();

        DynamicObjectType billtype = groupstandardCol.getDynamicObjectType();
        DynamicObject groupdetail = new DynamicObject(billtype);
        groupdetail.set("standardid", supplierGroup.getDynamicObject("standard"));
        groupdetail.set("groupid", supplierGroup);
        groupstandardCol.add(groupdetail);
        supplier.set("entry_groupstandard", groupstandardCol);

        //银行账号分录信息
        JSONArray bankArray = jsonData.getJSONArray("venBank");
        if(bankArray != null && bankArray.size() > 0){
            String bankAccount = "";
            String accountName = "";
            String bankName = "";
            String bankCode = "";
            String primaryAccount = "";
            boolean noDefault = true;

            //判断银行账号是否存在
            DynamicObjectCollection bankEntry  =  supplier.getDynamicObjectCollection("entry_bank");
            DynamicObjectType bankEntryType = bankEntry.getDynamicObjectType();

            //先清除银行账号分录
            bankEntry.clear();
            StringBuilder sb = new StringBuilder();


            if (defaultCurrency == null) {
                returnMap.put("code", "500");
                returnMap.put("msg", "默认币别CNY不存在，请核对币别是否正确！");

                return returnMap;
            }

            for(int index = 0; index < bankArray.size(); index++){
                boolean iscontinue = false;
                String isDefault = "0";

                JSONObject entrybank = bankArray.getJSONObject(index);

                bankAccount = entrybank.getString("venBankAccount");
                accountName = entrybank.getString("venBankAccountName");
                bankCode = entrybank.getString("venBankCode");
                bankName = entrybank.getString("venBankName");
                primaryAccount = entrybank.getString("venBankPrimaryAccount");

                if (StringUtils.isEmpty(bankAccount) || StringUtils.isEmpty(accountName)) {
                    iscontinue = true;

                    sb.append("第" + (index + 1) + "行的银行账号、名称不能为空");
                }
                if (StringUtils.isEmpty(bankCode) || StringUtils.isEmpty(bankName)) {
                    iscontinue = true;

//                    sb.append("第" + (index + 1) + "行的开户银行编号、名称不能为空");
                }

                if(iscontinue){
                    continue;
                }

                //开户银行
                QFilter filterbebank = new QFilter("number", QCP.equals, bankCode);
                filterbebank.and(new QFilter("status", QCP.equals, "C"));
                filterbebank.and(new QFilter("enable", QCP.equals, "1"));

                DynamicObject bebankEntity = BusinessDataServiceHelper.loadSingle("bd_bebank", filterbebank.toArray());
                if (bebankEntity == null) {
                    iscontinue = true;

//                    sb.append("第" + (index + 1) + "行的开户银行在星瀚中不存在");
                }

                if(iscontinue){
                    continue;
                }

                if(noDefault && ("Y".equals(primaryAccount) || index == bankArray.size() - 1)){
                    isDefault = "1";
                    noDefault = false;
                }

                DynamicObject bank = new DynamicObject(bankEntryType);

                bank.set("bankaccount",bankAccount);
                bank.set("accountname",accountName);
                bank.set("iban", "");
                bank.set("isdefault_bank", isDefault);
                bank.set("bank", bebankEntity);
                bank.set("currency", defaultCurrency);

                bankEntry.add(bank);
            }

            if(noDefault && bankEntry.size() > 0){
                for(DynamicObject bank : bankEntry){
                    bank.set("isdefault_bank", "1");

                    break;
                }
            }

            if(sb.length() > 0){
                returnMap.put("code", "500");
                returnMap.put("msg", sb.toString());

                return returnMap;
            }

            supplier.set("entry_bank",bankEntry);
        }

        try {
            //判断是否更新与新增，通过不同方法处理，保存操作会变更状态为保存
            if(isUpdate) {
    //            SaveServiceHelper.update(new DynamicObject[]{customer});
                OperationResult resultSave = SaveServiceHelper.saveOperate(ENTITY_SUPPLIER, new DynamicObject[]{supplier}, OperateOption.create());

                StringBuilder err = new StringBuilder();
                if (resultSave.getSuccessPkIds().size() <= 0) {
                    for (int i = 0; i < resultSave.getAllErrorOrValidateInfo().size(); i++) {
                        String message = resultSave.getAllErrorOrValidateInfo().get(i).getMessage();
                        err.append("/").append(message);
                    }

                    returnMap.put("code", "500");
                    returnMap.put("msg", err.toString());

                    return returnMap;
                }
                supplierId = supplier.getLong("id");
            } else {
                //并发问题，保存前再校验一次
                boolean exists = QueryServiceHelper.exists(ENTITY_SUPPLIER, qFilter.toArray());
                if(exists){
                    returnMap.put("code", "500");
                    returnMap.put("msg", "出现并发问题，当前调用取消执行");

                    return returnMap;
                }

                //新增保存供应商对象
                OperationResult resultSave = SaveServiceHelper.saveOperate(ENTITY_SUPPLIER, new DynamicObject[]{supplier}, OperateOption.create());

                StringBuilder err = new StringBuilder();
                if (resultSave.getSuccessPkIds().size() <= 0) {
                    for (int i = 0; i < resultSave.getAllErrorOrValidateInfo().size(); i++) {
                        String message = resultSave.getAllErrorOrValidateInfo().get(i).getMessage();
                        err.append("/").append(message);
                    }

                    returnMap.put("code", "500");
                    returnMap.put("msg", err.toString());

                    return returnMap;
                } else {
                    supplierId = (Long) resultSave.getSuccessPkIds().get(0);
                }

                DynamicObject customerObj = BusinessDataServiceHelper.loadSingle(supplierId, "bd_supplier");

                OperationResult resultSubmit = OperationServiceHelper.executeOperate("submit", ENTITY_SUPPLIER, new DynamicObject[]{customerObj}, OperateOption.create());

                err.setLength(0);

                if (resultSubmit.getSuccessPkIds().size() <= 0) {
                    for (int i = 0; i < resultSubmit.getAllErrorOrValidateInfo().size(); i++) {
                        String message = resultSubmit.getAllErrorOrValidateInfo().get(i).getMessage();
                        err.append("/").append(message);
                    }

                    returnMap.put("code", "500");
                    returnMap.put("msg", err.toString());

                    return returnMap;
                }

                OperationResult resultAudit = OperationServiceHelper.executeOperate("audit", ENTITY_SUPPLIER, new DynamicObject[]{customerObj}, OperateOption.create());

                err.setLength(0);

                if (resultAudit.getSuccessPkIds().size() <= 0) {
                    for (int i = 0; i < resultAudit.getAllErrorOrValidateInfo().size(); i++) {
                        String message = resultAudit.getAllErrorOrValidateInfo().get(i).getMessage();
                        err.append("/").append(message);
                    }

                    returnMap.put("code", "500");
                    returnMap.put("msg", err.toString());

                    return returnMap;
                }
            }

        } catch(Exception e){
            returnMap.put("code", "500");
            returnMap.put("msg", e.getMessage());

            return returnMap;
        }

//        List<Long> assignOrgIds = new ArrayList<>();
//        List<String> orgCodeList = new ArrayList<>();
//        List<String> orgCodeKdList = new ArrayList<>();
//
//        //分配公司信息
////        JSONArray assignOrgArray = jsonData.getJSONArray("venBukrsE");
//        if(assignOrgArray != null && assignOrgArray.size() > 0){
//            for(int index = 0; index < assignOrgArray.size(); index++){
//                JSONObject assignOrg = assignOrgArray.getJSONObject(index);
//
//                String orgCode = assignOrg.getString("venBukrsCode");
//
//                if(!orgCodeList.contains(orgCode)) {
//                    orgCodeList.add(orgCode);
//
//                    if(allKdOrgId.containsKey(orgCode)){
//                        assignOrgIds.add(allKdOrgId.get(orgCode));
//                        orgCodeKdList.add(allKdOrgName.get(orgCode));
//                    }
//                }
//            }
//
//            if(assignOrgIds.size() > 0) {
//                String assignResult = assignOrg2Supplier(supplierId, allOrgIds);
//
//                if (assignResult.isEmpty()) {
//                    returnMap.put("code", "0000");
//                    returnMap.put("msg", "同步成功、分配成功");
//
//                    return returnMap;
//                } else {
//                    returnMap.put("code", "500");
//                    returnMap.put("msg", "同步成功、分配失败");
//
//                    return returnMap;
//                }
//            }
//
//            if(orgCodeKdList.size() != orgCodeList.size()){
//                List<String> differenceList = orgCodeKdList.stream().filter(item -> !orgCodeKdList.contains(item)).collect(Collectors.toList());
//                if(differenceList.size() > 0){
//                    String unAssignOrgString = String.join(",", differenceList);
//
//                    returnMap.put("code", "500");
//                    returnMap.put("msg", "部分组织分配失败：" + unAssignOrgString + ", 这些组织在星瀚中未匹配到或不是CU！");
//
//                    return returnMap;
//                }
//            }
//        }

        if(allOrgIds.size() > 0) {
            String assignResult = assignOrg2Supplier(supplierId, allOrgIds);

            if (assignResult.isEmpty()) {
                returnMap.put("code", "0000");
                returnMap.put("msg", "同步成功、分配成功");

                return returnMap;
            } else {
                returnMap.put("code", "500");
                returnMap.put("msg", "同步成功、分配失败");

                return returnMap;
            }
        }

        returnMap.put("code", "0000");
        returnMap.put("msg", "同步成功");

        return returnMap;
    }

    /**
     * 客户分配组织
     * @param supplierId
     * @param assignOrgIds
     * @return
     */
    public String assignOrg2Supplier(Long supplierId, List<Long> assignOrgIds) {
        String result = "";

        ArrayList<Long> dataIds = new ArrayList();
        dataIds.add(supplierId);

        List<Long> assignOrgList = BaseDataServiceHelper.getAssignDesOrgs(DEFAULT_ORG_ID,"2",16L);
        //取交集
        Set<Long> intersectOrgs = intersectionLong(assignOrgList, assignOrgIds);
        Map<Long, Map> resultValue = BaseDataServiceHelper.batchAssignWithDetail(ENTITY_SUPPLIER, DEFAULT_ORG_ID, dataIds, new ArrayList(intersectOrgs));
        if (resultValue.isEmpty()){
            result= "";
        }else{
            result = "组织分配错误";
        }
        return result;

    }

    public static Set<Long> intersectionLong(Collection<Long> a, Collection<Long> b) {
        Set<Long> unite = unionLong(a, b);
        Set<Long> cloneFromB = new LinkedHashSet(b);
        unite.removeAll(a);
        cloneFromB.removeAll(unite);
        return cloneFromB;
    }

    public static Set<Long> unionLong(Collection<Long> a, Collection<Long> b) {
        Set<Long> unite = new LinkedHashSet();
        unite.addAll(a);
        unite.addAll(b);
        return unite;
    }

    /**
     * 自定义返回data对象
     * @param code  编码
     * @param message  错误信息
     * @return   CustomApiResult  返回
     */
    public CustomApiResult<JSONObject> returnResult(String code, String message, JSONArray responseData){
        JSONObject reslutData = new JSONObject();

        reslutData.put("status", code);
        reslutData.put("message", message);
        reslutData.put("responseData", responseData);

        return CustomApiResult.success(reslutData);
    }
}
