package cn.hmsoft.skill.service.cf;

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

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

import cn.hmsoft.frame.constants.FrameStatus;
import cn.hmsoft.frame.data.model.FrameOptr;
import cn.hmsoft.frame.exception.BusinessException;
import cn.hmsoft.frame.util.FrameAssertUtil;
import cn.hmsoft.helper.JsonHelper;
import cn.hmsoft.helper.StringHelper;
import cn.hmsoft.skill.constants.SkillLogType;
import cn.hmsoft.skill.constants.StdLogType;
import cn.hmsoft.skill.data.dao.school.SchoolAspectDao;
import cn.hmsoft.skill.data.dao.school.SchoolLogDao;
import cn.hmsoft.skill.data.dao.school.SchoolRegDao;
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.StdReg;
import cn.hmsoft.skill.enrol.service.EnrolStdEnrolService;
import cn.hmsoft.skill.enrol.service.EnrolStdRegService;
import cn.hmsoft.skill.helper.StdFetchHelper;
import cn.hmsoft.skill.service.SkillService;

@Service
public class SchoolAspectService extends SkillService {

	@Autowired
	private SchoolRegDao daoSchool;

	@Autowired
	private SchoolLogDao daoLog;
	@Autowired
	private StdEnrolDao daoEnrol;
	@Autowired
	private StdLogDao daoStdLog;
	@Autowired
	private StdRegDao daoStd;

	@Autowired
	private EnrolStdEnrolService sEnrol;

	@Autowired
	private EnrolStdRegService sStd;
	@Autowired
	private SchoolAspectDao schoolAspectDao;
	
	public void save(SchoolAspect aspect) {
		this.daoSchool.update(aspect);
		this.daoLog.log(aspect.getSchool_id(), SkillLogType.SchoolAspect_Save.toString(), aspect.getAspect_name());

	}

	public void cashPay(int enrol_id, SchoolReg school, FrameOptr optr) {
		StdEnrol enrol = this.daoEnrol.find(enrol_id);
		FrameAssertUtil.isNotNull(enrol, "基础数据错误！");
		FrameAssertUtil.isEqual(enrol.getSchool_id(), school.getSchool_id(), "越权操作，请检查当前角色权限！");
		if (FrameStatus.Active.toString().equals(enrol.getPay_status()))
			throw new BusinessException("该考生的此专业报考已完成缴费操作！");
		//
		enrol.setPay_status(FrameStatus.Active.toString());
		enrol.setPay_time(LocalDateTime.now());
		StdReg std = this.daoEnrol.find(StdReg.class, enrol.getStd_id());
		SchoolAspect aspect = this.daoEnrol.find(SchoolAspect.class, enrol.getAspect_id());

		this.daoLog.log(school.getSchool_id(), SkillLogType.StdPay.toString(),
				std.getStd_name() + " -> " + aspect.getAspect_name(), std.getStd_id() + " -> " + aspect.getAspect_id(),
				enrol.getPay_time());
		this.daoStdLog.log(school.getSchool_id(), std.getStd_id(), StdLogType.CashPay, optr, aspect.getAspect_name());
		this.daoEnrol.update(enrol);
	}

	public void unCashPay(int enrol_id, SchoolReg school, FrameOptr optr) {
		StdEnrol enrol = this.daoEnrol.find(enrol_id);
		FrameAssertUtil.isNotNull(enrol, "基础数据错误！");
		FrameAssertUtil.isEqual(enrol.getSchool_id(), school.getSchool_id(), "越权操作，请检查当前角色权限！");
		if (!FrameStatus.Active.toString().equals(enrol.getPay_status()))
			throw new BusinessException("该考生的此专业报考未完成缴费！");
		if (enrol.getBill_id() != null)
			throw new BusinessException("该考生的缴费是通过网络进行的，不可进行取消！");

		StdReg std = this.daoEnrol.find(StdReg.class, enrol.getStd_id());
		SchoolAspect aspect = this.daoEnrol.find(SchoolAspect.class, enrol.getAspect_id());

		this.daoLog.log(school.getSchool_id(), SkillLogType.UnStdPay.toString(),
				std.getStd_name() + " -> " + aspect.getAspect_name(), std.getStd_id() + " -> " + aspect.getAspect_id(),
				enrol.getPay_time());
		this.daoStdLog.log(school.getSchool_id(), std.getStd_id(), StdLogType.UnCashPay, optr, aspect.getAspect_name());
		this.daoEnrol.unPay(enrol_id);
	}

