package cn.hmsoft.pay.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hmsoft.application.SpringHelper;
import cn.hmsoft.frame.constants.FrameStatus;
import cn.hmsoft.frame.module.FrameModuleConfig;
import cn.hmsoft.helper.StringHelper;
import cn.hmsoft.log.LogHelper;
import cn.hmsoft.pay.constants.HmsoftPayConst;
import cn.hmsoft.pay.data.dao.PayMerchantChannelDao;
import cn.hmsoft.pay.data.model.PayChannelDefine;
import cn.hmsoft.pay.data.model.PayChannelInfo;
import cn.hmsoft.pay.data.model.PayMerchantChannel;
import cn.hmsoft.pay.data.model.PayMerchantDefine;
import cn.hmsoft.pay.impl.PayChannelAbstract;
import cn.hmsoft.pay.service.PayAbstractService;

public class PayModuleConfig extends FrameModuleConfig {

	private static Map<String, PayChannelAbstract> GobalPayMap = null;
	public static Map<String, List<PayChannelInfo>> GobalPayChannelInfoMap = null;

	public PayModuleConfig() {
		// this.module_name = PayParamUtil.ModuleName;
		// this.module_ailas = PayParamUtil.ModuleAlias;
		// this.module_version = PayParamUtil.ModuleVersion;
	}

	@Override
	protected boolean restart() throws Exception {
		return start();
	}

	@SuppressWarnings("unchecked")
	@Override
	protected boolean start() throws Exception {
		String clazz = this.module.getParamMap().get("BusinessClass");
		if (StringHelper.isEmpty(clazz)) {
			LogHelper.error("未找到支付插件的必要配置属性：BusinessClass");
			return false;
		}

		try {
			PayParamUtil.PayCallbackService = (Class<PayAbstractService>) (Class.forName(clazz));
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (PayParamUtil.PayCallbackService == null) {
			LogHelper.error("未能正常初始化支付回调函数：" + clazz);
			return false;
		}
		initializePayModule();
		return true;

	}

	@Override
	protected boolean stop() throws Exception {
		return true;
	}

	/**********************************
	 * 获取商户对应渠道的实现类
	 * 
	 * @param merchant_id 商户编号
	 * @param channel_id 渠道编号
	 * @return
	 */
	public static PayChannelAbstract getPayImpl(String merchant_id, String channel_id) {
		String key = getPayKey(merchant_id, channel_id);
		if (GobalPayMap == null || !GobalPayMap.containsKey(key))
			return null;
		return GobalPayMap.get(key);
	}

	/*********************************
	 * 初始化所有商户及对应的渠道
	 */
	private static boolean initializePayModule() {

		GobalPayMap = new HashMap<String, PayChannelAbstract>();
		GobalPayChannelInfoMap = new HashMap<String, List<PayChannelInfo>>();
		// 加载所有渠道
		PayMerchantChannelDao daoPay = SpringHelper.getBean(PayMerchantChannelDao.class);
		daoPay.init();
		List<PayChannelDefine> channelArray = daoPay.list(PayChannelDefine.class, "channel_status",
				FrameStatus.Active.toString());
		List<PayMerchantDefine> merchantArray = daoPay.list(PayMerchantDefine.class, "merchant_status",
				FrameStatus.Active.toString());
		if (merchantArray.size() == 0) {
			LogHelper.warn(PayParamUtil.ModuleAlias + ":未启用，未配置任何商户");
			return false;
		}
		Map<String, PayChannelDefine> channelMap = new HashMap<String, PayChannelDefine>();
		for (PayChannelDefine pay : channelArray)
			channelMap.put(pay.getChannel_id(), pay);

		List<PayMerchantChannel> mcArray = daoPay.all(PayMerchantChannel.class);
		int merchantCount = 0;
		for (PayMerchantDefine merchant : merchantArray) {

			// 加载
			int mcCount = 0;
			for (PayMerchantChannel mc : mcArray) {
				if (mc.getMerchant_id().equals(merchant.getMerchant_id())) {
					boolean flag = initializeMerchant(channelMap.get(mc.getChannel_id()), mc, merchant);
					if (flag) {
						if (!GobalPayChannelInfoMap.containsKey(merchant.getMerchant_id()))
							GobalPayChannelInfoMap.put(merchant.getMerchant_id(), new ArrayList<PayChannelInfo>());
						// 该商户的该渠道正常，启动中
						daoPay.setRunning(mc.getMerchant_id(), mc.getChannel_id());
						PayChannelInfo info = new PayChannelInfo();
						info.setChannel_id(mc.getChannel_id());
						info.setChannel_name(channelMap.get(mc.getChannel_id()).getChannel_name());
						info.setLarge_image(mc.getLarge_image());
						info.setNormal_image(mc.getNormal_image());
						info.setSmall_image(mc.getSmall_image());
						GobalPayChannelInfoMap.get(mc.getMerchant_id()).add(info);
						mcCount++;
					}
				}
			}
			if (mcCount > 0)
				merchantCount++;
		}
		if (merchantCount > 0) {
			LogHelper.info(PayParamUtil.ModuleAlias + ":启用，共[" + merchantCount + "]个有效商户，支付后业务处理类["
					+ PayParamUtil.PayCallbackService.getName() + "]");
			return true;
		} else {
			LogHelper.warn(PayParamUtil.ModuleAlias + ":未启用，未配置任何有效的商户渠道");
			return false;
		}
	}

	private static boolean initializeMerchant(PayChannelDefine channel, PayMerchantChannel mc,
			PayMerchantDefine merchant) {
		String clazz_name = "cn.hmsoft.pay.impl.Pay" + channel.getChannel_id() + "ChannelImpl";
		PayChannelAbstract pay = null;
		try {
			pay = (PayChannelAbstract) Class.forName(clazz_name).newInstance();
		} catch (Exception e) {
			LogHelper.error(e);
		}
		if (pay == null) {
			LogHelper.error(PayParamUtil.ModuleAlias + ":支付渠道[" + channel.getChannel_name() + "]暂不支持，请联系开发部门");
			return false;
		}

		boolean flag = pay.init(channel, mc, merchant);
		String key = getPayKey(merchant.getMerchant_id(), channel.getChannel_id());
		if (flag) {
			LogHelper.info(PayParamUtil.ModuleAlias + ":商户[" + merchant.getMerchant_name() + "]支付渠道["
					+ channel.getChannel_name() + "]成功加载");
			GobalPayMap.put(key, pay);
		}
		return flag;
	}

	private static String getPayKey(String merchant_id, String channel_id) {
		return "Pay_" + merchant_id + "_" + channel_id;
	}

	@Override
	public String setModule_name() {
		return HmsoftPayConst.MODULE_NAME;
	}

	@Override
	public String setModule_version() {
		return HmsoftPayConst.MODULE_VERSION;
	}

}
