package cn.hmsoft.skill.service.std;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.hmsoft.frame.constants.FrameStatus;
import cn.hmsoft.frame.constants.FrameThreadCallbackType;
import cn.hmsoft.frame.constants.FrameThreadStatus;
import cn.hmsoft.frame.data.model.FrameOptr;
import cn.hmsoft.frame.data.model.FrameThread;
import cn.hmsoft.frame.exception.BusinessException;
import cn.hmsoft.frame.thread.FrameThreadHelper;
import cn.hmsoft.frame.util.FrameAssertUtil;
import cn.hmsoft.frame.util.FrameIdCardUtil;
import cn.hmsoft.helper.JsonHelper;
import cn.hmsoft.helper.StringHelper;
import cn.hmsoft.skill.constants.ArtParamName;
import cn.hmsoft.skill.constants.StdCertType;
import cn.hmsoft.skill.constants.StdLogType;
import cn.hmsoft.skill.data.dao.school.SchoolAspectDao;
import cn.hmsoft.skill.data.dao.std.StdEnrolDao;
import cn.hmsoft.skill.data.dao.std.StdLogDao;
import cn.hmsoft.skill.data.dao.std.StdRegDao;
import cn.hmsoft.skill.data.model.school.SchoolAspect;
import cn.hmsoft.skill.data.model.school.SchoolReg;
import cn.hmsoft.skill.data.model.std.StdEnrol;
import cn.hmsoft.skill.data.model.std.StdEnrolSubject;
import cn.hmsoft.skill.data.model.std.StdReg;
import cn.hmsoft.skill.helper.ArtParamHelper;
import cn.hmsoft.skill.helper.StdFetchHelper;
import cn.hmsoft.skill.service.SkillService;

@Service
public class StdRegService extends SkillService {

	@Autowired
	private StdRegDao stdRegDao;
	@Autowired
	private StdRegDao daoStd;
	@Autowired
	private StdLogDao stdLogDao;
	@Autowired
	private StdEnrolDao stdEnrolDao;
	@Autowired
	private SchoolAspectDao schoolAspectDao;

	public StdReg create(StdReg std) throws BusinessException {
		FrameAssertUtil.checkParam(std.getCert_id(), std.getStd_name(), std.getStd_sex());
		std.setCert_id(std.getCert_id().trim().toUpperCase());
		std.setReg_time(LocalDateTime.now());
		StdReg s = this.stdRegDao.find("cert_id", std.getCert_id());
		if (s != null) {
			throw new BusinessException("证件号【" + std.getCert_id() + "】已存在，请检查");
		}
		try {
			std.setStd_province("");
			this.stdRegDao.insert(std);
			this.stdLogDao.log(std.getFrom_school(), std.getStd_id(), StdLogType.Reg, LocalDateTime.now(), null,
					JsonHelper.fromObject(std));
		} catch (Exception e) {
			e.printStackTrace();
			throw new BusinessException(e.getMessage());
		}
		return std;

	}

	public void delete(Integer std_id, FrameOptr frameOptr) {
		StdReg std = this.stdRegDao.find(std_id);
		List<Map<String, Object>> array = this.stdEnrolDao.listEnrol(std_id, std.getFrom_school());
		for (Map<String, Object> enrol : array) {
			if (enrol.containsKey("pay_status")
					&& FrameStatus.Active.toString().equals(enrol.get("pay_status").toString()))
				throw new BusinessException("该考生有缴费成功的报考，禁止删除考生");
		}
		this.stdEnrolDao.delete(StdEnrol.class, "std_id", std_id);
		this.stdEnrolDao.delete(StdEnrolSubject.class, "std_id", std_id);
		// this.stdEnrolDao.delete(StdMaterial.class, "std_id", std_id);
		this.stdEnrolDao.delete(StdReg.class, "std_id", std_id);
		this.stdLogDao.log(std.getFrom_school(), std_id, StdLogType.Delete, LocalDateTime.now(), frameOptr,
				JsonHelper.fromObject(std));
	}

	public void save(StdReg std, FrameOptr frameOptr) {
		FrameAssertUtil.checkParam(std.getCert_id(), std.getStd_name(), std.getStd_sex());
		std.setCert_id(std.getCert_id().trim().toUpperCase());
		if (!FrameIdCardUtil.validateIdCard18(std.getCert_id()))
			throw new BusinessException("证件号码错误，请检查！");
		this.stdRegDao.update(std);
		this.stdLogDao.log(std.getFrom_school(), std.getStd_id(), StdLogType.Update, LocalDateTime.now(), frameOptr,
				JsonHelper.fromObject(std));
	}

