package nckd.base.helper;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.basedata.BaseDataServiceHelper;
import kd.bos.servicehelper.org.OrgUnitServiceHelper;
import kd.bos.servicehelper.org.OrgViewType;
import kd.bos.util.StringUtils;
import kd.tmc.fbp.common.helper.SystemStatusCtrolHelper;
import kd.tmc.fbp.common.util.EmptyUtil;
import org.apache.commons.lang3.ObjectUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 工具类
 * @author wanghaiwu_kd
 * @date 2025/04/23
 */
public class CommonHelperUtils {
    /**
     * 根据单据编号获取客户化配置
     * @param number
     * @return
     */
    public static Map<String, String> getCommonParams(String number){
        String selectField = "nckd_entryentity.nckd_key, nckd_entryentity.nckd_value";

        QFilter qFilter = new QFilter("number", QCP.equals, number);
        DynamicObject commonParam = BusinessDataServiceHelper.loadSingle("nckd_commonparams", selectField, qFilter.toArray());
        if (ObjectUtils.isEmpty(commonParam)) {
            return null;
        }

        DynamicObjectCollection entryentity = commonParam.getDynamicObjectCollection("nckd_entryentity");
        if(entryentity == null || entryentity.size() == 0){
            return null;
        }
        Map<String, String> mapentity = entryentity.stream().collect(Collectors.toMap(k->k.getString("nckd_key")
                                                                        , v -> v.getString("nckd_value"),
                                                                            (existing, replacement) -> existing));

        return mapentity;
    }

    /**
     * 获取日期最小时分，最大时分
     * @param date
     * @param isStart
     * @return
     * @throws ParseException
     */
    public static Date getCurDateForm(Date date, boolean isStart) throws ParseException {
        SimpleDateFormat shortformat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat longformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = shortformat.format(date);
        String suffix = " 00:00:00";
        if (!isStart) {
            suffix = " 23:59:59";
        }

        return longformat.parse(dateStr + suffix);
    }

