package yem.wmc.ca.utils;

import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import kd.bos.db.DBRoute;
import kd.bos.entity.*;
import kd.bos.entity.param.AppParam;
import kd.bos.form.*;
import kd.bos.form.field.events.BeforeF7SelectEvent;
import kd.bos.list.ListShowParameter;
import kd.bos.algo.DataSet;
import kd.bos.algo.Row;
import kd.bos.bill.OperationStatus;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.db.DB;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.exception.KDBizException;
import kd.bos.fileservice.FileItem;
import kd.bos.fileservice.FileService;
import kd.bos.fileservice.FileServiceFactory;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.permission.model.perm.req.field.UserFieldPermSchemeReq;
import kd.bos.servicehelper.AttachmentServiceHelper;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.basedata.BaseDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.parameter.SystemParamServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.bos.util.FileNameUtils;
import org.json.XML;

import static yem.wmc.ca.utils.InvoicingRemarksUtils.getRemarks;

/**
 * 公共类
 */
public class CommonUtils {

    /**
     * 获取当前登录用户主键
     */
    public static Long getCurrentUserId() {
        return RequestContext.get().getCurrUserId();
    }

    /**
     * 获取当前登录用户对象
     */
    public static DynamicObject getCurrentUser() {
        final long currentUserId = RequestContext.get().getCurrUserId();
        return BusinessDataServiceHelper.loadSingleFromCache((Object) currentUserId, "bos_user");
    }


    /**
     * 获取所有系统参数
     *
     * @return
     */
    public static Map getcaParameter(Long OrgId, String entityName) {
        AppParam apm = new AppParam();
        apm.setAppId(getAppId(entityName));
        apm.setOrgId(OrgId);
        // 获取整体应用参数
        Map<String, Object> paramWhole = SystemParamServiceHelper.loadAppParameterFromCache(apm);
        return paramWhole;
    }

    /**
     * 获取指定系统参数
     *
     * @return
     */
    public static Object getcaParameterkey(Long OrgId, String entityName, String key) {
        AppParam apm = new AppParam();
        apm.setAppId(getAppId(entityName));
        apm.setOrgId(OrgId); // 参数的组织ID
        // 获取整体应用参数
        Map<String, Object> paramWhole = SystemParamServiceHelper.loadAppParameterFromCache(apm);
        if (paramWhole.containsKey(key)) {
            return paramWhole.get(key);
        } else {
            return null;
        }
    }

    /**
     * 根据单据标识获取应用id
     *
     * @param entityName 单据标识
     * @return
     */
    public static String getAppId(String entityName) {
        String app_Id = null;
        QFilter qFilter = new QFilter("number", QCP.equals, entityName);
        DynamicObjectCollection query = QueryServiceHelper.query("bos_entitymeta", "bizapp", new QFilter[]{qFilter});
        if (query.size() > 0) {
            app_Id = query.get(0).getString("bizapp");
            DynamicObject bos_devportal_bizapp = BusinessDataServiceHelper.loadSingle(app_Id, "bos_devportal_bizapp");
//            String number = bos_devportal_bizapp.getString("number");
//            String name = bos_devportal_bizapp.getString("name");
        }
        return app_Id;
    }

    /**
     * 判断对象是否为空
     *
     * @param o
     * @return
     */
    public static boolean isNull(final Object o) {
        return o == null || (o instanceof String && ((String) o).length() == 0)
                || (o instanceof StringBuffer && ((StringBuffer) o).length() == 0)
                || (o instanceof List && ((List) o).size() == 0)
                || (o instanceof Collection && ((Collection) o).size() == 0)
                || (o instanceof Object[] && ((Object[]) o).length == 0) || (o instanceof Map && ((Map) o).size() == 0);
    }

    /**
     * 开票备注
     *
     * @return
     */
    public static DynamicObject billingnote(DynamicObject yem_ca_billlogon) {
        DynamicObject yem_transmodbase = yem_ca_billlogon.getDynamicObject("yem_transmodbase");
        if (yem_transmodbase != null) {
            QFilter qFilter = new QFilter("yem_isdefault", QCP.equals, true);
            qFilter.and(new QFilter("yem_transmodbase.name", QCP.equals, yem_transmodbase.getString("name")));
            DynamicObject[] invoicingremarks = BusinessDataServiceHelper.load("yem_invoicingremarks",
                    "id,name,number",
                    new QFilter[]{qFilter}, null);
            if (invoicingremarks.length > 0) {
                long InvoicingRemarksId = invoicingremarks[0].getLong("id");
                String yem_billingnote = getRemarks(InvoicingRemarksId, yem_ca_billlogon.getLong("id"), "yem_ca_cusdec");
                yem_ca_billlogon.set("yem_invoicingremarks", invoicingremarks[0]);
                yem_ca_billlogon.set("yem_billingnote", yem_billingnote.trim());

            }
        }
        return yem_ca_billlogon;
    }

