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

import com.thoughtworks.xstream.XStream;
import com.ym.mec.collectfee.common.dao.BaseDAO;
import com.ym.mec.collectfee.common.page.PageInfo;
import com.ym.mec.collectfee.common.service.impl.BaseServiceImpl;
import com.ym.mec.collectfee.dao.*;
import com.ym.mec.collectfee.entity.*;
import com.ym.mec.collectfee.service.ApplyInfoService;
import com.ym.mec.collectfee.utils.CDesECB;
import com.ym.mec.collectfee.utils.HttpUtil;
import com.ym.mec.collectfee.utils.MapUtil;
import com.ym.mec.collectfee.utils.XStreamUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.StringWriter;
import java.io.Writer;
import java.util.*;

@Service
@Slf4j
public class ApplyInfoServiceImpl extends BaseServiceImpl<Integer, ApplyInfo> implements ApplyInfoService {
	
	@Autowired
	private ApplyInfoDao applyInfoDao;
	@Autowired
	private MecUserDao mecUserDao;
	@Autowired
	private OrderDao orderDao;
	@Autowired
	private CourseGroupInfoDao courseGroupInfoDao;
	@Autowired
	private BranchDao branchDao;
	@Autowired
	private SeminaryDao seminaryDao;

	@Value("${common.properties.mec-publicKey}")
	private String publicKey;

	@Value("${common.properties.mec-url}")
	private String url;

	@Value("${common.properties.key}")
	private String key;

	@Override
	public BaseDAO<Integer, ApplyInfo> getDAO() {
		return applyInfoDao;
	}

	@Override
	public ApplyInfo findUserByPhone(String phone, Integer clazzId) {
		return applyInfoDao.findUserByPhone(phone,clazzId);
	}

