package com.cku.oa.handler.service;

import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cku.oa.handler.dao.HandlerDiplomaDao;
import com.cku.oa.handler.dao.HandlerQualificationCertificateDao;
import com.cku.oa.handler.dao.RefereeRankingDao;
import com.cku.oa.handler.dao.RefereeRankingSchemDao;
import com.cku.oa.handler.entity.HandlerQualificationCertificate;
import com.cku.oa.handler.entity.RefereeRanking;
import com.cku.oa.handler.entity.RefereeRankingSchem;
import com.cku.oa.show.dao.ShowApplyDao;
import com.cku.oa.show.dao.ShowResultsDao;
import com.cku.oa.show.entity.ShowApply;
import com.cku.oa.show.entity.ShowResults;
import com.cku.oa.trainschool.dao.TrainingInstitutionDao;
import com.cku.oa.trainschool.entity.TrainingInstitution;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.StringUtils;

@Service
@Transactional(readOnly = true)
public class RefereeRankingSchemService extends CrudService<RefereeRankingSchemDao, RefereeRankingSchem> {

	@Autowired
	private ShowResultsDao showResultsDao;
	@Autowired
	private ShowApplyDao showApplyDao;
	@Autowired
	private RefereeRankingDao refereeRankingDao;
	@Autowired
	private HandlerQualificationCertificateDao handlerQualificationCertificateDao;
	@Autowired
	private TrainingInstitutionDao trainingInstitutionDao;
	@Autowired
	private HandlerDiplomaDao handlerDiplomaDao;

	public RefereeRankingSchem get(String id) {
		return super.get(id);
	}

	public List<RefereeRankingSchem> findList(RefereeRankingSchem refereeRankingSchem) {
		return super.findList(refereeRankingSchem);
	}

	public Page<RefereeRankingSchem> findPage(Page<RefereeRankingSchem> page, RefereeRankingSchem refereeRankingSchem) {
		return super.findPage(page, refereeRankingSchem);
	}

	@Transactional(readOnly = false)
	public void save(RefereeRankingSchem refereeRankingSchem) {
		super.save(refereeRankingSchem);
	}

	@Transactional(readOnly = false)
	public void delete(RefereeRankingSchem refereeRankingSchem) {
		super.delete(refereeRankingSchem);
	}

	@Transactional(readOnly = false)
	public void saveSchem(RefereeRankingSchem refereeRankingSchem) {
		getSerialNumAndDesc(refereeRankingSchem);
		refereeRankingSchem.setStatus("0");

		dao.deleteBySerialNum(refereeRankingSchem.getSerialNum());
		refereeRankingDao.deleteBySerialNum(refereeRankingSchem.getSerialNum());
		this.save(refereeRankingSchem);
	}

	// 生成序号
	public RefereeRankingSchem getSerialNumAndDesc(RefereeRankingSchem refereeRankingSchem) {
		switch (refereeRankingSchem.getType()) {
		case "1":
			refereeRankingSchem.setSerialNum(refereeRankingSchem.getYear());
			refereeRankingSchem.setRemarks(refereeRankingSchem.getYear() + "年年度积分方案");
			break;
		case "2":
			refereeRankingSchem.setSerialNum(refereeRankingSchem.getYear() + "-Q" + refereeRankingSchem.getQuarter());
			refereeRankingSchem
					.setRemarks(refereeRankingSchem.getYear() + "年" + refereeRankingSchem.getQuarter() + "季度积分方案");
			break;
		case "3":
			refereeRankingSchem.setSerialNum(refereeRankingSchem.getYear() + "-M" + refereeRankingSchem.getMonth());
			refereeRankingSchem
					.setRemarks(refereeRankingSchem.getYear() + "年" + refereeRankingSchem.getMonth() + "月度积分方案");
			break;

		case "4":
			if ("1".equals(refereeRankingSchem.getHalf())) {
				refereeRankingSchem.setSerialNum(refereeRankingSchem.getYear() + "-First");
				refereeRankingSchem.setRemarks(refereeRankingSchem.getYear() + "年" + "上半年积分方案");
			} else {
				refereeRankingSchem.setSerialNum(refereeRankingSchem.getYear() + "-Second");
				refereeRankingSchem.setRemarks(refereeRankingSchem.getYear() + "年" + "下半年积分方案");
			}

			break;
		}
		return refereeRankingSchem;
	}

	public List<String> getAllMonth() {
		return dao.getAllMonth();
	}

	public List<String> getAllYear() {
		return dao.getAllYear();
	}