	/**
	 * 导入批量注册.
	 * 
	 * @param thread
	 * @param values
	 * @param frameOptr
	 */
	@SuppressWarnings("unused")
	public void batchReg(FrameThread thread, List<List<String>> values, FrameOptr frameOptr) {
		int total = 0;
		int row = 2;
		for (List<String> list : values) {
			String cert_type = list.get(0) == null ? null : list.get(0).trim();
			String cert_id = list.get(1) == null ? null : list.get(1).trim();
			String exam_id = list.get(2) == null ? null : list.get(2).trim();
			String aspect_name = list.get(3) == null ? null : list.get(3).trim();
			String std_name = list.get(4) == null ? null : list.get(4).trim();
			String std_sex = list.get(5) == null ? null : list.get(5).trim();
			String link_mobile = list.get(6) == null ? null : list.get(6).trim();
			String std_nation = list.get(7) == null ? null : list.get(7).trim();
			String std_province = list.get(8) == null ? null : list.get(8).trim();
			String std_city = list.get(9) == null ? null : list.get(9).trim();
			String link_addr = list.get(10) == null ? null : list.get(10).trim();
			// 证件类型
			if (StringHelper.isEmpty(cert_type)) {
				uploadError(thread, "第【" + row + "】行，证件类型不能为空");
			}
			// 证件号码不能为空
			if (StringHelper.isEmpty(cert_id))
				uploadError(thread, "第【" + row + "】行证件号码不能为空");
			// 高考报名号不能为空
			if (StringHelper.isEmpty(exam_id))
				uploadError(thread, "第【" + row + "】行，高考报名号不能为空");
			// 报考专业不能为空
			if (StringHelper.isEmpty(aspect_name))
				uploadError(thread, "第【" + row + "】行，报考专业不能为空");
			// 姓名不能为空
			if (StringHelper.isEmpty(std_name))
				uploadError(thread, "第【" + row + "】行，姓名不能为空");
			List<SchoolAspect> saList = this.schoolAspectDao.findAspectByName(frameOptr.getOrg_id(), aspect_name);
			if (saList.size() == 0) {
				uploadError(thread, "第【" + row + "】行，找不到该专业");
			}
			// 判断编号是否重复
			StdReg tr = this.stdRegDao.find(StdReg.class, "cert_id", cert_id);
			if (tr != null) {
				List<StdEnrol> enrolList = this.stdEnrolDao.list("std_id", tr.getStd_id());
				if (enrolList.size() > 0) {
					uploadError(thread, "第【" + row + "】行，证件号【" + cert_id + "】已经存在报考");
				} else {
					createEnrol(frameOptr, saList, tr);
				}
			} else {
				tr = new StdReg();
				if (cert_type.equals("居民身份证")) {
					tr.setCert_type(StdCertType.IdCard);
				} else if (cert_type.equals("外国护照")) {
					tr.setCert_type(StdCertType.Passport);
				} else if (cert_type.equals("台湾居民往来大陆通行证")) {
					tr.setCert_type(StdCertType.TaiWanPass);
				} else if (cert_type.equals("港澳居民来往内地通行证")) {
					tr.setCert_type(StdCertType.HongKongMacaoPass);
				}
				tr.setFrom_school(frameOptr.getOrg_id());
				tr.setCert_id(cert_id);
				tr.setExam_id(exam_id);
				tr.setStd_name(std_name);
				tr.setStd_sex(std_sex);
				tr.setStd_mobile1(link_mobile);
				tr.setStd_nation(std_nation);
				tr.setStd_province(std_province);
				tr.setStd_city(std_city);
				tr.setLink_addr(link_addr);
				tr.setConfirm_time(LocalDateTime.now());// 默认都确认了
				tr.setStd_pass(cert_id.substring(cert_id.length() - 6));// 证件号码后6位为密码
				tr.setReg_time(LocalDateTime.now());

				SchoolReg school = this.daoStd.find(SchoolReg.class, frameOptr.getOrg_id());

				StdReg transStd = StdFetchHelper.fetch(school, tr);

				// 判断考试院数据接口是否有数据
				if (transStd != null) {
					try {
						this.stdRegDao.insert(transStd);
						createEnrol(frameOptr, saList, transStd);
					} catch (Exception e) {
						e.printStackTrace();
						uploadError(thread, "第【" + row + "】行，文字信息过长，请缩减后重新上传！");
					}

				} else {
					// 技能高考需要判断考试院接口中是否有信息返回
					String sysType = ArtParamHelper.getParamValue(ArtParamName.SysType, "Skill");
					if (sysType.equals("Sk")) {
						// 考试院接口中如果不存在，则抛出异常
						uploadError(thread, "第【" + row + "】行，考生信息不在考试院报名库中！");
					} else {
						try {
							this.stdRegDao.insert(tr);
							createEnrol(frameOptr, saList, tr);
						} catch (Exception e) {
							e.printStackTrace();
							uploadError(thread, "第【" + row + "】行，文字信息过长，请缩减后重新上传！");
						}

					}

				}
			}

			total++;
			row++;
			if (total % 10 == 0) {
				// 每100条记录下
				FrameThreadHelper.updateThread(thread, total * 10 / values.size(),
						"已处理【" + total + "】条注册，一共需要处理【" + values.size() + "】条记录");
			}

		}
		FrameThreadHelper.completeThread(thread, "导入成功：已处理【" + total + "】条注册");
		this.log(frameOptr, StdLogType.BatchReg.toString(), values.size());
	}