    /**
     * XML转json
     *
     * @param xmltext XML入参
     * @return
     */
    public static String XMLTOJosn(String xmltext) {
        String josn = null;
        try {
            org.json.JSONObject jsonObject = XML.toJSONObject(xmltext);
            String jsonString = jsonObject.toString();
            return jsonString;
        } catch (Exception e) {
            josn = "XML 转 josn 转换失败";
            return josn;
        }
    }

    /**
     * 处理运保杂
     */
    public static DynamicObject ManageYBZ(DynamicObject yem_ca_billlogon, Map map) {
        if (yem_ca_billlogon != null) {
            //金额合计
            BigDecimal yem_sumdecltotal = yem_ca_billlogon.getBigDecimal("yem_sumdecltotal");
            //金额本位币
            BigDecimal yem_sumlocdecltotal = yem_ca_billlogon.getBigDecimal("yem_sumlocdecltotal");
            //进出口日期
            Date yem_fiedatets = yem_ca_billlogon.getDate("yem_fiedatets");
            BigDecimal yem_grosswt = yem_ca_billlogon.getBigDecimal("yem_grosswt");
            BigDecimal yem_exchangerate = yem_ca_billlogon.getBigDecimal("yem_exchangerate");//报关汇率
            if (yem_exchangerate.equals(BigDecimal.ZERO)) {
                //报关币别
                DynamicObject yem_currencybase = yem_ca_billlogon.getDynamicObject("yem_currencybase");
                if (yem_currencybase != null) {
                    yem_exchangerate = exchangerate(yem_fiedatets, yem_currencybase, map);
                    yem_sumlocdecltotal = yem_exchangerate.multiply(yem_sumdecltotal);
                    yem_ca_billlogon.set("yem_sumlocdecltotal", yem_sumlocdecltotal);
                }
            }
            //当前单据运费保费杂费汇总
            BigDecimal SumYBZ = BigDecimal.ZERO;
            //运费标志
            String yem_feemarkname = yem_ca_billlogon.getString("yem_feemarkname").toString();
            if (StringUtils.isNotEmpty(yem_feemarkname) && StringUtils.isNotNull(yem_feemarkname)) {
                DynamicObject yem_feecurrbase = yem_ca_billlogon.getDynamicObject("yem_feecurrbase");//运费币别
                if (yem_feecurrbase != null) {
                    BigDecimal yem_feerate = yem_ca_billlogon.getBigDecimal("yem_feerate");//运费/率
                    BigDecimal feemarkAmt = YBZAmt(yem_feemarkname, yem_fiedatets, yem_feerate, yem_feecurrbase, yem_sumdecltotal, yem_grosswt, map);
                    SumYBZ = SumYBZ.add(feemarkAmt);
                    yem_ca_billlogon.set("yem_feecurrtotal", feemarkAmt);//运费总额（RMB）
                }
            }
            //保费标志
            String yem_insurmarkname = yem_ca_billlogon.getString("yem_insurmarkname").toString();
            if (StringUtils.isNotEmpty(yem_insurmarkname) && StringUtils.isNotNull(yem_insurmarkname)) {
                DynamicObject yem_insurcurbase = yem_ca_billlogon.getDynamicObject("yem_insurcurbase");//保费币别
                if (yem_insurcurbase != null) {
                    BigDecimal yem_insurrate = yem_ca_billlogon.getBigDecimal("yem_insurrate");//保费/率
                    BigDecimal feemarkAmt = YBZAmt(yem_insurmarkname, yem_fiedatets, yem_insurrate, yem_insurcurbase, yem_sumdecltotal, yem_grosswt,map);
                    SumYBZ = SumYBZ.add(feemarkAmt);
                    yem_ca_billlogon.set("yem_insurcurtotal", feemarkAmt);//保费总额（RMB）
                }
            }
            //杂费标志
            String yem_othermarkname = yem_ca_billlogon.getString("yem_othermarkname").toString();
            if (StringUtils.isNotEmpty(yem_othermarkname) && StringUtils.isNotNull(yem_othermarkname)) {
                DynamicObject yem_othercubase = yem_ca_billlogon.getDynamicObject("yem_othercubase");//保费币别
                BigDecimal yem_otherrate = yem_ca_billlogon.getBigDecimal("yem_otherrate");//杂费/率
                BigDecimal feemarkAmt = YBZAmt(yem_othermarkname, yem_fiedatets, yem_otherrate, yem_othercubase, yem_sumdecltotal, yem_grosswt, map);
                SumYBZ = SumYBZ.add(feemarkAmt);
                yem_ca_billlogon.set("yem_othercutotal", feemarkAmt);//运费总额（RMB）
            }
            BigDecimal yem_fobtotal = BigDecimal.ZERO;
            BigDecimal yem_fobtotalusd = BigDecimal.ZERO;
            DynamicObjectCollection yem_ca_cddetailedentry = yem_ca_billlogon.getDynamicObjectCollection("yem_ca_cddetailedentry");
            for (int j = 0; j < yem_ca_cddetailedentry.size(); j++) {
                BigDecimal yem_fobamout = BigDecimal.ZERO;
                BigDecimal yem_fobusd = BigDecimal.ZERO;
                DynamicObject cddetailedentry = yem_ca_cddetailedentry.get(j);
                BigDecimal yem_gqty = cddetailedentry.getBigDecimal("yem_gqty");//数量
                BigDecimal yem_decltotal = cddetailedentry.getBigDecimal("yem_decltotal");//分录总额
                cddetailedentry.set("yem_rmbdecltotal", yem_decltotal.multiply(yem_exchangerate));//分录总额本位币
                if (SumYBZ.equals(BigDecimal.ZERO)) {
                    yem_fobamout = yem_decltotal.multiply(yem_exchangerate).setScale(2, BigDecimal.ROUND_HALF_UP);//FOB总价(RMB)
                    cddetailedentry.set("yem_fobamout", yem_fobamout);
                    if (!yem_gqty.equals(BigDecimal.ZERO)) {
                        cddetailedentry.set("yem_fobprice", yem_fobamout.divide(yem_gqty, 10, BigDecimal.ROUND_UP));//FOB单价(RMB)
                    }
                    if ((BigDecimal.ZERO).compareTo(yem_exchangerate) != 0) {
                        yem_fobusd = yem_fobamout.divide(yem_exchangerate, 10, BigDecimal.ROUND_UP).setScale(2, BigDecimal.ROUND_HALF_UP);
                    }
                    cddetailedentry.set("yem_usdfob", yem_fobusd);
                } else {
                    BigDecimal bl = yem_decltotal.divide(yem_sumdecltotal, 10, BigDecimal.ROUND_UP);
                    BigDecimal ybzrmb = SumYBZ.multiply(bl);
                    yem_fobamout = yem_decltotal.multiply(yem_exchangerate).subtract(ybzrmb).setScale(2, BigDecimal.ROUND_HALF_UP);
                    if ((BigDecimal.ZERO).compareTo(yem_exchangerate) != 0) {
                        yem_fobusd = yem_fobamout.divide(yem_exchangerate, 10, BigDecimal.ROUND_UP).setScale(2, BigDecimal.ROUND_HALF_UP);
                    }
                    cddetailedentry.set("yem_fobamout", yem_fobamout);
                    if (!yem_gqty.equals(BigDecimal.ZERO)) {
                        cddetailedentry.set("yem_fobprice", yem_fobamout.divide(yem_gqty, 10, BigDecimal.ROUND_UP));//FOB单价(RMB)
                    }
                    cddetailedentry.set("yem_usdfob", yem_fobusd);
                }
                yem_fobtotal = yem_fobtotal.add(yem_fobamout);
                yem_fobtotalusd = yem_fobtotalusd.add(yem_fobusd);
            }
            yem_ca_billlogon.set("yem_fobtotal", yem_fobtotal);
            yem_ca_billlogon.set("yem_usdfobtotal", yem_fobtotalusd);
        }
        return yem_ca_billlogon;
    }