	@Transactional(readOnly = false)
	@Async
	public void create(String id) {
		RefereeRankingSchem schem = this.get(id);

		// 根据类型查询区间成绩
		List<ShowResults> results = new ArrayList<>();
		String type = schem.getType();
		if (type.equals("1")) {
			results = showResultsDao.getRangeResultList(schem.getYear() + "-01-01", schem.getYear() + "-12-31");
		} else if (type.equals("2")) {
			Map<String, String> quarterMap = getQuarter(schem);
			results = showResultsDao.getRangeResultList(quarterMap.get("firstDay"), quarterMap.get("lastDay"));
		} else if (type.equals("3")) {
			// 月第一天
			LocalDate localDate = LocalDate.of(Integer.parseInt(schem.getYear()), Integer.parseInt(schem.getMonth()),
					1);
			// 月最后一天
			LocalDate lastDay = localDate.with(TemporalAdjusters.lastDayOfMonth());
			results = showResultsDao.getRangeResultList(localDate.toString(), lastDay.toString());
		} else if (type.equals("4")) {
			if ("1".equals(schem.getHalf())) { // 上半年
				results = showResultsDao.getRangeResultList(schem.getYear() + "-01-01", schem.getYear() + "-06-30");
			} else {
				results = showResultsDao.getRangeResultList(schem.getYear() + "-07-01", schem.getYear() + "-12-31");
			}
		}

		Map<String, Integer> tempMap = new HashMap<>();
		for (ShowResults result : results) {
			boolean flag = true;
			// 根据赛事成绩查询赛事报名获取牵犬师信息
			ShowApply showApply = showApplyDao.findByQusInfo(result.getShowCode(), result.getPedigreeCertified());
			if (showApply == null) {
				continue;
			}

			String isOwner = showApply.getIsOwner();
			// 是否为犬主人组
			if (StringUtils.isNotEmpty(isOwner) && isOwner.contains("1")) {
				String[] showCodeArray = showApply.getShowCode().split(",");
				String[] isOwnerArray = isOwner.split(",");
				for (int i = 0; i < isOwnerArray.length; i++) {
					if (isOwnerArray[i].equals("1") && showCodeArray[i].equals(result.getShowCode())) {
						flag = false;
						break;
					}
				}
			}

			if (flag && StringUtils.isNotEmpty(showApply.getHandlerMemberCode())) {
				String code = showApply.getHandlerMemberCode().split(",")[0]; // 牵犬师
				String max = getMax(result);
				// 修改赛事成绩
				result.setQusResult(max);
				result.setQusCode(code);
				showResultsDao.updateQusResult(result);
				// 暂存牵犬师成绩
				Integer score = tempMap.get(code);
				if (score != null) {
					tempMap.put(code, Integer.parseInt(max) + score);
				} else {
					tempMap.put(code, Integer.parseInt(max));
				}
			}
		}

		// 牵犬师区间积分
		List<RefereeRanking> resultList = new ArrayList<>();
		for (String key : tempMap.keySet()) {
			Integer score = tempMap.get(key);
			if (type.equals("1")) {
				// 基础积分 牵犬师资质
				score = score + baseScore(key, schem);
			}
			if (score > 0) {
				RefereeRanking refereeRanking = new RefereeRanking();
				refereeRanking.setCreateDate(new Date());
				refereeRanking.setDelFlag("0");
				refereeRanking.setMemberCode(key);
				refereeRanking.setSerialNum(schem.getSerialNum());
				refereeRanking.setRankingScore(score.toString());
				refereeRanking.setYear(schem.getYear());
				refereeRanking.setType(schem.getType());
				refereeRanking.setQuarter(schem.getQuarter());
				refereeRanking.setMonth(schem.getMonth());
				refereeRanking.setRemarks(schem.getRemarks());
				refereeRanking.setHalf(schem.getHalf());
				resultList.add(refereeRanking);
			}
		}
		if (CollectionUtils.isNotEmpty(resultList)) {
			refereeRankingDao.insertBatch(resultList);
		}

		schem.setStatus("2");
		this.save(schem);
	}

	private String getMax(ShowResults results) {
		String bis = results.getResultBis();
		if (StringUtils.isNotEmpty(bis)) {
			switch (bis) {
			case "BIS1":
				return "100";
			case "BIS2":
				return "90";
			case "BIS3":
				return "80";
			case "BIS4":
			case "JBIS1":
				return "70";
			case "JBIS2":
				return "60";
			case "PBIS1":
			case "JBIS3":
			case "BPBIS1":	
				return "50";
			case "PBIS2":
			case "JBIS4":
			case "BPBIS2":
				return "40";
			case "PBIS3":
			case "BPBIS3":
				return "30";
			case "PBIS4":
			case "BPBIS4":
				return "20";
			case "BBIS1":
				return "50";
			case "BBIS2":
				return "40";
			case "BBIS3":
				return "30";
			case "BBIS4":
				return "20";
			}
		}
		String jbis = results.getResultJbis();
		if (StringUtils.isNotEmpty(jbis)) {
			switch (jbis) {
			case "JBIS1":
				return "70";
			case "JBIS2":
				return "60";
			case "JBIS3":
				return "50";
			case "JBIS4":
				return "40";
			}
		}

		String big = results.getResultBig();
		if (StringUtils.isNotEmpty(big)) {
			switch (big) {
			case "BIG1":
				return "60";
			case "BIG2":
				return "50";
			case "BIG3":
				return "40";
			case "BIG4":
				return "30";
			}
		}

		String bob = results.getResultBob();
		if (StringUtils.isNotEmpty(bob)) {
			switch (bob) {
			case "BOB":
				return "20";
			case "PBOB":
			case "BPBOB":
			case "BOS":
				return "10";
			case "PBOS":
			case "BPBOS":
				return "5";
			}
		}
		return "0";
	}

