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

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

import com.ym.mec.auth.api.enums.CertificateTypeEnum;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.MusicGroupPaymentCalenderDao;
import com.ym.mec.biz.dal.dao.MusicGroupStudentFeeDao;
import com.ym.mec.biz.dal.dao.StudentDao;
import com.ym.mec.biz.dal.dao.StudentPaymentOrderDetailDao;
import com.ym.mec.biz.dal.dto.StudentInfo;
import com.ym.mec.biz.dal.entity.CooperationOrgan.OwnershipType;
import com.ym.mec.biz.dal.entity.Goods;
import com.ym.mec.biz.dal.entity.MusicGroup;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
import com.ym.mec.biz.dal.entity.MusicGroupStudentFee;
import com.ym.mec.biz.dal.entity.MusicGroupSubjectGoodsGroup;
import com.ym.mec.biz.dal.entity.MusicGroupSubjectPlan;
import com.ym.mec.biz.dal.entity.StudentPaymentOrder;
import com.ym.mec.biz.dal.entity.StudentPaymentOrderDetail;
import com.ym.mec.biz.dal.entity.StudentRegistration;
import com.ym.mec.biz.dal.entity.Subject;
import com.ym.mec.biz.dal.entity.SysUserContracts;
import com.ym.mec.biz.dal.entity.SysUserContracts.ContractType;
import com.ym.mec.biz.dal.entity.SysUserTsign;
import com.ym.mec.biz.dal.entity.VipGroup;
import com.ym.mec.biz.dal.enums.DealStatusEnum;
import com.ym.mec.biz.dal.enums.KitGroupPurchaseTypeEnum;
import com.ym.mec.biz.dal.enums.OrderDetailTypeEnum;
import com.ym.mec.biz.service.ContractService;
import com.ym.mec.biz.service.GoodsService;
import com.ym.mec.biz.service.MusicGroupService;
import com.ym.mec.biz.service.MusicGroupSubjectGoodsGroupService;
import com.ym.mec.biz.service.MusicGroupSubjectPlanService;
import com.ym.mec.biz.service.StudentPaymentOrderService;
import com.ym.mec.biz.service.StudentRegistrationService;
import com.ym.mec.biz.service.SubjectService;
import com.ym.mec.biz.service.SysUserContractsService;
import com.ym.mec.biz.service.SysUserTsignService;
import com.ym.mec.biz.service.VipGroupService;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.thirdparty.eseal.ESealPlugin;
import com.ym.mec.thirdparty.storage.StoragePluginContext;
import com.ym.mec.thirdparty.storage.provider.KS3StoragePlugin;
import com.ym.mec.thirdparty.user.realname.RealnameAuthenticationPluginContext;
import com.ym.mec.thirdparty.user.realname.provider.LinkfaceRealnameAuthenticationPlugin;
import com.ym.mec.util.date.DateUtil;
import com.ym.mec.util.freemarker.FreemarkerTemplateEngine;
import com.ym.mec.util.money.MoneyUtil;
import com.ym.mec.util.pdf.PDFUtil;

@Service
public class ContractServiceImpl implements ContractService, InitializingBean {

	@Autowired
	private SysUserTsignService sysUserTsignService;

	@Autowired
	private SysUserFeignService sysUserFeignService;

	@Autowired
	private SysUserContractsService sysUserContractsService;

	@Autowired
	private StudentRegistrationService studentRegistrationService;

	@Autowired
	private StudentPaymentOrderService studentPaymentOrderService;

	@Autowired
	private MusicGroupSubjectPlanService musicGroupSubjectPlanService;

	@Autowired
	private MusicGroupSubjectGoodsGroupService musicGroupSubjectGoodsGroupService;

	@Autowired
	private MusicGroupPaymentCalenderDao musicGroupPaymentCalenderDao;

	@Autowired
	private MusicGroupStudentFeeDao musicGroupStudentFeeDao;

