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

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

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.dto.StudentInfo;
import com.ym.mec.biz.dal.entity.Goods;
import com.ym.mec.biz.dal.entity.MusicGroupPaymentCalender;
import com.ym.mec.biz.dal.entity.MusicGroupSubjectPlan;
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.OrderDetailTypeEnum;
import com.ym.mec.biz.service.ContractService;
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.StoragePlugin;
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 {

	@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 MusicGroupPaymentCalenderDao musicGroupPaymentCalenderDao;

	@Autowired
	private VipGroupService vipGroupService;

	@Autowired
	private SubjectService subjectService;

	@Autowired
	private ESealPlugin eSealPlugin;

	@Autowired
	private StoragePlugin storagePlugin;

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

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

	@Override
	public boolean register(Integer userId) {

		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);

		if (sysUserTsign == null) {

			SysUser user = sysUserFeignService.queryUserById(userId);
			if (user == null) {
				return false;
			}
			String accountId = eSealPlugin.createUserAccount(user.getRealName(), user.getIdCardNo(), user.getPhone());

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

			String sealData = eSealPlugin.createSeal(accountId);

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

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

			sysUserTsignService.insert(sysUserTsign);
		}

		return true;
	}

	@Override
	public boolean transferRegisterContract(Integer userId) {

		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);

		if (sysUserTsign == null) {
			return false;
		}

		// 合成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,
					"config/fonts/simsun.ttc");
		} catch (IOException e) {
			throw new BizException("生成pdf协议失败", e);
		}

		eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);

		Date date = new Date();
		// 上传到oss
		String dateStrOss = dateFormatOss.format(date);
		String pdfFilePath = storagePlugin.uploadFile(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);
		}
		FileUtils.deleteQuietly(srcFile);

		return result;
	}

	@Override
	public boolean transferMusicGroupCoursesContract(Integer userId, String musicGroupId) {
		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);

		if (sysUserTsign == null) {
			return false;
		}

		// 合成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("用户 报名信息不存在");
		}
		MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId,
				studentRegistration.getActualSubjectId());
		if (musicGroupSubjectPlan == null) {
			throw new BizException("声部课程费用设置找不到");
		}
		params.put("courseFee", musicGroupSubjectPlan.getFee().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(",")));
		}

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

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

		eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);

		Date date = new Date();
		// 上传到oss
		String dateStrOss = dateFormatOss.format(date);
		String pdfFilePath = storagePlugin.uploadFile(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 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("用户 报名信息不存在");
		}
		MusicGroupSubjectPlan musicGroupSubjectPlan = musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId,
				studentRegistration.getActualSubjectId());
		if (musicGroupSubjectPlan == null) {
			throw new BizException("声部课程费用设置找不到");
		}
		params.put("courseFee", musicGroupSubjectPlan.getFee().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(",")));
		}

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

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

		return result;
	}

	@Override
	public boolean transferVipGroupCoursesContract(Integer userId, Long vipGroupId) {
		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);

		if (sysUserTsign == null) {
			return false;
		}

		// 合成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", "一次性");

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

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

		eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);

		Date date = new Date();
		// 上传到oss
		String dateStrOss = dateFormatOss.format(date);
		String pdfFilePath = storagePlugin.uploadFile(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 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", "一次性");

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

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

		return result;
	}

	@Override
	public boolean transferGoodsContract(Integer userId, String musicGroupId) {
		SysUserTsign sysUserTsign = sysUserTsignService.get(userId);

		if (sysUserTsign == null) {
			return false;
		}

		// 合成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 = studentPaymentOrderService.queryApplyGoodsList(musicGroupId, OrderDetailTypeEnum.MUSICAL);
		params.put("goodsList", goodsList);
		
		MusicGroupSubjectPlan musicGroupSubjectPlan =musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId, subjectId);
		if (musicGroupSubjectPlan == null) {
			throw new BizException("声部课程费用设置找不到");
		}
		params.put("depositFee", musicGroupSubjectPlan.getDepositFee().doubleValue());
		params.put("depositFeeFmt", MoneyUtil.toChinese(musicGroupSubjectPlan.getDepositFee().toString()));

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

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

		eSealPlugin.userSign(sysUserTsign.getAccountId(), sysUserTsign.getSealData(), srcPdfPath, srcPdfPath);

		Date date = new Date();
		// 上传到oss
		String dateStrOss = dateFormatOss.format(date);
		String pdfFilePath = storagePlugin.uploadFile(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 queryGoodsContract(Integer userId, String musicGroupId) {

		// 合成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 = studentPaymentOrderService.queryApplyGoodsList(musicGroupId, OrderDetailTypeEnum.MUSICAL);
		params.put("goodsList", goodsList);
		
		MusicGroupSubjectPlan musicGroupSubjectPlan =musicGroupSubjectPlanService.getMusicOneSubjectClassPlan(musicGroupId, subjectId);
		if (musicGroupSubjectPlan == null) {
			throw new BizException("声部课程费用设置找不到");
		}
		params.put("depositFee", musicGroupSubjectPlan.getDepositFee().doubleValue());
		params.put("depositFeeFmt", MoneyUtil.toChinese(musicGroupSubjectPlan.getDepositFee().toString()));

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

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

		return result;
	}

}