    /**
     * 返回日期字符格式
     * @param date
     * @param pattern
     * @return
     */
    public static String getDateFormatString(Date date, String pattern){
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    /**
     *
     * @param dateString
     * @param pattern
     * @return
     */
    public static Date getDateStringFormat(String dateString, String pattern){
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.parse(dateString);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    public static Date getDateStringFormat(Date date, String pattern){
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.parse(sdf.format(date));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 计算两个日期相差天数
     * @param startDate
     * @param endDate
     * @return
     */
    public static int diffDateD(Date startDate, Date endDate) {
        return Math.round((endDate.getTime() - startDate.getTime()) / 86400000);
    }

    /**
     * 在日期上增加月份
     * @param date
     * @param n
     * @return
     */
    public static Date addMonth(Date date, int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, n);
        return cal.getTime();
    }

    /**
     * 格式化BigDecimal对象
     * @param objValue
     * @return
     */
    public static BigDecimal getBigDecimal(Object objValue) {
        BigDecimal ret = null;

        if (objValue == null || objValue.equals("")) {
            return BigDecimal.ZERO;
        }
        if (objValue instanceof BigDecimal) {
            ret = (BigDecimal) objValue;
        } else if (objValue instanceof String) {
            ret = new BigDecimal((String) objValue);
        } else if (objValue instanceof BigInteger) {
            ret = new BigDecimal((BigInteger) objValue);
        } else if (objValue instanceof Number) {
            ret = new BigDecimal(((Number) objValue).doubleValue());
        } else {
            throw new ClassCastException("Not possible to coerce [" + objValue + "] from class " + objValue.getClass() + " into a BigDecimal.");
        }

        return ret;
    }

    /**
     * 查询实体对象
     * @param entityName
     * @param filterName
     * @param value
     * @return
     */
    public static DynamicObject queryBaseDynamicObject(String entityName, String filterName, String value){
        QFilter qFilter = new QFilter("status", QCP.equals, "C");
        qFilter.and(new QFilter("enable", QCP.equals, "1"));
        qFilter.and(new QFilter(filterName, QCP.equals, value));

        DynamicObject objectInfo = BusinessDataServiceHelper.loadSingle(entityName, qFilter.toArray());

        return objectInfo;
    }

    /**
     * 查询实体对象
     * @param entityName
     * @param filterName
     * @param value
     * @return
     */
    public static DynamicObject queryBillDynamicObject(String entityName, String filterName, String value, String billStatus){
        QFilter qFilter = new QFilter("billstatus", QCP.equals, billStatus);
        qFilter.and(new QFilter(filterName, QCP.equals, value));

        DynamicObject objectInfo = BusinessDataServiceHelper.loadSingle(entityName, qFilter.toArray());

        return objectInfo;
    }

    /**
     * 获取部门所在的公司
     * @param dept
     * @return
     */
    public static DynamicObject getAdminCompany(DynamicObject dept){
        if(dept == null){
            return null;
        }

        QFilter qFilter = new QFilter("view.id", QCP.equals, 1L);
        qFilter.and(new QFilter("org.id", QCP.equals, dept.getLong("id")));
        DynamicObject openOrg = BusinessDataServiceHelper.loadSingle("bos_org_structure", qFilter.toArray());
        if(openOrg == null){
            return null;
        }

        List<Long> parentIds = OrgUnitServiceHelper.getAllSuperiorOrgs(OrgViewType.Admin, openOrg.getLong("org.id"));
        if(!parentIds.contains(openOrg.getLong("org.id"))){
            parentIds.add(openOrg.getLong("org.id"));
        }
        QFilter filterView = new QFilter("view.id", QCP.equals, 1L);
        QFilter filteraOrg = new QFilter("org.id", QCP.in, parentIds);
        QFilter[] filters = new QFilter[]{filterView, filteraOrg};
        String selectProperties = "org, number";
        String orderBy = "longnumber desc";
        DynamicObject[] orgList = BusinessDataServiceHelper.load("bos_org_structure", selectProperties, filters, orderBy);

        for(int i = 0; i < orgList.length; i++){
            DynamicObject adminCompany = BusinessDataServiceHelper.loadSingle(orgList[i].getLong("org.id"), "bos_org");

            if(adminCompany.getDynamicObject("orgpattern") != null){
                String pattern = adminCompany.getDynamicObject("orgpattern").getString("name");
                if(StringUtils.isNotEmpty(pattern) && pattern.contains("公司")){
                    return adminCompany;
                }
            }
        }

        return null;
    }


    /**
     * 获取最新的汇率
     * @param exchangeTableId
     * @param currencyId
     * @param tarCurrencyId
     * @param date
     * @return
     */
    public static BigDecimal getExchangeRate(Long exchangeTableId, Long currencyId, Long tarCurrencyId, Date date){
        if(currencyId.compareTo(tarCurrencyId) == 0){
            return BigDecimal.ONE;
        }
        BigDecimal exchangeRate = BaseDataServiceHelper.getExchangeRate(exchangeTableId, currencyId, tarCurrencyId, date);

        return exchangeRate;
    }

    /**
     * 获取汇率表
     * @param orgId
     * @return
     */
    public static Long getExchageTableId(Long orgId) {
        Map<String, Long> baseAccountingInfo = BaseDataServiceHelper.getBaseAccountingInfo(orgId);
        Long exchangeTableId = null;
        if (EmptyUtil.isNoEmpty(baseAccountingInfo)) {
            exchangeTableId = (Long)baseAccountingInfo.get("exchangeRateTableID");
        }

        if (EmptyUtil.isEmpty(exchangeTableId)) {
            DynamicObject standardExRateTable = SystemStatusCtrolHelper.getStandardExRateTable(orgId);
            if (EmptyUtil.isNoEmpty(standardExRateTable)) {
                exchangeTableId = standardExRateTable.getLong("id");
            }
        }

        return exchangeTableId;
    }

    /**
     * 构造调用esb接口的参数，inputData正常调用第三方接口的参数，通过esb调用时，需要包一层requestHead和requestData
     * 例如：星瀚的获取apptoken接口需要按以下格式
     * {
     * 	"requestHead": {
     *         "system": "XH",
     *         "tenantId": "",
     *         "apiversion": "",
     *         "timestamp": "",
     *         "retrycount": 0,
     *         "mainBodyId": "JY",
     *         "mainBodyEx1": "",
     *         "mainBodyEx2": "",
     *         "mainBodyEx3": ""
     *     },
     * 	"requestData": [{
     * 		"appId": "mdm",
     * 		"appSecret": "6*KIh+kO117xS@qC",
     * 		"tenantid": "jmkd-dev",
     * 		"accountId": "2189944093541401600",
     * 		"language": "zh_CN"
     *        }]
     * }
     * @param inputData，传 null 时，表示原body为 {}
     * @return
     */
    public static String buildEsbApiBodyJSON(JSONObject inputData){
        JSONObject jsonBody = new JSONObject();

        //requestHead参数
        JSONObject requestHead = new JSONObject();

        requestHead.put("system", "");
        requestHead.put("tenantId", "");
        requestHead.put("apiversion", "");
        requestHead.put("timestamp", "");
        requestHead.put("retrycount", "");
        requestHead.put("mainBodyId", "JY");
        requestHead.put("mainBodyEx1", "");
        requestHead.put("mainBodyEx2", "");
        requestHead.put("mainBodyEx3", "");

        jsonBody.put("requestHead", requestHead);

        //requestData参数
        JSONArray requestData = new JSONArray();
        if(inputData != null) {
            requestData.add(inputData);
        }
        jsonBody.put("requestData", requestData);

        return jsonBody.toJSONString();
    }
}