	@Autowired
	private StudentPaymentOrderDetailDao studentPaymentOrderDetailDao;

	@Autowired
	@Lazy
	private VipGroupService vipGroupService;

	@Autowired
	private SubjectService subjectService;

	@Autowired
	private ESealPlugin eSealPlugin;

	@Autowired
	private StoragePluginContext storagePluginContext;

	@Autowired
	private GoodsService goodsService;

	@Autowired
	private MusicGroupService musicGroupService;

	@Autowired
	private StudentDao studentDao;

	@Value("${contract.baseDir:/var/pdf}")
	private String contractBaseDir;

	@Value("${message.debugMode}")
	private boolean debugMode;

	@Autowired
	private RealnameAuthenticationPluginContext realnameAuthenticationPluginContext;

	private DateFormat dateFormatOss = new SimpleDateFormat("yyyy/MM/dd");

	private DateFormat dateFormat1 = new SimpleDateFormat("yyMMddHHmmSS");

	private final Logger logger = LoggerFactory.getLogger(ContractService.class);

	@Override
	public void afterPropertiesSet() throws Exception {
		// 注册企业账户
		Map<String, String> organList = new HashMap<String, String>();
		organList.put("91420106333619290A", "武汉长乐长风乐器销售有限公司");
		organList.put("91440300326364429H", "深圳大雅乐盟网络教育股份有限公司");

		for (Entry<String, String> organ : organList.entrySet()) {

			String organCode = organ.getKey();
			String orgName = organ.getValue();

			SysUserTsign sysUserTsign = sysUserTsignService.queryByCardNo(organCode);

			if (sysUserTsign == null) {

				String accountId = eSealPlugin.createOrganAccount(orgName, organCode);

				if (StringUtils.isBlank(accountId)) {
					throw new BizException("创建企业电子存证账户失败");
				}

				String sealData = eSealPlugin.createOrganSeal(accountId, "", "");

				if (StringUtils.isBlank(sealData)) {
					throw new BizException("创建电子存证印章失败");
				}

				sysUserTsign = new SysUserTsign(-1, accountId, sealData, orgName, organCode);

				sysUserTsignService.insert(sysUserTsign);

			}
		}
	}

	@Override
	public SysUserTsign register(Integer userId, String realName, String idCardNo, String mobileNo) {

		if (StringUtils.isBlank(realName) || StringUtils.isBlank(idCardNo) || StringUtils.isBlank(mobileNo)) {
			return null;
		}

		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
		if (sysUserTsign == null) {

			if(!debugMode){
				realnameAuthenticationPluginContext.getRealnameAuthenticationPlugin(LinkfaceRealnameAuthenticationPlugin.getName()).verify(realName, idCardNo);
			}

			String accountId = eSealPlugin.createUserAccount(realName, idCardNo, mobileNo);

			if (StringUtils.isBlank(accountId)) {
				throw new BizException("创建电子存证账户失败");
			}

			String sealData = eSealPlugin.createUserSeal(accountId);

			if (StringUtils.isBlank(sealData)) {
				throw new BizException("创建电子存证印章失败");
			}

			sysUserTsign = new SysUserTsign(userId, accountId, sealData, realName, idCardNo);

			sysUserTsignService.insert(sysUserTsign);

			return sysUserTsign;
		}

		return null;
	}

	@Override
	public boolean transferRegisterContract(Integer userId) {

		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);

