package com.yem.wm.utils;

import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.EntryType;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.ValueMapItem;
import kd.bos.entity.operate.OperateOptionConst;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.property.ComboProp;
import kd.bos.entity.report.CellStyle;
import kd.bos.form.ClientActions;
import kd.bos.form.ClientProperties;
import kd.bos.form.IClientViewProxy;
import kd.bos.form.IFormView;
import kd.bos.message.api.CountryCode;
import kd.bos.message.api.ShortMessageInfo;
import kd.bos.permission.api.HasPermOrgResult;
import kd.bos.servicehelper.basedata.BaseDataServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.bos.servicehelper.workflow.MessageCenterServiceHelper;
import kd.bos.workflow.engine.msg.info.MessageInfo;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.util.*;

/**
 * 常用工具类
 * 
 * @author longh
 * @date 2020年12月7日 上午11:33:16
 */
public class YEM {

	/**
	 * 获取上下文
	 * 
	 * @return
	 */
	public static RequestContext requestContext() {
		return RequestContext.get();
	}

	/**
	 * 获取当前登录用户id
	 * 
	 * @return
	 */
	public static long getCurrentUserId() {
		return requestContext().getCurrUserId();
	}

	/**
	 * 获取当前登录组织id
	 * 
	 * @return
	 */
	public static long getCurrentOrgId() {
		return requestContext().getOrgId();
	}

	/**
	 * 获取用户可切换的组织结果
	 * 
	 * @return
	 */
	public static HasPermOrgResult getUserChangeAbleOrg() {
		return UserServiceHelper.getUserChangeAbleOrg(getCurrentUserId(), true);
	}

	/**
	 * 获取用户可切换的组织集合
	 * 
	 * @return
	 */
	public static List<Long> getUserChangeAbleOrgIds() {
		return getUserChangeAbleOrg().getHasPermOrgs();
	}

	/**
	 * 获取动态对象类型
	 * 
	 * @param entityKey
	 *            实体标识
	 * @return
	 */
	public static MainEntityType getDataEntityType(String entityKey) {
		return EntityMetadataCache.getDataEntityType(entityKey);
	}

	/**
	 * 获取OperateOption
	 * 
	 * @return
	 */
	public static OperateOption getOption() {
		return OperateOption.create();
	}

	/**
	 * 获取OperateOption，跳过浮框提示
	 * 
	 * @return
	 */
	public static OperateOption getOptionNoMsg() {
		OperateOption option = getOption();
		option.setVariableValue(OperateOptionConst.ISSHOWMESSAGE, Boolean.toString(false));
		return option;
	}

	/**
	 * 获取操作失败信息
	 * 
	 * @param opResult
	 * @return
	 */
	public static String getOpMsg(OperationResult opResult) {
		if (opResult == null) {
			return "";
		}
		List<IOperateInfo> allErrorOrValidateInfo = opResult.getAllErrorOrValidateInfo();
		String msg = opResult.getMessage();
		for (int i = 0; i < allErrorOrValidateInfo.size(); i++) {
			IOperateInfo iOperateInfo = allErrorOrValidateInfo.get(i);
			msg = i == 0 ? msg + "原因:" : msg;
			msg += String.format("%s、%s ", i + 1, iOperateInfo.getMessage());
		}
		return msg;
	}