    /**
     * 获取汇率
     *
     * @param yem_fiedatets
     * @param yem_currencybase
     * @param map
     * @return
     */
    public static BigDecimal exchangerate(Date yem_fiedatets, DynamicObject yem_currencybase, Map map) {
        BigDecimal exchangerate = BigDecimal.ZERO;
        if (yem_currencybase != null) {
            if (map.containsKey("yem_exchangetype")) {
                String yem_exchangetype = map.get("yem_exchangetype").toString();
                if ("yem".equals(yem_exchangetype)) {
                    Date Min = DateUtils.getMinMonthDate(yem_fiedatets);
                    Date max = DateUtils.getMaxMonthDate(yem_fiedatets);
                    QFilter filter = new QFilter("yem_date", QCP.large_equals, Min)
                            .and(new QFilter("yem_date", QCP.less_equals, max));
                    //查查询字段标
                    String yem_curr = yem_currencybase.getString("number");
                    String Fileid = "yem_" + yem_curr.toLowerCase();//将字段标识转换为小写
                    DynamicObject[] erpcurrency = BusinessDataServiceHelper.load("yem_ca_centralrate",
                            "id,name,number,yem_date," + Fileid + "",
                            new QFilter[]{filter}, "yem_date");
                    if (erpcurrency != null && erpcurrency.length > 0) {
                        DynamicObject yem_ca_billlogon = erpcurrency[0];
                        if (yem_ca_billlogon != null) {
                            exchangerate = BigDecimalUtils.toBigDecimal(yem_ca_billlogon.getString(Fileid)).divide(BigDecimalUtils.one_handred);
                        }
                    }
                } else {
                    LinkedHashMap yem_exratetable = (LinkedHashMap)map.get("yem_exratetable");
                    String number = yem_exratetable.get("number").toString();
                    //获取汇率表
                    long exchangeratetableId = CommonUtils.getexratetable(number);
                    //获取本位币内码
                    long localCurrencyId = CommonUtils.getcurrencyid("CNY");
                    //获取原币内码
                    long endCurrencyId = CommonUtils.getcurrencyid(yem_currencybase.getString("number"));
                    if (exchangeratetableId > 0 && localCurrencyId > 0 && endCurrencyId > 0 && yem_fiedatets != null) {
                        if (localCurrencyId == endCurrencyId) {
                            exchangerate = new BigDecimal(1);
                        } else {
                            exchangerate = BaseDataServiceHelper.getExchangeRate(exchangeratetableId, endCurrencyId, localCurrencyId, yem_fiedatets);
                        }
                    }
                }
            }

        }
        return exchangerate;
    }