	private void createEnrol(FrameOptr frameOptr, List<SchoolAspect> saList, StdReg tr) {
		StdEnrol enrol = new StdEnrol();
		enrol.setAspect_id(saList.get(0).getAspect_id());
		enrol.setSchool_id(frameOptr.getOrg_id());
		enrol.setEnrol_status("Active");
		enrol.setEnrol_time(LocalDateTime.now());
		enrol.setFee_amount(saList.get(0).getFee_amount());
		enrol.setPay_status("Active");
		enrol.setStd_id(tr.getStd_id());
		this.stdEnrolDao.insert(enrol);
	}

	private void uploadError(FrameThread thread, String value) {
		FrameThreadHelper.completeThread(thread, "出现业务错误，导入失败！", FrameThreadCallbackType.Swal, value,
				FrameThreadStatus.Error);
		throw new BusinessException(value);
	}

	/**
	 * 判断考生是否预报名缴费
	 * 
	 * @param std_id
	 */
	public void stdPaymentUpdate(Integer std_id) {
		StdReg std = this.stdRegDao.find(std_id);
		List<Map<String, Object>> array = this.stdEnrolDao.listEnrol(std_id, std.getFrom_school());
		List<SchoolAspect> saList = this.schoolAspectDao.findAspectBySchoolId(std.getFrom_school());
		if (array.size() > 0) {
			for (Map<String, Object> enrol : array) {
				if (enrol.containsKey("pay_status")
						&& FrameStatus.Active.toString().equals(enrol.get("pay_status").toString())) {
					throw new BusinessException("该考生有缴费成功的报考,不需要重复缴费！");
				} else {
					this.stdEnrolDao.stdPaymentUpdate(std_id, std.getFrom_school());

					this.stdLogDao.log(std.getFrom_school(), std.getStd_id(), StdLogType.Update, LocalDateTime.now(),
							null, JsonHelper.fromObject(std));
				}
			}
		} else {
			StdEnrol enrol = new StdEnrol();
			enrol.setAspect_id(saList.get(0).getAspect_id());
			enrol.setSchool_id(std.getFrom_school());
			enrol.setEnrol_status("Active");
			enrol.setEnrol_time(LocalDateTime.now());
			enrol.setFee_amount(saList.get(0).getFee_amount());
			enrol.setPay_status("Active");
			enrol.setStd_id(std_id);
			this.stdEnrolDao.insert(enrol);
			this.stdLogDao.log(std.getFrom_school(), std.getStd_id(), StdLogType.Enrol, LocalDateTime.now(), null,
					JsonHelper.fromObject(std));
		}

	}

	/**
	 * 重置考生密码
	 * 
	 * @param std_id
	 */
	public void stdUpdatePassword(Integer std_id) {
		StdReg std = this.stdRegDao.find(std_id);
		if (StringHelper.isEmpty(std.getCert_id())) {
			this.stdRegDao.stdUpdatePassword(std_id, std.getFrom_school());
			this.stdLogDao.log(std.getFrom_school(), std.getStd_id(), StdLogType.Update, LocalDateTime.now(), null,
					JsonHelper.fromObject(std));
		} else {
			String password = std.getCert_id().substring(std.getCert_id().length() - 6, std.getCert_id().length());
			this.stdRegDao.stdUpdatePassword(std_id, std.getFrom_school(), password);
			this.stdLogDao.log(std.getFrom_school(), std.getStd_id(), StdLogType.Update, LocalDateTime.now(), null,
					JsonHelper.fromObject(std));
		}

	}

	/**
	 * 添加身份证照片信息
	 * 
	 * @param std_id
	 * @param std_param5
	 */
	public void stdUpdateIdcard(int std_id, String std_param5) {
		this.stdRegDao.stdUpdateIdcard(std_id, std_param5);
	}

	/**
	 * 添加免冠照片信息
	 * 
	 * @param std_id
	 * @param std_param5
	 */
	public void stdUpdateNoCrownPhoto(int std_id, String std_image) {
		this.stdRegDao.stdUpdateNoCrownPhoto(std_id, std_image);
	}

}