	public void saveUpload(List<List<String>> array, int school_id, boolean auto_reg, boolean auto_enrol,
			boolean auto_pay, boolean none_trans) {
		SchoolReg school = this.daoSchool.find(school_id);
		String sql = "select * from school_aspect where school_id=? and aspect_name=?";
		String enrol_sql = "select * from std_enrol where std_id=? and aspect_id=?";
		for (List<String> list : array) {
			String seq = list.get(0) == null ? "" : list.get(0).trim();
			if (StringHelper.isEmpty(seq))
				continue;
			String cert_id = list.get(1) == null ? "" : list.get(1).trim();
			String exam_id = list.get(2) == null ? "" : list.get(2).trim();
			String std_name = list.get(3) == null ? "" : list.get(3).trim();
			String aspect_name = list.get(4) == null ? "" : list.get(4).trim();
			String std_mobile1 = list.get(5) == null ? "" : list.get(5).trim();
			String std_mobile2 = list.get(6) == null ? "" : list.get(6).trim();
			String link_addr = list.get(7) == null ? "" : list.get(7).trim();
			List<SchoolAspect> aspectArray = this.daoEnrol.listBySql(SchoolAspect.class, sql, school_id, aspect_name);
			if (aspectArray.size() == 0) {
				list.add("专业名称不存在");
				if (!none_trans) {
					throw new BusinessException("专业名称不存在");
				} else
					continue;
			} else if (aspectArray.size() > 1) {
				list.add("专业名称重复");
				if (!none_trans) {
					throw new BusinessException("专业名称重复");
				} else
					continue;
			}
			SchoolAspect aspect = aspectArray.get(0);
			// 检查是否存在
			StdReg std = this.daoStd.find("cert_id", cert_id);
			if (std == null) {
				if (auto_reg) {
					std = new StdReg();
					std.setCert_id(cert_id);
					std.setStd_name(std_name);
					std.setExam_id(exam_id);

					StdReg transStd = null;
					try {
						transStd = StdFetchHelper.fetch(school, std);
					} catch (Exception e) {
						e.printStackTrace();

					}
					if (transStd == null || transStd.getReg_time() == null) {
						list.add("[" + cert_id + "]未能从考试院获取到考生数据，请稍候再试");
						if (!none_trans) {
							throw new BusinessException("[" + cert_id + "]未能从考试院获取到考生数据，请稍候再试");
						} else
							continue;
					} else {
						transStd.setFrom_school(school_id);
						transStd.setStd_mobile1(std_mobile1);
						transStd.setStd_mobile2(std_mobile2);
						transStd.setLink_addr(link_addr);
						this.sStd.stdFormRemote(school, transStd);
						std = transStd;
					}
				} else {
					if (!none_trans) {
						list.add("未进行信息注册");
						throw new BusinessException("未进行信息注册");
					} else {
						continue;
					}
				}
			}

			// 报名
			StdEnrol enrol = this.daoEnrol.findBySql(enrol_sql, std.getStd_id(), aspect.getAspect_id());

			if (enrol == null) {
				if (auto_enrol) {
					try {
						enrol = new StdEnrol();
						enrol.setSchool_id(school_id);
						enrol.setAspect_id(aspect.getAspect_id());
						enrol.setEnrol_status(FrameStatus.Active.toString());
						enrol.setEnrol_time(LocalDateTime.now());
						enrol.setFee_amount(aspect.getFee_amount());
						enrol.setStd_id(std.getStd_id());
						this.sEnrol.save(std, enrol, true);
					} catch (Exception e) {
						if (!none_trans) {
							list.add(e.getMessage());
							throw new BusinessException(e.getMessage());
						} else {
							list.add(e.getMessage());
							continue;
						}
					}
				} else {
					if (!none_trans) {
						list.add("未进行专业报考");
						throw new BusinessException("未进行专业报考");
					} else {
						list.add("未进行专业报考");
						continue;
					}
				}
			} else {
				if (!enrol.getAspect_id().equals(aspect.getAspect_id())) {
					if (!none_trans) {
						list.add("考生报考专业和导入信息不一致");
						throw new BusinessException("考生报考专业和导入信息不一致");
					} else {
						list.add("考生报考专业和导入信息不一致");
						continue;
					}
				}
			}

			// 缴费
			if (!FrameStatus.Active.toString().equals(enrol.getPay_status())) {
				if (auto_pay) {
					try {
						this.sEnrol.pay(enrol.getEnrol_id(), null);
						list.add("导入成功，标记为现金缴费");
					} catch (Exception e) {
						if (!none_trans) {
							list.add(e.getMessage());
							throw new BusinessException(e.getMessage());
						} else {
							list.add(e.getMessage());
							continue;
						}
					}
				} else {
					list.add("导入成功，完成报考，未进行缴费");
				}
			} else
				list.add("导入前已完成缴费");

		}

	}