		if (sysUserTsign == null) {
			SysUser user = sysUserFeignService.queryUserById(userId);
			if (user == null) {
				throw new BizException("用户信息查询失败");
			}
			if(CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType()))
				sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
		}

		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/register/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();

		templateEngine.render(params, "register.ftl", srcFile);

		// 生成借款协议PDF
		try {
			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
		} catch (IOException e) {
			throw new BizException("生成pdf协议失败", e);
		}

		if (sysUserTsign != null) {
			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
		}

		Date date = new Date();
		// 上传到oss
		String dateStrOss = dateFormatOss.format(date);
		dateStrOss = "users/" + dateStrOss + "/" + DateUtil.getHour(date);
		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);

		SysUserContracts sysUserContracts = new SysUserContracts();
		sysUserContracts.setCreateTime(date);
		sysUserContracts.setType(ContractType.REGISTER);
		sysUserContracts.setUrl(pdfFilePath);
		sysUserContracts.setUserId(userId);

		sysUserContractsService.insert(sysUserContracts);

		FileUtils.deleteQuietly(srcFile);

		return true;
	}

	@Override
	public String queryRegisterContract(Integer userId) {

		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/register/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();

		templateEngine.render(params, "register.ftl", srcFile);

		String result = "";
		try {
			result = FileUtils.readFileToString(srcFile);
		} catch (IOException e) {
			throw new BizException("读取注册协议出错", e);
		} finally {
			FileUtils.deleteQuietly(srcFile);
		}

		return result;
	}

	@Override
	public boolean transferMusicGroupCoursesContract(Integer userId, String musicGroupId) {
		if(true){
			return transferProduceContract(userId, musicGroupId);
		}

		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);

		if (sysUserTsign == null) {
			SysUser user = sysUserFeignService.queryUserById(userId);
			if (user == null) {
				throw new BizException("用户信息查询失败");
			}
			if(CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType()))
				sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
		}
		Date date = new Date();

		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/courses/" + dateFormat1.format(date) + "/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();

		// 查询参数信息
		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
		params.put("studentInfo", studentInfo);

		// 课程类型
		params.put("classesType", "乐团团课");

		// 课程费用
		StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
		if (studentRegistration == null) {
			throw new BizException("用户 报名信息不存在");
		}
		MusicGroupStudentFee musicGroupStudentFee = musicGroupStudentFeeDao.findByUser(userId, musicGroupId);
		if (musicGroupStudentFee == null) {
			MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId,
					studentRegistration.getActualSubjectId());
			if (musicGroupSubjectPlan == null) {
				throw new BizException("声部课程费用设置找不到");
			}
			params.put("courseFee", musicGroupSubjectPlan.getFee().doubleValue());
		} else {
			params.put("courseFee", musicGroupStudentFee.getTemporaryCourseFee().doubleValue() > 0 ? musicGroupStudentFee.getTemporaryCourseFee().doubleValue()
					: musicGroupStudentFee.getCourseFee().doubleValue());
		}

		// 收费形式
		List<MusicGroupPaymentCalender> calenders = musicGroupPaymentCalenderDao.findByMusicGroupId(musicGroupId);

		/*if (calenders == null || calenders.size() == 0) {
			
		} else {
			params.put("paymentcalender", calenders.stream().map(cal -> cal.getPaymentMonth().toString()).collect(Collectors.joining("月,")) + "月");
		}*/
		params.put("paymentcalender", "一次性");

		params.put("isShowVisualSeal", false);

		MusicGroup musicGroup = musicGroupService.get(musicGroupId);
		if (musicGroup == null) {
			throw new BizException("乐团信息没找到");
		}

		params.put("ownershipType", musicGroup.getOwnershipType().name());

		templateEngine.render(params, "courses.ftl", srcFile);

		// 生成借款协议PDF
		try {
			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
		} catch (IOException e) {
			throw new BizException("生成pdf协议失败", e);
		}
		String organCode = "";
		if (musicGroup.getOwnershipType() == OwnershipType.OWN) {
			organCode = "91440300326364429H";
		} else {
			organCode = "91420106333619290A";
		}
		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
		if (organTsign == null) {
			throw new BizException("甲方未创建签章");
		}

		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
		if (sysUserTsign != null) {
			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
		}

		// 上传到oss
		String dateStrOss = dateFormatOss.format(date);
		dateStrOss = "musicCourses/" + dateStrOss + "/" + DateUtil.getHour(date);
		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);

		SysUserContracts sysUserContracts = new SysUserContracts();
		sysUserContracts.setCreateTime(date);
		sysUserContracts.setType(ContractType.COURSES);
		sysUserContracts.setUrl(pdfFilePath);
		sysUserContracts.setUserId(userId);

		sysUserContractsService.insert(sysUserContracts);

		FileUtils.deleteQuietly(srcFile);

		return true;
	}

	@Override
	public String queryMusicGroupCoursesContract(Integer userId, String musicGroupId) {

		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/courses/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();

		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
		params.put("studentInfo", studentInfo);

		// 课程类型
		params.put("classesType", "乐团团课");

		// 课程费用
		StudentRegistration studentRegistration = studentRegistrationService.queryByUserIdAndMusicGroupId(userId, musicGroupId);
		if (studentRegistration == null) {
			throw new BizException("用户报名信息不存在");
		}
		MusicGroupStudentFee musicGroupStudentFee = musicGroupStudentFeeDao.findByUser(userId, musicGroupId);
		if (musicGroupStudentFee == null) {
			MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId,
					studentRegistration.getActualSubjectId());
			if (musicGroupSubjectPlan == null) {
				throw new BizException("声部课程费用设置找不到");
			}
			params.put("courseFee", musicGroupSubjectPlan.getFee().doubleValue());
		} else {
			params.put(
					"courseFee",
					(musicGroupStudentFee.getTemporaryCourseFee() != null && musicGroupStudentFee.getTemporaryCourseFee().doubleValue() > 0) ? musicGroupStudentFee
							.getTemporaryCourseFee().doubleValue() : musicGroupStudentFee.getCourseFee().doubleValue());
		}

		// 收费形式
		List<MusicGroupPaymentCalender> calenders = musicGroupPaymentCalenderDao.findByMusicGroupId(musicGroupId);

		/*if (calenders == null || calenders.size() == 0) {
			params.put("paymentcalender", "一次性");
		} else {
			params.put("paymentcalender", calenders.stream().map(cal -> cal.getPaymentMonth().toString()).collect(Collectors.joining("月,")) + "月");
		}*/
		
		params.put("paymentcalender", "一次性");

		params.put("isShowVisualSeal", true);

		MusicGroup musicGroup = musicGroupService.get(musicGroupId);
		if (musicGroup == null) {
			throw new BizException("乐团信息没找到");
		}

		params.put("ownershipType", musicGroup.getOwnershipType().name());

		templateEngine.render(params, "courses.ftl", srcFile);

		String result = "";
		try {
			result = FileUtils.readFileToString(srcFile);
		} catch (IOException e) {
			throw new BizException("读取课程协议出错", e);
		} finally {
			FileUtils.deleteQuietly(srcFile);
		}

		return result;
	}

	@Override
	public boolean transferVipGroupCoursesContract(Integer userId, Long vipGroupId) {
		if(true){
			return transferProduceContract(userId, null);
		}

		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);

		if (sysUserTsign == null) {
			SysUser user = sysUserFeignService.queryUserById(userId);
			if (user == null) {
				throw new BizException("用户信息查询失败");
			}
			if(CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType()))
				sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
		}
		Date date = new Date();

		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/vipCourses/" + dateFormat1.format(date) + "/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();

		// 查询参数信息
		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
		params.put("studentInfo", studentInfo);

		// 课程类型
		params.put("classesType", "VIP课");

		// 课程费用
		VipGroup vipGroup = vipGroupService.get(vipGroupId);
		if (vipGroup == null) {
			throw new BizException("VIP课找不到");
		}
		params.put("courseFee", vipGroup.getTotalPrice().doubleValue());

		// 收费形式
		params.put("paymentcalender", "一次性");

		params.put("isShowVisualSeal", false);

		params.put("ownershipType", "OWN");

		templateEngine.render(params, "courses.ftl", srcFile);

		// 生成借款协议PDF
		try {
			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
		} catch (IOException e) {
			throw new BizException("生成pdf协议失败", e);
		}
		String organCode = "91440300326364429H";
		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
		if (organTsign == null) {
			throw new BizException("甲方未创建签章");
		}

		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);

		if (sysUserTsign != null) {
			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
		}

		// 上传到oss
		String dateStrOss = dateFormatOss.format(date);
		dateStrOss = "vipCourses/" + dateStrOss + "/" + DateUtil.getHour(date);
		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);

		SysUserContracts sysUserContracts = new SysUserContracts();
		sysUserContracts.setCreateTime(date);
		sysUserContracts.setType(ContractType.VIP_COURSES);
		sysUserContracts.setUrl(pdfFilePath);
		sysUserContracts.setUserId(userId);

		sysUserContractsService.insert(sysUserContracts);

		FileUtils.deleteQuietly(srcFile);

		return true;
	}

	@Override
	public String queryVipGroupCoursesContract(Integer userId, Long vipGroupId) {

		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/courses/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();

		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
		params.put("studentInfo", studentInfo);

		// 课程类型
		params.put("classesType", "VIP课");

		// 课程费用
		VipGroup vipGroup = vipGroupService.get(vipGroupId);
		if (vipGroup == null) {
			throw new BizException("VIP课找不到");
		}
		params.put("courseFee", vipGroup.getTotalPrice().doubleValue());

		// 收费形式
		params.put("paymentcalender", "一次性");

		params.put("isShowVisualSeal", true);

		params.put("ownershipType", "OWN");

		templateEngine.render(params, "courses.ftl", srcFile);

		String result = "";
		try {
			result = FileUtils.readFileToString(srcFile);
		} catch (IOException e) {
			throw new BizException("读取课程协议出错", e);
		} finally {
			FileUtils.deleteQuietly(srcFile);
		}

		return result;
	}

	@Override
	public boolean transferGoodsContract(Integer userId, String musicGroupId, String goodsIds, KitGroupPurchaseTypeEnum kitGroupPurchaseTypeEnum) {
		if(true){
			return transferProduceContract(userId, musicGroupId);
		}

		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);

		if (sysUserTsign == null) {
			SysUser user = sysUserFeignService.queryUserById(userId);
			if (user == null) {
				throw new BizException("用户信息查询失败");
			}
			if(CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType()))
				sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
		}
		Date date = new Date();

		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/goods/" + dateFormat1.format(date) + "/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();

		// 查询参数信息
		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);

		int subjectId = studentInfo.getSubject().getId();

		Subject subject = subjectService.get(subjectId);
		studentInfo.setSubject(subject);

		params.put("studentInfo", studentInfo);

		List<Goods> goodsList = goodsService.findGoodsByIds(goodsIds);
		params.put("goodsList", goodsList);

		double depositFee = 0d;
		if (kitGroupPurchaseTypeEnum == KitGroupPurchaseTypeEnum.LEASE) {
			StudentPaymentOrder studentPaymentOrder = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, musicGroupId, DealStatusEnum.SUCCESS);

			if (studentPaymentOrder == null) {
				MusicGroupSubjectGoodsGroup musicGroupSubjectPlan = musicGroupSubjectGoodsGroupService.query(musicGroupId, subjectId, goodsIds);
				if (musicGroupSubjectPlan != null) {
					depositFee = musicGroupSubjectPlan.getDepositFee().doubleValue();
				}
			} else {

				List<StudentPaymentOrderDetail> orderDetailList = studentPaymentOrderDetailDao.findApplyOrderGoods(studentPaymentOrder.getId());
				for (StudentPaymentOrderDetail detail : orderDetailList) {
					if (detail.getType() == OrderDetailTypeEnum.MUSICAL) {
						depositFee = detail.getPrice().doubleValue();
					}
				}
			}
		}
		params.put("depositFee", depositFee);
		params.put("depositFeeFmt", MoneyUtil.toChinese(depositFee + ""));

		params.put("isShowVisualSeal", false);

		MusicGroup musicGroup = musicGroupService.get(musicGroupId);
		if (musicGroup == null) {
			throw new BizException("乐团信息没找到");
		}

		params.put("ownershipType", musicGroup.getOwnershipType().name());

		templateEngine.render(params, "goods.ftl", srcFile);

		// 生成借款协议PDF
		try {
			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
		} catch (IOException e) {
			throw new BizException("生成pdf协议失败", e);
		}
		String organCode = "";
		if (musicGroup.getOwnershipType() == OwnershipType.OWN) {
			organCode = "91440300326364429H";
		} else {
			organCode = "91420106333619290A";
		}
		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
		if (organTsign == null) {
			throw new BizException("甲方未创建签章");
		}

		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);

		if (sysUserTsign != null) {
			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
		}

		// 上传到oss
		String dateStrOss = dateFormatOss.format(date);
		dateStrOss = "goods/" + dateStrOss + "/" + DateUtil.getHour(date);
		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);

		SysUserContracts sysUserContracts = new SysUserContracts();
		sysUserContracts.setCreateTime(date);
		sysUserContracts.setType(ContractType.INSTRUMENT);
		sysUserContracts.setUrl(pdfFilePath);
		sysUserContracts.setUserId(userId);

		sysUserContractsService.insert(sysUserContracts);

		FileUtils.deleteQuietly(srcFile);

		return true;
	}

	@Override
	public String queryGoodsContract(Integer userId, String musicGroupId, String goodsIds, KitGroupPurchaseTypeEnum kitGroupPurchaseTypeEnum) {

		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/goods/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();

		// 查询参数信息
		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);

		int subjectId = studentInfo.getSubject().getId();

		Subject subject = subjectService.get(subjectId);
		studentInfo.setSubject(subject);

		params.put("studentInfo", studentInfo);

		List<Goods> goodsList = goodsService.findGoodsByIds(goodsIds);
		params.put("goodsList", goodsList);

		double depositFee = 0d;
		if (kitGroupPurchaseTypeEnum == KitGroupPurchaseTypeEnum.LEASE) {
			StudentPaymentOrder studentPaymentOrder = studentPaymentOrderService
					.findMusicGroupApplyOrderByStatus(userId, musicGroupId, DealStatusEnum.WAIT_PAY);

			if (studentPaymentOrder == null) {
				MusicGroupSubjectGoodsGroup musicGroupSubjectPlan = musicGroupSubjectGoodsGroupService.query(musicGroupId, subjectId, goodsIds);
				if (musicGroupSubjectPlan != null) {
					depositFee = musicGroupSubjectPlan.getDepositFee().doubleValue();
				}
			} else {

				List<StudentPaymentOrderDetail> orderDetailList = studentPaymentOrderDetailDao.findApplyOrderGoods(studentPaymentOrder.getId());
				for (StudentPaymentOrderDetail detail : orderDetailList) {
					if (detail.getType() == OrderDetailTypeEnum.MUSICAL) {
						depositFee = detail.getPrice().doubleValue();
					}
				}
			}
		}
		params.put("depositFee", depositFee);
		params.put("depositFeeFmt", MoneyUtil.toChinese(depositFee + ""));

		params.put("isShowVisualSeal", true);

		MusicGroup musicGroup = musicGroupService.get(musicGroupId);
		if (musicGroup == null) {
			throw new BizException("乐团信息没找到");
		}

		params.put("ownershipType", musicGroup.getOwnershipType().name());

		templateEngine.render(params, "goods.ftl", srcFile);

		String result = "";
		try {
			result = FileUtils.readFileToString(srcFile);
		} catch (IOException e) {
			throw new BizException("读取商品协议出错", e);
		} finally {
			FileUtils.deleteQuietly(srcFile);
		}

		return result;
	}

	@Override
	public String queryPracticeCoursesContract(Integer userId, int courseSectionNum, Date startDate, Date endDate, BigDecimal fee) {
		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/practice/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("courseSectionNum", courseSectionNum);
		params.put("startDate", startDate);
		params.put("endDate", endDate);
		params.put("fee", fee);

		params.put("isShowVisualSeal", false);

		params.put("ownershipType", "OWN");

		templateEngine.render(params, "practice.ftl", srcFile);

		String result = "";
		try {
			result = FileUtils.readFileToString(srcFile);
		} catch (IOException e) {
			throw new BizException("读取网管课购买协议出错", e);
		} finally {
			FileUtils.deleteQuietly(srcFile);
		}

		return result;
	}

	@Override
	public boolean transferPracticeCoursesContract(Integer userId, int courseSectionNum, Date startDate, Date endDate, BigDecimal fee) {
		if(true){
			return transferProduceContract(userId, null);
		}

		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);

		if (sysUserTsign == null) {
			SysUser user = sysUserFeignService.queryUserById(userId);
			if (user == null) {
				throw new BizException("用户信息查询失败");
			}
			if(CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType()))
				sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
		}

		Date date = new Date();

		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/practice/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("courseSectionNum", courseSectionNum);
		params.put("startDate", startDate);
		params.put("endDate", endDate);
		params.put("fee", fee);

		params.put("isShowVisualSeal", false);

		params.put("ownershipType", "OWN");

		templateEngine.render(params, "practice.ftl", srcFile);

		// 生成借款协议PDF
		try {
			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
		} catch (IOException e) {
			throw new BizException("生成pdf协议失败", e);
		}
		String organCode = "91440300326364429H";
		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
		if (organTsign == null) {
			throw new BizException("甲方未创建签章");
		}

		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);

		if (sysUserTsign != null) {
			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
		}

		// 上传到oss
		String dateStrOss = dateFormatOss.format(date);
		dateStrOss = "practice/" + dateStrOss + "/" + DateUtil.getHour(date);
		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);

		SysUserContracts sysUserContracts = new SysUserContracts();
		sysUserContracts.setCreateTime(date);
		sysUserContracts.setType(ContractType.PRACTICE);
		sysUserContracts.setUrl(pdfFilePath);
		sysUserContracts.setUserId(userId);

		sysUserContractsService.insert(sysUserContracts);

		FileUtils.deleteQuietly(srcFile);

		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
	public boolean transferProduceContract(Integer userId,String musicGroupId) {
		SysUser user = studentDao.lockUserReturnInfo(userId);

		if (user == null) {
			logger.error("用户不存在({})", userId);
			return false;
		}

		List<SysUserContracts> userContracts = sysUserContractsService.getUserContractWithType(userId, ContractType.PRODUCT);
		if(!CollectionUtils.isEmpty(userContracts)){
			return true;
		}

		if(StringUtils.isBlank(user.getRealName())||StringUtils.isBlank(user.getIdCardNo())){
			logger.error("身份信息缺失({})", userId);
			return false;
		}

		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);
		if (sysUserTsign == null && CertificateTypeEnum.IDENTITY.getCode().equals(user.getCertificateType())) {
			try {
				sysUserTsign = register(userId, user.getRealName(), user.getIdCardNo(), user.getPhone());
			} catch (Exception e) {
				logger.error("用户电子签章注册失败", e);
				return false;
			}
		}
		Date date = new Date();

		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/product/" + dateFormat1.format(date) + "/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();

		// 查询参数信息
		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
		params.put("studentInfo", studentInfo);

		params.put("isShowVisualSeal", false);

		if(StringUtils.isBlank(musicGroupId)){
			params.put("ownershipType", "OWN");
		}else{
			MusicGroup musicGroup = musicGroupService.get(musicGroupId);
			if (musicGroup == null) {
				logger.error("乐团信息没找到({})", musicGroupId);
				return false;
			}
			params.put("ownershipType", musicGroup.getOwnershipType().name());
		}

		templateEngine.render(params, "product.ftl", srcFile);

		// 生成借款协议PDF
		try {
			PDFUtil.renderToPDFByData(ContractServiceImpl.class.getResource("/").getFile(), FileUtils.readFileToString(srcFile), srcPdfPath, "simsun.ttc");
		} catch (IOException e) {
			logger.error("生成产品协议失败", e);
			return false;
		}


		String organCode = "";
		if (OwnershipType.OWN.name().equals(params.get("ownershipType"))){
			organCode = "91440300326364429H";
		} else {
			organCode = "91420106333619290A";
		}
		SysUserTsign organTsign = sysUserTsignService.queryByCardNo(organCode);
		if (organTsign == null) {
			logger.error("甲方未创建签章");
			return false;
		}

		eSealPlugin.organSign(organTsign.getSealData(), srcPdfPath, srcPdfPath);
		if (sysUserTsign != null) {
			eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);
		}

		// 上传到oss
		String dateStrOss = dateFormatOss.format(date);
		dateStrOss = "product/" + dateStrOss + "/" + DateUtil.getHour(date);
		String pdfFilePath = storagePluginContext.uploadFile(KS3StoragePlugin.PLUGIN_NAME, dateStrOss, srcFile);

		SysUserContracts sysUserContracts = new SysUserContracts();
		sysUserContracts.setCreateTime(date);
		sysUserContracts.setType(ContractType.PRODUCT);
		sysUserContracts.setUrl(pdfFilePath);
		sysUserContracts.setUserId(userId);

		sysUserContractsService.insert(sysUserContracts);

		FileUtils.deleteQuietly(srcFile);
		return true;
	}

	@Override
	@Transactional(isolation = Isolation.READ_COMMITTED)
	public Map<String, Object> queryProductContract(Integer userId,String musicGroupId) {
		// 合成freemarker
		String srcPdfPath = contractBaseDir + "/product/" + userId + ".pdf";

		File srcFile = new File(srcPdfPath);

		File debtFile = new File(srcFile.getParent());
		if (!debtFile.exists()) {
			debtFile.mkdirs();
		}

		FreemarkerTemplateEngine templateEngine = FreemarkerTemplateEngine.getInstance();
		templateEngine.setClassForTemplateLoading(ContractServiceImpl.class, "/config/contracts/");

		Map<String, Object> params = new HashMap<String, Object>();

		StudentInfo studentInfo = studentRegistrationService.queryStudentInfo(userId);
		if(Objects.isNull(studentInfo)){
			studentInfo = new StudentInfo();
		}
		if(StringUtils.isEmpty(studentInfo.getCertificateType())){
			studentInfo.setCertificateType(CertificateTypeEnum.IDENTITY.getCode());
		}
		params.put("studentInfo", studentInfo);
		params.put("isShowVisualSeal", true);

		if(StringUtils.isBlank(musicGroupId)){
			params.put("ownershipType", "OWN");
		}else{
			MusicGroup musicGroup = musicGroupService.get(musicGroupId);
			if (musicGroup == null) {
				throw new BizException("乐团信息没找到");
			}
			params.put("ownershipType", musicGroup.getOwnershipType().name());
		}

		templateEngine.render(params, "product.ftl", srcFile);

		String html = "";
		try {
			html = FileUtils.readFileToString(srcFile);
		} catch (IOException e) {
			throw new BizException("读取产品协议出错", e);
		} finally {
			FileUtils.deleteQuietly(srcFile);
		}

		List<SysUserContracts> userContractWithType = sysUserContractsService.getUserContractWithType(userId, ContractType.PRODUCT);

		Map<String, Object> result = new HashMap<>();
		result.put("exists", !CollectionUtils.isEmpty(userContractWithType));
		result.put("productContract", html);
		return result;
	}

}