	private int baseScore(String memberCode, RefereeRankingSchem schem) {
		int score = 0;
		//查出牵犬师资格证书列表
		List<HandlerQualificationCertificate> certificateList = handlerQualificationCertificateDao
				.getByMemberCode(memberCode);
		List<Integer> maxList = new ArrayList<>();
		for (HandlerQualificationCertificate handlerQualificationCertificate : certificateList) {
			switch (handlerQualificationCertificate.getCertificateLevelEn()) {
			case "MASTER":
				maxList.add(500);
				break;
			case "A":
				maxList.add(400);
				break;
			case "B":
				maxList.add(300);
				break;
			case "C":
				maxList.add(200);
				break;
			}
		}
		if (CollectionUtils.isNotEmpty(maxList)) {
			score = score + Collections.max(maxList);
		}

		TrainingInstitution trainingInstitution = trainingInstitutionDao.getQusByMemberCode(memberCode);
		if (trainingInstitution != null) {
			List<HandlerQualificationCertificate> qualificationCertificateList = new ArrayList<>();
			Date yearDate = DateUtils.parseDate(schem.getYear() + "-12-31");
			if (yearDate.before(trainingInstitution.getEndDate())) {
				score = score + handlerDiplomaDao.countBySchoolId(trainingInstitution.getId(),
						DateUtils.formatDate(yearDate));
				qualificationCertificateList = handlerQualificationCertificateDao
						.getBySchoolId(trainingInstitution.getSchoolNameCn(), DateUtils.formatDate(yearDate));
			} else {
				score = score + handlerDiplomaDao.countBySchoolId(trainingInstitution.getSchoolNameCn(),
						DateUtils.formatDate(trainingInstitution.getEndDate()));
				qualificationCertificateList = handlerQualificationCertificateDao.getBySchoolId(
						trainingInstitution.getSchoolNameCn(), DateUtils.formatDate(trainingInstitution.getEndDate()));
			}

			for (HandlerQualificationCertificate obj : qualificationCertificateList) {
				if ("A".equals(obj.getCertificateLevelEn())) {
					score = score + 300;
				} else if ("B".equals(obj.getCertificateLevelEn())) {
					score = score + 200;
				} else if ("C".equals(obj.getCertificateLevelEn())) {
					score = score + 100;
				}
			}

		}

		return score;
	}

	public Map<String, String> getQuarter(RefereeRankingSchem schem) {
		Map<String, String> map = new HashMap<>();
		String firstDay = "";
		String lastDay = "";
		if (schem.getQuarter().equals("1")) {
			firstDay = schem.getYear() + "-01-01";
			lastDay = schem.getYear() + "-03-31";
		} else if (schem.getQuarter().equals("2")) {
			firstDay = schem.getYear() + "-04-01";
			lastDay = schem.getYear() + "-06-30";
		} else if (schem.getQuarter().equals("3")) {
			firstDay = schem.getYear() + "-07-01";
			lastDay = schem.getYear() + "-09-30";
		} else if (schem.getQuarter().equals("4")) {
			firstDay = schem.getYear() + "-10-01";
			lastDay = schem.getYear() + "-12-31";
		}
		map.put("firstDay", firstDay);
		map.put("lastDay", lastDay);
		return map;
	}

	@Transactional(readOnly = false)
	public int updateStatus(String id, String status) {
		return dao.updateStatus(id, status);
	}

	public RefereeRankingSchem getBySerialNum(String serialNum) {
		return dao.getBySerialNum(serialNum);
	}

	public Map<String, String> schemCheck(RefereeRankingSchem refereeRankingSchem) {
		refereeRankingSchem = this.getSerialNumAndDesc(refereeRankingSchem);
		RefereeRankingSchem temp = dao.getBySerialNum(refereeRankingSchem.getSerialNum());
		Map<String, String> resultMap = new HashMap<>();
		resultMap.put("data", "OK");
		if (temp != null) {
			resultMap.put("data", "ERROR");
		}
		return resultMap;
	}

}