    public static BigDecimal YBZAmt(String yem_feemarkname, Date yem_fiedatets, BigDecimal yem_feerate, DynamicObject yem_feecurrbase, BigDecimal yem_sumdecltotal, BigDecimal grosswt, Map map) {
        BigDecimal amt = BigDecimal.ZERO;
        if (yem_feecurrbase != null) {
            BigDecimal yem_feecurrexchangerate = exchangerate(yem_fiedatets, yem_feecurrbase, map);//运费汇率
            if (yem_feemarkname.equals("单价")) {
                BigDecimal yem_grosswt = grosswt.divide(BigDecimalUtils.one_thousand);//毛重
                amt = yem_grosswt.multiply(yem_feerate).multiply(yem_feecurrexchangerate);
            } else if (yem_feemarkname.equals("率")) {
                BigDecimal feerate = yem_feerate.divide(BigDecimalUtils.one_handred);
                amt = yem_sumdecltotal.multiply(feerate).multiply(yem_feecurrexchangerate);
            } else if (yem_feemarkname.equals("总价")) {
                amt = yem_feerate.multiply(yem_feecurrexchangerate);
            }
        }
        return amt;
    }

    /**
     * 获取币别内码
     * @param number 货币代码
     * @return
     */
    public static  long getcurrencyid(String number){
        long fid = 0;
        QFilter filter = new QFilter("number", QCP.equals,number);
        DynamicObject[] currency = BusinessDataServiceHelper.load("bd_currency",
                "id,name,number",
                new QFilter[]{filter}, null);
        if(currency.length>0){
            DynamicObject bd_currency = currency[0];
            if(bd_currency!=null){
                fid= bd_currency.getLong("id");
            }
        }
        return  fid;
    }

    /**
     * 获取汇率表内码
     * @param number 汇率表编码
     * @return
     */
    public static long getexratetable(String number){
        long fid = 0;
        QFilter filter = new QFilter("number", QCP.equals,number);
        DynamicObject[] currency = BusinessDataServiceHelper.load("bd_exratetable",
                "id,name,number",
                new QFilter[]{filter}, null);
        if(currency.length>0){
            DynamicObject bd_currency = currency[0];
            if(bd_currency!=null){
                fid= bd_currency.getLong("id");
            }
        }
        return  fid;
    }

}