	/*************
	 * 更改考生专业
	 * 
	 * @param school_id
	 * @param enrol_id
	 * @param aspect_id
	 */
	public void changeStdAspect(int school_id, int enrol_id, int aspect_id, FrameOptr optr) {
		SchoolAspect aspect = this.daoEnrol.find(SchoolAspect.class, aspect_id);
		if (aspect == null || aspect.getSchool_id() - school_id != 0)
			return;
		StdEnrol enrol = this.daoEnrol.find(StdEnrol.class, enrol_id);
		if (enrol == null || enrol.getSchool_id() - school_id != 0 || enrol.getAspect_id() - aspect_id == 0)
			return;

		SchoolAspect oAspect = this.daoEnrol.find(SchoolAspect.class, enrol.getAspect_id());
		if (enrol.getFee_amount() - aspect.getFee_amount() != 0)
			throw new BusinessException("专业金额存在差额，不允许直接更换专业！");
		enrol.setAspect_id(aspect_id);
		this.daoEnrol.update(enrol);
		this.daoStdLog.log(school_id, enrol.getStd_id(), StdLogType.ChangeAspect, optr, aspect.getAspect_name(), LocalDateTime.now());
	}

	public void addSchoolAspect(SchoolAspect aspect, FrameOptr frameOptr) {
		this.validValues(aspect);
		// 判断编号是否存在
		FrameAssertUtil.isNull(this.schoolAspectDao.find(aspect.getAspect_id()),
				"编号【" + aspect.getAspect_id() + "】的报考方向已经存在，请修改");
		// 方向名称是否存在
		FrameAssertUtil.isEmpty(this.schoolAspectDao.findAspectByName(aspect.getSchool_id(), aspect.getAspect_name()),
				"名称【" + aspect.getAspect_name() + "】的专业方向已经存在，请修改");
		this.schoolAspectDao.insert(aspect);
		this.log(frameOptr, SkillLogType.SchoolAspect_Add.toString(), JsonHelper.fromObject(aspect));
		
	}
	
	private void validValues(SchoolAspect aspect) {
		FrameAssertUtil.isNotNull(aspect.getAspect_id(), "专业方向编号不能为空");
		FrameAssertUtil.moreThen(aspect.getAspect_id(), "专业方向编号不能小于1");
		FrameAssertUtil.isNotEmpty(aspect.getAspect_name(), "专业方向名称不能为空");
		FrameAssertUtil.isNotEmpty(aspect.getAspect_status(), "专业方向状态不能为空");
		// 判断费用
		FrameAssertUtil.isNotNull(aspect.getFee_amount(), "未找到缴费配置，数据同步错误，请重新登录！");
	}

	public void editSchoolAspect(SchoolAspect aspect, FrameOptr frameOptr) {
		this.validValues(aspect);
		// 判断编号是否存在
		//SchoolAspect cg = this.schoolAspectDao.find("aspect_name", aspect.getAspect_name());
		// 判断编号是否存在
		this.schoolAspectDao.update(aspect);
		this.log(frameOptr, SkillLogType.SchoolAspect_Edit.toString(), JsonHelper.fromObject(aspect));
	}

	public void deleteAspect(int aspect_id, FrameOptr frameOptr) {
		SchoolAspect aspect = this.schoolAspectDao.find(aspect_id);
		FrameAssertUtil.isNotNull(aspect, "未找到该专业方向，数据同步错误，请重新登录");
		// 判断是否有考生使用了该专业
		// 判断是否有考点使用了该专业方向
		/*int count = this.schoolAspectDao.count(SchoolAspect.class, "aspect_id", aspect_id);
		FrameAssertUtil.isEqual(count, 0, "该专业方向被一个或者多个考点使用，禁止删除！");*/
		this.schoolAspectDao.delete(SchoolAspect.class, "aspect_id", aspect_id);
		// 删除报考规则里的
		this.log(frameOptr, SkillLogType.SchoolAspect_Delete.toString(), JsonHelper.fromObject(aspect));
	}
}
