package org.dromara.payment.timer;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson.JSONObject;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.enums.BusRole;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.payment.merchant.domain.BusMerchant;
import org.dromara.payment.merchant.domain.vo.BusMerchantAccountSynVo;
import org.dromara.payment.merchant.domain.vo.BusMerchantAccountVo;
import org.dromara.payment.merchant.mapper.BusMerchantAccountMapper;
import org.dromara.payment.merchant.mapper.BusMerchantAccountSynMapper;
import org.dromara.payment.merchant.mapper.BusMerchantMapper;
import org.dromara.payment.merchant.service.IBusMerchantFlowsService;
import org.dromara.payment.sys.domain.SysSyd;
import org.dromara.settlement.api.RemoteAccountService;
import org.dromara.settlement.api.domain.AccountSyn;
import org.dromara.settlement.api.domain.Result;
import org.dromara.system.api.RemoteNoticeService;
import org.dromara.system.api.domain.vo.RemoteSysNoticeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tech.powerjob.worker.core.processor.ProcessResult;
import tech.powerjob.worker.core.processor.TaskContext;
import tech.powerjob.worker.core.processor.sdk.BasicProcessor;
import tech.powerjob.worker.log.OmsLogger;

/**
 * 同步商户虚拟账户余额
 * @author 张涛
 * @date 2021年9月3日
 */
@Component
public class SynMerchantAccountJob {

    @Autowired
    private BusMerchantAccountSynMapper synDao;

    @Autowired
    private BusMerchantAccountMapper accountDao;

    @Autowired
    private BusMerchantMapper shDao;


    @DubboReference
    private RemoteAccountService accountService;

    @DubboReference
    private RemoteNoticeService noticeService;

    @Autowired
    private IBusMerchantFlowsService merchantFlowsService;

    @XxlJob("SynMerchantAccountJob")
    public void process() throws Exception {
		int minId = 0;
		int limit = 10;
        XxlJobHelper.log("开始同步商户虚拟账户余额");
		Integer lockAccId = null;
		String synBatch = null;
		Integer row = 0;
		try {
			synBatch = DateUtils.parseDateToString("yyyyMMddHHmmssSSS", new Date());
            //补全不存在同步记录的账户, 从bus_merchant_account 到 bus_merchant_account_syn
			synDao.autoNotExist();
			do {
                //分配账户的同步批次
				row = synDao.allotSyns(synBatch,minId,0,limit);
				if(row > 0) {
                    //查询待同步的账户id
					List<BusMerchantAccountSynVo> schools = synDao.selectSyn(synBatch, null);
					for (BusMerchantAccountSynVo accid : schools) {
						lockAccId = accid.getId().intValue();
						if (synDao.lock(synBatch, accid.getId().intValue()) > 0) {
							Result<AccountSyn> rtn = accountService.synAccount(accid.getId().intValue(),(short)1,accid.getSynPosition(),Arrays.asList("转账失败，退回记账服务费","转账退票，退回个人服务费","退回企业服务费","代收小额支付业务手续费"));
							if (rtn.hasError()) {
                                XxlJobHelper.log("同步账户出错："+rtn.getResult());
							}else if (rtn.hasTip()) {
                                XxlJobHelper.log("同步账户："+rtn.getResult());
							}else if (rtn.getRtnData().getAddAmount() > 0) {
                                BusMerchantAccountVo acc = accountDao.selectByAccId(accid.getId().intValue());
                                BusMerchant merchant = shDao.selectById(acc.getMerId());
                                acc.setMerName(merchant.getName());
								//充值的金额
								Long addAmount = merchantFlowsService.saveFlows(acc, rtn.getRtnData());
								if(addAmount > 0) {
                                    noticeService.addNotice(new RemoteSysNoticeVo("商户充值通知", String.format("%s商户往%s充值%s元",merchant.getName(),rtn.getRtnData().getBankType(),new DecimalFormat("0.##").format(addAmount/100.0)), merchant.getId().intValue(), BusRole.MERCHANT));
                                    noticeService.addNotice(new RemoteSysNoticeVo("商户充值通知", String.format("%s商户往%s充值%s元",merchant.getName(),rtn.getRtnData().getBankType(),new DecimalFormat("0.##").format(addAmount/100.0)), rtn.getRtnData().getUnitId().intValue(), BusRole.SERVICE));
								}
							}
							synDao.cancelSyn(accid.getId().intValue());
							minId = accid.getId().intValue();
							lockAccId = null;
						}else {
                            XxlJobHelper.log("同步账户加锁失败："+synBatch+","+ JSONObject.toJSONString(accid));
						}
					}
				}
			} while (row == limit);
		} catch (Exception e) {
			e.printStackTrace();
			// TODO 自动生成的 catch 块
            XxlJobHelper.log("同步商户虚拟账户余额出错（" + minId + "," + limit + "," + lockAccId + "）：",e);
		}finally {
			if(row > 0) {
				try {
					synDao.cancelSynByBatch(synBatch);
				} catch (Exception e) {
                    XxlJobHelper.log("同步商户虚拟账户余额时解锁出错（" + minId + "," + limit + "," + lockAccId + "," + synBatch + "）：", e);
				}
			}
		}
        XxlJobHelper.log("结束同步商户虚拟账户余额");
	}
}