	/**
	 * 异常转字符串
	 * 
	 * @param e
	 * @return
	 */
	public static String exceptionToStr(Exception e) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		e.printStackTrace(pw);
		String error = sw.toString();
		return error;
	}

	/**
	 * 根据物料、计量单位、基本单位获取转换率
	 * 
	 * @param material
	 * @param srcUnit
	 * @param desUnit
	 * @return
	 */
	public static BigDecimal getUnitRate(Object material, Object srcUnit, Object desUnit) {
		BigDecimal unitRate = BigDecimal.ZERO;
		if (material == null || srcUnit == null || desUnit == null) {
			return unitRate;
		}
		Long materialId = material instanceof DynamicObject ? ((DynamicObject) material).getLong("id")
				: material instanceof String ? Long.valueOf((String) material) : (Long) material;
		Long srcUnitId = srcUnit instanceof DynamicObject ? ((DynamicObject) srcUnit).getLong("id")
				: srcUnit instanceof String ? Long.valueOf((String) srcUnit) : (Long) srcUnit;
		Long desUnitId = desUnit instanceof DynamicObject ? ((DynamicObject) desUnit).getLong("id")
				: desUnit instanceof String ? Long.valueOf((String) desUnit) : (Long) desUnit;
		if (srcUnitId.longValue() == desUnitId.longValue()) {
			return BigDecimal.ONE;
		} else {
			DynamicObject muConv = BaseDataServiceHelper.getMUConv(materialId, srcUnitId, desUnitId);
			if (muConv != null && muConv.getInt("numerator") != 0) {
				unitRate = new BigDecimal(muConv.getInt("numerator"))
						.divide(new BigDecimal(muConv.getInt("denominator")), 10, 4);
			}
		}

		return unitRate;
	}

	/**
	 * 获取汇率
	 * 
	 * @param exchangeRateTable
	 * @param sourceCurrency
	 * @param targetCurrency
	 * @param date
	 * @return
	 */
	public static BigDecimal getExchangeRate(Object exchangeRateTable, Object sourceCurrency, Object targetCurrency,
			Date date) {
		BigDecimal exchangeRate = BigDecimal.ZERO;
		if (exchangeRateTable == null || sourceCurrency == null || targetCurrency == null) {
			return exchangeRate;
		}
		date = date == null ? new Date() : date;
		Long exchangeRateTableId = exchangeRateTable instanceof DynamicObject
				? ((DynamicObject) exchangeRateTable).getLong("id")
				: exchangeRateTable instanceof String ? Long.valueOf((String) exchangeRateTable)
						: (Long) exchangeRateTable;
		Long sourceCurrencyId = sourceCurrency instanceof DynamicObject ? ((DynamicObject) sourceCurrency).getLong("id")
				: sourceCurrency instanceof String ? Long.valueOf((String) sourceCurrency) : (Long) sourceCurrency;
		Long targetCurrencyId = targetCurrency instanceof DynamicObject ? ((DynamicObject) targetCurrency).getLong("id")
				: targetCurrency instanceof String ? Long.valueOf((String) targetCurrency) : (Long) targetCurrency;
		if (sourceCurrencyId.equals(targetCurrencyId)) {
			return BigDecimal.ONE;
		}
		exchangeRate = BaseDataServiceHelper.getExchangeRate(exchangeRateTableId, sourceCurrencyId, targetCurrencyId,
				date);

		return exchangeRate == null ? BigDecimal.ZERO : exchangeRate;
	}

	/**
	 * 改变控件颜色
	 * 
	 * @param view
	 * @param key
	 * @param backColor
	 *            背景色
	 * @param foreColor
	 *            前景色
	 */
	public static void changeCtlColor(IFormView view, String key, String backColor, String foreColor) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put(ClientProperties.BackColor, backColor);
		paramMap.put(ClientProperties.ForeColor, foreColor);
		view.updateControlMetadata(key, paramMap);
	}
	
	/**
	 * 改变控件颜色
	 * add by zhangh 20230714
	 * @param view
	 * @param key
	 * @param backColor
	 *            背景色
	 * @param foreColor
	 *            前景色
	 */
	public static void changeCtlColor(IFormView view, String key, String backColor) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put(ClientProperties.BackColor, backColor);
		view.updateControlMetadata(key, paramMap);
	}

	/**
	 * 改变表格行颜色
	 * 
	 * @param view
	 * @param entryKey
	 * @param index
	 *            行索引
	 * @param backColor
	 *            背景色
	 * @param foreColor
	 *            前景色
	 */
	public static void changeRowColor(IFormView view, String entryKey, int index, String backColor, String foreColor) {
		changeRowColor(view, entryKey, new int[] { index }, backColor, foreColor);
	}

	/**
	 * 改变表格行颜色
	 * 
	 * @param view
	 * @param entryKey
	 * @param indexs
	 *            行索引
	 * @param backColor
	 *            背景色
	 * @param foreColor
	 *            前景色
	 */
	public static void changeRowColor(IFormView view, String entryKey, int[] indexs, String backColor,
			String foreColor) {
		IClientViewProxy proxy = view.getService(IClientViewProxy.class);
		ClientActions.createRowStyleBuilder().setRows(indexs).setBackColor(backColor).setForeColor(foreColor)
				.buildStyle().build().invokeControlMethod(proxy, entryKey);
	}

	/**
	 * 改变表格单元格颜色
	 * 
	 * @param view
	 * @param entryKey
	 * @param index
	 *            行索引
	 * @param backColor
	 *            背景色
	 * @param foreColor
	 *            前景色
	 */
	public static void changeCellColor(IFormView view, String entryKey, String fieldKey, int index, String backColor,
			String foreColor) {
		IClientViewProxy proxy = view.getService(IClientViewProxy.class);
		List<CellStyle> cellStyles = new ArrayList<>();
		CellStyle cs = new CellStyle();
		cs.setBackColor(backColor);
		cs.setForeColor(foreColor);
		cs.setFieldKey(fieldKey);
		cs.setRow(index);
		cellStyles.add(cs);
		ClientActions.createCellStyle().addAll(cellStyles).invokeControlMethod(proxy, entryKey);
	}
	
	/**
	 * 改变表格单元格颜色
	 * add by zhangh 20230714
	 * @param view
	 * @param entryKey
	 * @param index
	 *            行索引
	 * @param backColor
	 *            背景色
	 * @param foreColor
	 *            前景色
	 */
	public static void changeCellColor(IFormView view, String entryKey, String fieldKey, int index, String backColor) {
		IClientViewProxy proxy = view.getService(IClientViewProxy.class);
		List<CellStyle> cellStyles = new ArrayList<>();
		CellStyle cs = new CellStyle();
		cs.setBackColor(backColor);
		cs.setFieldKey(fieldKey);
		cs.setRow(index);
		cellStyles.add(cs);
		ClientActions.createCellStyle().addAll(cellStyles).invokeControlMethod(proxy, entryKey);
	}

	/**
	 * 消息中心-发送消息
	 * 
	 * @param receiverslist
	 *            接收人内码集合
	 * @param type
	 *            消息平台-消息类型 ：可自行设置
	 * @param title
	 *            标题
	 * @param msg
	 *            详细内容
	 * @param tag
	 *            业务标签
	 * @return
	 */
	public static long sendMessage(final List<Long> receiverslist, String type, String title, String msg, String tag) {
		RequestContext requestContext = requestContext();
		String userName = requestContext.getUserName();
		MessageInfo message = new MessageInfo();
		message.setUserIds(receiverslist);
		message.setSenderName(userName);
		message.setType(type);
		message.setTitle(title);
		message.setContent(msg);
		message.setTag(tag);
		return MessageCenterServiceHelper.sendMessage(message);
	}

	/**
	 *  消息中心发送消息
	 * @param receiverslist 消息接受人集合
	 * @param userName 发送人名称
	 * @param type 发送消息类型
	 * @param title 标题
	 * @param msg 详细信息
	 * @param tag 标签
	 * @return 消息中心id
	 */
	public static long sendMessage(final List<Long> receiverslist, String userName,String type, String title, String msg, String tag) {
		MessageInfo message = new MessageInfo();
		message.setUserIds(receiverslist);
		message.setSenderName(userName);
		message.setType(type);
		message.setTitle(title);
		message.setContent(msg);
		message.setTag(tag);
		return MessageCenterServiceHelper.sendMessage(message);
	}

	/**
	 *  发送短信
	 * @param list 接受收集好集合
	 * @param msg  短信内容
	 * @param Signature 短信签名
	 *                  短信签名如项生效 需要修改消息配置为
	 *                  https://api.kingdee.com/msgsrv/sms2
	 */
	public static void SendPhonemessage(List<String> list, String msg,String Signature) {
		ShortMessageInfo messageInfo = new ShortMessageInfo();
		messageInfo.setPhone(list);
		messageInfo.setCountryCode(CountryCode.CN);
		messageInfo.setMessage(msg);
		messageInfo.setSignature(Signature);
		Map<String, Object> stringObjectMap = kd.bos.message.service.handler.MessageHandler.sendShortMessage(messageInfo);
		if (stringObjectMap.size() > 0) {

		}
	}
	/**
	 * 判断对象是否为空
	 * 
	 * @param o
	 * @return
	 */
	public static boolean isEmpty(Object o) {
		if (o == null) {
			return true;
		} else if (o instanceof String) {
			return o.toString().trim().length() == 0;
		} else if (o instanceof Long) {
			return ((Long) o).longValue() == 0L;
		} else if (o instanceof BigDecimal) {
			return ((BigDecimal) o).compareTo(BigDecimal.ZERO) == 0;
		} else if (o instanceof Object[]) {
			return ((Object[]) o).length == 0;
		} else if (!(o instanceof DynamicObject)) {
			return o instanceof Collection ? ((Collection<?>) o).isEmpty() : o == null;
		} else {
			DynamicObject obj = (DynamicObject) o;
			return obj.getPkValue() == null || ((Long) obj.getPkValue()).longValue() == 0L;
		}
	}

	public static boolean isNotEmpty(Object o) {
		return !isEmpty(o);
	}

	/**
	 * 指定字符，截取字符串中最后一个该字符之前或之后的部分
	 * 
	 * @param str
	 * @param symbol
	 *            指定字符
	 * @return
	 */
	public static String substringAfterLast(String str, String symbol) {
		return org.apache.commons.lang.StringUtils.substringAfterLast(str, symbol);
	}

	public static String substringBeforeLast(String str, String symbol) {
		return org.apache.commons.lang.StringUtils.substringBeforeLast(str, symbol);
	}

	/**
	 * Integer转为String固定位数，不足补零
	 * 
	 * @param seq
	 * @param format
	 *            //常用："%04d"，0代表前面要补的字符（不加为空格），4代表字符串长度，d表示参数为整数类型
	 * @return
	 */
	public static String formatInteger(String format, Integer seq) {
		return String.format(format, seq);
	}

	/**
	 * 获得下拉列表的 key - value
	 * 
	 * @param dataEntityType
	 * @param fieldKey
	 * @param flag
	 * @param straight
	 * @return
	 * @author xwudd
	 */
	public static Map<String, String> getComboProp(Object dataEntityType, String fieldKey, Boolean flag,
			Boolean straight) {
		Map<String, String> comboItemMap = new HashMap<String, String>();
		MainEntityType entity = null;
		EntryType entry = null;
		DataEntityPropertyCollection properties = null;
		if (flag == false) {
			entity = (MainEntityType) dataEntityType;
			properties = entity.getProperties();
		} else {
			entry = (EntryType) dataEntityType;
			properties = entry.getProperties();
		}
		ComboProp comboProp = (ComboProp) properties.get(fieldKey);
		List<ValueMapItem> comboItems = comboProp.getComboItems();
		for (ValueMapItem comboItem : comboItems) {
			String name = comboItem.getName().toString();
			String value = comboItem.getValue();
			if (!straight) {
				comboItemMap.put(value, name);
			} else {
				comboItemMap.put(name, value);
			}

		}
		return comboItemMap;
	}
}
