package com.ym.mec.biz.service.impl;

import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.entity.CloudCoachPaymentProgram;
import com.ym.mec.biz.dal.entity.CloudTeacherOrder;
import com.ym.mec.biz.dal.entity.MemberRankSetting;
import com.ym.mec.biz.dal.enums.MessageTypeEnum;
import com.ym.mec.biz.service.*;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.common.tenant.TenantContextHolder;
import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
import com.ym.mec.util.collection.MapUtil;
import com.ym.mec.util.http.HttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class CloudCoachPaymentProgramServiceImpl extends BaseServiceImpl<Long, CloudCoachPaymentProgram>  implements CloudCoachPaymentProgramService {
	
	@Autowired
	private CloudCoachPaymentProgramDao cloudCoachPaymentProgramDao;
	@Autowired
	private StudentCloudCoachPaymentDetailsDao studentCloudCoachPaymentDetailsDao;
	@Autowired
	private MemberFeeSettingService memberFeeSettingService;
	@Autowired
	private MemberRankSettingDao memberRankSettingDao;
	@Autowired
	private TenantConfigService tenantConfigService;
	@Autowired
	private CloudTeacherOrderService cloudTeacherOrderService;
	@Autowired
	private SysConfigDao sysConfigDao;
	@Autowired
	private SysMessageService sysMessageService;
	@Autowired
	private TeacherDao teacherDao;
	@Autowired
	private SysUserFeignService sysUserFeignService;

	@Override
	public BaseDAO<Long, CloudCoachPaymentProgram> getDAO() {
		return cloudCoachPaymentProgramDao;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void add(CloudCoachPaymentProgram cloudCoachPaymentProgram) {
		List<Integer> userIds = cloudCoachPaymentProgram.getUserIds();
		if(userIds == null || userIds.size() == 0){
			throw new BizException("请选择学员");
		}
		Integer tenantId = TenantContextHolder.getTenantId();
		//获取原价
		BigDecimal originalFee = memberFeeSettingService.getAmount(cloudCoachPaymentProgram.getOrganId(),
				cloudCoachPaymentProgram.getMemberRankSettingId(),
				cloudCoachPaymentProgram.getPeriod(),
				cloudCoachPaymentProgram.getMemberNum(),
				MemberFeeSettingServiceImpl::getOriginalFee);
		cloudCoachPaymentProgram.setOriginalAmount(originalFee);
		//获取会员名称
		MemberRankSetting memberRankSetting = memberRankSettingDao.get(cloudCoachPaymentProgram.getMemberRankSettingId());
		cloudCoachPaymentProgram.setName(memberRankSetting.getName());
		cloudCoachPaymentProgram.setUserNum(userIds.size());
		cloudCoachPaymentProgram.setTenantId(tenantId);
		//获取缴费状态
		cloudCoachPaymentProgram.setStatus(getStatus(cloudCoachPaymentProgram));
		//是否自动激活
		cloudCoachPaymentProgram.setAutoActivationFlag(tenantConfigService.autoActivationFlag(tenantId));
		cloudCoachPaymentProgramDao.insert(cloudCoachPaymentProgram);
		studentCloudCoachPaymentDetailsDao.batchInsert(cloudCoachPaymentProgram.getId(),userIds,tenantId);
		if(cloudCoachPaymentProgram.getStatus() == CloudCoachPaymentProgram.StatusEnum.OPEN){
			this.auditPass(cloudCoachPaymentProgram);
		}
	}

	private CloudCoachPaymentProgram.StatusEnum getStatus(CloudCoachPaymentProgram cloudCoachPaymentProgram){
		//价格是否变动
		//获取现价
		BigDecimal groupPurchaseFee = memberFeeSettingService.getAmount(cloudCoachPaymentProgram.getOrganId(),
				cloudCoachPaymentProgram.getMemberRankSettingId(),
				cloudCoachPaymentProgram.getPeriod(),
				cloudCoachPaymentProgram.getMemberNum(),
				MemberFeeSettingServiceImpl::getGroupPurchaseFee);
		if(cloudCoachPaymentProgram.getActualAmount().compareTo(groupPurchaseFee) == 0){
			return CloudCoachPaymentProgram.StatusEnum.OPEN;
		}else {
			return CloudCoachPaymentProgram.StatusEnum.AUDITING;
		}
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void auditPass(CloudCoachPaymentProgram cloudCoachPaymentProgram){
		List<Integer> userIds = cloudCoachPaymentProgram.getUserIds();
		//是否0元购买
		Boolean isFree = cloudCoachPaymentProgram.getActualAmount().compareTo(BigDecimal.ZERO) == 0;
		//如果是0元订单，保存为待激活的云教练订单
		if(isFree){
			cloudCoachPaymentProgram.setPaymentUserNum(userIds.size());
			cloudCoachPaymentProgramDao.update(cloudCoachPaymentProgram);
			studentCloudCoachPaymentDetailsDao.updatePaymentStatus(cloudCoachPaymentProgram.getId());
			CloudTeacherOrder cloudTeacherOrder = cloudTeacherOrderService.getInitCloudTeacherOrder(cloudCoachPaymentProgram);
			cloudTeacherOrderService.batchInsert(cloudTeacherOrder,cloudCoachPaymentProgram.getUserIds(),cloudCoachPaymentProgram.getAutoActivationFlag());
		}else {
			//推送缴费消息
			//TenantInfo tenantInfo = tenantInfoDao.selectById(cloudCoachPaymentProgram.getTenantId());
			Map<Integer, String> phoneMaps = MapUtil.convertMybatisMap(teacherDao.queryPhoneByIds(StringUtils.join(userIds,",")));
			String baseApiUrl = sysConfigDao.findConfigValue(SysConfigService.BASE_API_URL);
			StringBuffer pushUrl = new StringBuffer(baseApiUrl).append("/#/studentMember?id=").append(cloudCoachPaymentProgram.getId());
			sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.STUDENT_SMS_CLOUD_PAYMENT,phoneMaps,
					null,0,"",null, HttpUtil.getSortUrl(pushUrl.toString()));

			StringBuffer notifyUrl = new StringBuffer("8?").append(baseApiUrl).append("/#/studentMember?id=").append(cloudCoachPaymentProgram.getId());
			Map<Integer, String> userIdMaps = new HashMap<>(userIds.size());
			userIds.forEach(e->userIdMaps.put(e,e.toString()));
			sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_PUSH_CLOUD_PAYMENT,userIdMaps,
					null,0,notifyUrl.toString(),"STUDENT");
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void modify(CloudCoachPaymentProgram cloudCoachPaymentProgram) {
		CloudCoachPaymentProgram paymentProgram = cloudCoachPaymentProgramDao.getLock(cloudCoachPaymentProgram.getId());
		if(paymentProgram.getStatus() != CloudCoachPaymentProgram.StatusEnum.REJECT){
			throw new BizException("当前状态缴费项目不可编辑");
		}
		cloudCoachPaymentProgram.setStatus(getStatus(cloudCoachPaymentProgram));
		//是否自动激活
		cloudCoachPaymentProgram.setAutoActivationFlag(tenantConfigService.autoActivationFlag(cloudCoachPaymentProgram.getTenantId()));
		cloudCoachPaymentProgramDao.update(cloudCoachPaymentProgram);
		if(cloudCoachPaymentProgram.getStatus() == CloudCoachPaymentProgram.StatusEnum.OPEN){
			List<Integer> userIds = studentCloudCoachPaymentDetailsDao.findUserByProgramId(cloudCoachPaymentProgram.getId());
			cloudCoachPaymentProgram.setUserIds(userIds);
			this.auditPass(cloudCoachPaymentProgram);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void audit(CloudCoachPaymentProgram cloudCoachPaymentProgram) {
		CloudCoachPaymentProgram paymentProgram = cloudCoachPaymentProgramDao.getLock(cloudCoachPaymentProgram.getId());
		if(paymentProgram.getStatus() != CloudCoachPaymentProgram.StatusEnum.AUDITING){
			throw new BizException("当前状态缴费项目不可审核");
		}
		CloudCoachPaymentProgram.StatusEnum status = cloudCoachPaymentProgram.getStatus();
		if(status == CloudCoachPaymentProgram.StatusEnum.AUDITING){
			throw new BizException("审核状态异常");
		}
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		paymentProgram.setStatus(status);
		paymentProgram.setMemo(cloudCoachPaymentProgram.getMemo());
		Date date = new Date();
		paymentProgram.setUpdateTime(date);
		paymentProgram.setAuditTime(date);
		paymentProgram.setAudit(sysUser.getId());
		cloudCoachPaymentProgramDao.update(paymentProgram);
		if(status == CloudCoachPaymentProgram.StatusEnum.OPEN){
			List<Integer> userIds = studentCloudCoachPaymentDetailsDao.findUserByProgramId(paymentProgram.getId());
			paymentProgram.setUserIds(userIds);
			this.auditPass(paymentProgram);
		}
	}
}