	@Override
	public Boolean userRegister(String phone,Integer orderId) {
		try {
			ApplyInfo applyInfo = applyInfoDao.findUserByPhone(phone,null);
			if(applyInfo != null && applyInfo.getStatus() == 1 && applyInfo.getPushStatus() != 1){
				//组装请求
				applyInfo.setRealName(applyInfo.getName());
				String gClass = applyInfo.getgClass();
				applyInfo.setgClass(applyInfo.getGrade() + applyInfo.getgClass());
				applyInfo.setMobile(applyInfo.getPatriarchPhone());
				XStream xs = new XStream();
				xs.autodetectAnnotations(true);
				xs.ignoreUnknownElements();
				String body = xs.toXML(applyInfo);
				body = body.substring(body.indexOf("<user>")+6,body.indexOf("</user>"));
				//推送mec注册接口
				log.info("推送到用户数据到mec注册 body: " + body);
				body = getBody(body,121301);
				Date date = new Date();
				try {
					applyInfo.setUpdateTime(date);
					ResponseUserInfo userInfo = parseRegisterInfo(body);
					applyInfo.setUserId(userInfo.getUserId());
					applyInfo.setPushStatus(1);
					applyInfo.setGClass(gClass);
					RequestMecApplyClass applyClass = getApplyClass(applyInfo,orderId);
					body = xs.toXML(applyClass);
					body = body.substring(body.indexOf("<body>")+6,body.indexOf("</body>"));
					//推送mec用户缴费
					log.info("推送到用户数据到mec缴费 body: " + body);
					getBody(body,125218);
					applyInfoDao.update(applyInfo);
					return true;
				}catch (Exception e){
					e.printStackTrace();
					applyInfo.setPushStatus(2);
					applyInfoDao.update(applyInfo);
				}
				return false;
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public RequestMecApplyClass getApplyClass(ApplyInfo applyInfo,Integer orderId) {
//		Order order = orderDao.findOrderByStatus(applyInfo.getId(), null);
		Order order = orderDao.get(orderId);
		if(order != null){
			//封装请求参数
			RequestMecApplyClass applyClass = new RequestMecApplyClass();
			//<studentId>学员编号</studentId>
			applyClass.setStudentId(applyInfo.getUserId());
			//<classId>课程班（乐团）编号</classId>
			applyClass.setClassId(applyInfo.getClassId());
			//<subName>学员专业名称</subName>
			CourseGroupInfo groupInfo = courseGroupInfoDao.get(applyInfo.getCourseId());
			applyClass.setSubName(groupInfo.getSubName());
			//<remark>备注</remark>
			applyClass.setRemark(order.getRemark());
			List<Course> courses = new ArrayList<>();
			Course course = new Course();
			//<courseId>课程组编号</courseId>
			course.setCourseId(groupInfo.getId());
			courses.add(course);
			applyClass.setCourses(courses);
			//<amount>缴费总金额</amount>
			applyClass.setAmount(order.getAmount());
			//<tuiFee>学费金额</tuiFee>
			applyClass.setTuiFee(order.getTuiFee());
			//<goodsFee>乐器费用</goodsFee>
			applyClass.setGoodsFee(order.getGoodsFee());
			//<sdName>杂费名称</sdName>
			List<Sundry> sundries = new ArrayList<>();
			Sundry sundry = new Sundry();
			sundry.setSdFee(order.getSdFee());
			String sdName = order.getSdName();
			if(StringUtils.isEmpty(sdName)){
				sdName = order.getRemark();
			}
			//<sdFee>杂费金额</sdFee>
			sundry.setSdName(sdName);
			sundries.add(sundry);
			applyClass.setSundries(sundries);
			return applyClass;
		}
		return null;
	}

	@Override
	public List<Branch> getBranches() {
		try {
			List<Branch> branchList = branchDao.findAll(null);
			if(branchList == null || branchList.size() < 1){
				String body = "<province>0</province>";
				body = getBody(body,121002);
				body = "<body><branches>" + new String(Base64.getDecoder().decode(body)) + "</branches></body>";
				ResponseBranchesBean branches = XStreamUtil.xmlToObject("body", ResponseBranchesBean.class, body);
				branchDao.batchInsert(branches.getBranches());
				return branches.getBranches();
			}
			return branchList;
		}catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void saveSeminary() {
		try {
			List<Branch> branchList = branchDao.findAll(null);
			for (Branch branch:branchList) {
				Seminary seminary = seminaryDao.findByBranchId(branch.getBranchId());
				if(seminary != null){
					break;
				}
				String body = "<branchId>" + branch.getBranchId() + "</branchId>";
				body = getBody(body,121107);
				body = "<body><schools>" + new String(Base64.getDecoder().decode(body)) + "</schools></body>";
				ResponseSeminariesBean seminaries = XStreamUtil.xmlToObject("body", ResponseSeminariesBean.class, body);
				if(seminaries.getSchools() == null || seminaries.getSchools().size() < 1){
					break;
				}
				seminaryDao.batchInsert(seminaries.getSchools());
			}
		}catch (Exception e){
			e.printStackTrace();
		}
	}

	@Override
	public Map<String, Object> getUserRegisterViewDetail(Integer stuId) {
		Map<String, Object> vIewDetail = applyInfoDao.getUserRegisterVIewDetail(stuId);
		String subName = vIewDetail.get("sub_name_").toString();
		if(subName.contains("圆号") || subName.contains("上低音") ||subName.contains("长号") ||subName.contains("大号")){
			vIewDetail.put("isCopperPipe",true);
		}else {
			vIewDetail.put("isCopperPipe",false);
		}
		return vIewDetail;
	}

	@Override
	public PageInfo<ApplyInfoPage> queryUserPage(StudentsQueryInfo queryInfo) {
		PageInfo<ApplyInfoPage> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);

		List<ApplyInfoPage> dataList = null;
		int count = applyInfoDao.queryUserCount(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = applyInfoDao.queryUserPage(params);
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public List<MecCourse> queryUserCourse(Integer userId) {
		try {
			//获取学员信息
			findMecUser(userId);
			//获取学员课程班数据
			//1小课，2乐团
			String body = "<body><userId>" + userId + "</userId><classType>1</classType></body>";
			List<MecCourse> coursesMin = getCourses(body);
			body = "<body><userId>" + userId + "</userId><classType>2</classType></body>";
			List<MecCourse> coursesMax = getCourses(body);
			if(coursesMin != null && coursesMin.size() > 0){
				coursesMin.forEach( e -> {
					e.setClassType(1);
				} );
			}else {
				coursesMin = new ArrayList<>();
			}
			if(coursesMax != null && coursesMax.size() > 0){
				coursesMax.forEach( e -> {
					e.setClassType(2);
				} );
			}else {
				coursesMax = new ArrayList<>();
			}
			coursesMin.addAll(coursesMax);
			return coursesMin;
		}catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public MecUser findMecUser(Integer userId) {
		try {
			//获取学员信息
			MecUser mecUser = mecUserDao.get(userId);
			if(mecUser == null){
				String body = "<body><userId>" + userId + "</userId></body>";
				log.info("获取学员信息mec body: " + body);
				body = getBody(body, 121313);
				if(!StringUtils.isEmpty(body)){
					body = new String(Base64.getDecoder().decode(body));
					mecUser = XStreamUtil.xmlToObject("student", MecUser.class, body);
					//同步mec用户数据
					mecUserDao.insert(mecUser);
				}
			}
			return mecUser;
		}catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public boolean pushRenew(RenewBean renewBean) {
		try {
			XStream xs = new XStream();
			xs.autodetectAnnotations(true);
			String body = xs.toXML(renewBean);
			body = body.substring(body.indexOf("<body>")+6,body.indexOf("</body>"));
			log.info("推送续费数据到mec body: " + body);
			body = CDesECB.encode(key,body);
			RequestParamBean requestParamBean = new RequestParamBean();
			requestParamBean.setBody(body);
			requestParamBean.setHead(XStreamUtil.getOrdersHead(body,123255,publicKey,2,4));
			Writer writer = new StringWriter();
			writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
			xs = new XStream();
			xs.autodetectAnnotations(true);
			xs.toXML(requestParamBean,writer);
			body = HttpUtil.postXmlData(writer.toString(), url);
			log.info("mec响应的续费数据 body: " + body);
			body = body.substring(body.indexOf("<errCode>") + 9, body.indexOf("</errCode>"));
//			body = new String(CDesECB.decode(key,body.getBytes()));
//			body = CDesECB.decodeValue(key,body);
			if(!StringUtils.equals(body,"0")){
				return false;
			}
			return true;
		}catch (Exception e){
			e.printStackTrace();
		}
		return false;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateUserSub(String userId, Integer subId,Integer courseId) {
		String[] userIds = userId.split(",");
		for (String string:userIds) {
			applyInfoDao.updateUserSub(Integer.parseInt(string),subId,courseId,new Date());
		}
	}

	@Override
	public boolean mecUserIsExist(String phone) {
		try {
			String body = "<body><uType>1</uType><uName>" + phone +"</uName></body>";
			log.info("用户是否存在mec系统 body: " + body);
			body = getBody(body, 120431);
			body = new String(Base64.getDecoder().decode(body));
			if(StringUtils.isEmpty(body)){
				return false;
			}
			MecUserInfo mecUserInfo = XStreamUtil.xmlToObject("userInfo", MecUserInfo.class, body);
			if(mecUserInfo == null || StringUtils.isNotEmpty(mecUserInfo.getMobile())){
				return true;
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return false;
	}


	private List<MecCourse> getCourses(String body) throws Exception{
		body = getBody(body,123031);
		if(StringUtils.isEmpty(body)){
			return null;
		}
		body = "<body><courses>" + new String(Base64.getDecoder().decode(body)) + "</courses></body>";
		ParseMecCourse parseMecCourse = XStreamUtil.xmlToObject("body", ParseMecCourse.class, body);
		return parseMecCourse.getCourses();
	}

	private String getBody(String body,Integer cmd) throws Exception{
		body = Base64.getEncoder().encodeToString(body.getBytes());
		RequestParamBean requestParamBean = new RequestParamBean();
		requestParamBean.setBody(body);
		requestParamBean.setHead(XStreamUtil.getOrdersHead(body,cmd,publicKey,null,null));
		Writer writer = new StringWriter();
		writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
		XStream xs = new XStream();
		xs.autodetectAnnotations(true);
		xs.toXML(requestParamBean,writer);
		body = HttpUtil.postXmlData(writer.toString(), url);
		log.info("mec响应参数 body: " + body + " ,cmd: " + cmd);
		return body.substring(body.indexOf("<body>")+6,body.indexOf("</body>"));
	}

	private ResponseUserInfo parseRegisterInfo(String body){
		body = "<body>" + new String(Base64.getDecoder().decode(body)) + "</body>";
		ResponseUserInfo userInfo = XStreamUtil.xmlToObject("body", ResponseUserInfo.class, body);
		return userInfo;
	}
}