package com.cku.oa.show.service;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cku.core.ZAErrorCode;
import com.cku.core.ZAException;
import com.cku.oa.dog.entity.Dog;
import com.cku.oa.dog.entity.DogOwnerChange;
import com.cku.oa.dog.service.DogOwnerChangeService;
import com.cku.oa.dog.service.DogService;
import com.cku.oa.show.dao.ShowApplyDao;
import com.cku.oa.show.dao.ShowApplyDiscountDao;
import com.cku.oa.show.entity.ApplyDiscountListVo;
import com.cku.oa.show.entity.ChildShows;
import com.cku.oa.show.entity.ShowApply;
import com.cku.oa.show.entity.ShowApplyDiscount;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.service.CrudService;

import edu.emory.mathcs.backport.java.util.Collections;

/**
 * 报名满减优惠表Service
 * 
 * @author xx
 * @version 2022-09-13
 */
@Service
@Transactional(readOnly = true)
public class ShowApplyDiscountService extends CrudService<ShowApplyDiscountDao, ShowApplyDiscount> {

	@Autowired
	private DogOwnerChangeService dogOwnerChangeService;
	@Autowired
	private DogService dogService;
	@Autowired
	private ChildShowsService childShowsService;
	@Autowired
	private ShowApplyDao showApplyDao;

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

	public List<ShowApplyDiscount> findList(ShowApplyDiscount showApplyDiscount) {
		return super.findList(showApplyDiscount);
	}

	public Page<ShowApplyDiscount> findPage(Page<ShowApplyDiscount> page, ShowApplyDiscount showApplyDiscount) {
		return super.findPage(page, showApplyDiscount);
	}

	@Transactional(readOnly = false)
	public void save(ShowApplyDiscount showApplyDiscount) {
		super.save(showApplyDiscount);
	}

	@Transactional(readOnly = false)
	public void delete(ShowApplyDiscount showApplyDiscount) {
		super.delete(showApplyDiscount);
	}

	public ShowApplyDiscount getByShowApplyId(String showApplyId) {
		return dao.getByShowApplyId(showApplyId);
	}

	/**
	 * 主犬展下所有参与优惠的子犬展ID
	 * 
	 * @param mainShowId
	 * @return
	 */
	public Set<String> getDiscountChildShowsId(String mainShowId) {
		List<ChildShows> childShowsList = childShowsService.findListByMainShowId(mainShowId);
		Set<String> set = childShowsList.stream().filter(a -> Objects.equals("0", a.getIsDiscount()))
				.map(a -> a.getId()).collect(Collectors.toSet());// 所有参与优惠的子犬展
		return set;

	}

	/**
	 * 找到主犬展ID
	 * 
	 * @param childShowsId
	 * @return
	 * @throws Exception
	 */
	public String getMainShowId(String childShowsId) throws Exception {
		ChildShows childShows = childShowsService.get(childShowsId);
		if (childShows == null) {
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "所提交的犬展ID没有查到！");
		}
		return childShows.getMainShowId();
	}

	/**
	 * 此次报名能不能进行满减
	 * 
	 * @param pedigreeCertified
	 * @param ageGroups
	 * @return
	 * @throws Exception
	 */
	public boolean isDiscount(String pedigreeCertified, Map<String, String> showIdAgeGroups) throws Exception {
		if (!isCycleSign(pedigreeCertified, showIdAgeGroups)) {// 不满足进入周期的直接返回
			return false;
		}
		String showId = showIdAgeGroups.keySet().iterator().next();// 子犬展ID
		String mainShowId = getMainShowId(showId);
		Dog dog = dogService.getByPedigreeCertifiedCode(pedigreeCertified);

		return checkCycleSignNo(mainShowId, dog.getMemberCode());

	}

	/**
	 * 是否满足进入满减周期的条件
	 * 
	 * @param pedigreeCertified
	 * @param ageGroups
	 * @return
	 * @throws Exception
	 */
	public boolean isCycleSign(String pedigreeCertified, Map<String, String> showIdAgeGroups) throws Exception {
		String showId = showIdAgeGroups.keySet().iterator().next();// 子犬展ID
		String mainShowId = getMainShowId(showId);
		Set<String> set = getDiscountChildShowsId(mainShowId);// 所有参与优惠的子犬展
		if (set.size() == 0) {// 没有设置满减优惠
			return false;
		}
		if (!showIdAgeGroups.keySet().containsAll(set)) {// 每只犬需报名满所有参与优惠的场次
			return false;
		}
		for (String a : set) {// 参赛犬只报名组别，特幼公、特幼母、幼小公、幼小母不参与优惠；
			if (Integer.valueOf(showIdAgeGroups.get(a)) < 5) {
				return false;
			}
		}
		Dog dog = dogService.getByPedigreeCertifiedCode(pedigreeCertified);
		if (!checkDogOwnerChange(dog.getId())) {// 进行过犬主变更则不参加满减
			return false;
		}

		return true;// 提前全部通过 则进入周期计数
	}

	public boolean isCycleSignForStringParam(String pedigreeCertified, String showIdAgeGroupString) throws Exception {
		String[] array = showIdAgeGroupString.split(",");
		Map<String, String> showIdAgeGroups = new HashMap<>();
		for (int i = 0; i < array.length; i++) {
			String[] showIdAgeGroupArray = array[i].split("=");
			showIdAgeGroups.put(showIdAgeGroupArray[0], showIdAgeGroupArray[1]);
		}
		return isCycleSign(pedigreeCertified, showIdAgeGroups);
	}

	/**
	 * 进行过犬主变更则不参加满减
	 * 
	 * @param pedigreeCertified
	 * @return
	 * @throws Exception
	 */
	public boolean checkDogOwnerChange(String dogId) throws Exception {
		Integer a = dogOwnerChangeService
				.countDogOwnerChangeByReviewTime(new SimpleDateFormat("yyyy-MM-dd").parse("2022-08-15"), dogId);
		if (a > 0) {// 参赛犬只8月15日后办理过犬主变更的不参与优惠（判断条件：时间用审核通过时间，审核通过计算为办理完成）
			return false;
		}
		return true;

	}

	/**
	 * 周期计数是否免费
	 * 
	 * @param mainShowId
	 * @param dogOwnerMemberCode
	 * @return
	 */
	public boolean checkCycleSignNo(String mainShowId, String dogOwnerMemberCode) {
		// 犬只需在同一犬主名下,已付款的报名才会计入该表
		String lastCycleSign = dao.getLastCycleSign(mainShowId, dogOwnerMemberCode);// 当前最后一个周期标志
		int count = Objects.isNull(lastCycleSign) ? 0 : dao.countByCycleSign(lastCycleSign);
		// 情况一：此周期有八条记录，周期结束，进入新周期，当前报名不免费
		// 情况二：此周期符合规定的报名满3免1，满6免1，满7免1，计算符合规则的报名个数即可
		// 增加最大优惠只数限制 6最多1 7最多2 8最多3
    	int countDiscount = dao.countDiscountByCycleSign(lastCycleSign);
	    if((count==3 && countDiscount==0) 
	    		|| (count==6 && countDiscount <= 1) 
	    		|| (count==7 && countDiscount <= 2) ) {
			return true;
		}
		return false;

	}

	public int saveNewRecord(ShowApply showApply) throws Exception {
		String uuid = UUID.randomUUID().toString().replaceAll("-", "");
		ShowApplyDiscount ShowApplyDiscount = new ShowApplyDiscount();
		ShowApplyDiscount.setId(uuid);
		ShowApplyDiscount.setShowApplyId(showApply.getId());
		ShowApplyDiscount.setShowMainId(showApply.getMainShowId());
		ShowApplyDiscount.setRunningNumber(showApply.getRunningNumber());
		ShowApplyDiscount.setDiscountSign(showApply.getDogOwnerMemberCode());
		ShowApplyDiscount.setIsDiscount(isDiscount(showApply) ? "0" : "1");
		CycleSignInfo info = getNextCycleSign(showApply.getMainShowId(), showApply.getDogOwnerMemberCode());
		ShowApplyDiscount.setCycleSign(info.getCycleSign());// 周期标志
		ShowApplyDiscount.setCycleSignNo(info.getCycleSignNo());
		ShowApplyDiscount.setDelFlag("0");
		ShowApplyDiscount.preInsert();
		return dao.insert(ShowApplyDiscount);

	}

	/**
	 * 获得下一条记录的周期标志
	 * 
	 * @param mainShowId
	 * @param discountSign
	 * @return
	 */
	private CycleSignInfo getNextCycleSign(String mainShowId, String discountSign) {
		String lastCycleSign = dao.getLastCycleSign(mainShowId, discountSign);// 当前最后一个周期标志
		if (StringUtils.isBlank(lastCycleSign)) {
			return new CycleSignInfo(1, UUID.randomUUID().toString().replaceAll("-", ""));
		}
		int count = dao.countByCycleSign(lastCycleSign);// 最后一个周期有几条记录
		return new CycleSignInfo(count < 8 ?count + 1:1,
				count < 8 ? lastCycleSign : UUID.randomUUID().toString().replaceAll("-", ""));

	}

	private class CycleSignInfo {

		public CycleSignInfo(int cycleSignNo, String cycleSign) {
			this.cycleSign = cycleSign;
			this.cycleSignNo = cycleSignNo;
		}

		private int cycleSignNo;// 周期序号

		private String cycleSign; // 周期标志

		public int getCycleSignNo() {
			return cycleSignNo;
		}

		public void setCycleSignNo(int cycleSignNo) {
			this.cycleSignNo = cycleSignNo;
		}

		public String getCycleSign() {
			return cycleSign;
		}

		public void setCycleSign(String cycleSign) {
			this.cycleSign = cycleSign;
		}
	}

	/**
	 * 后台判断是此次报名是否参与满减
	 * 
	 * @param showApply
	 * @return
	 * @throws Exception
	 */
	public boolean isDiscount(ShowApply showApply) throws Exception {
		Set<String> set = getDiscountChildShowCode(showApply.getMainShowId());// 所有参与优惠的子犬展
		if (set.size() == 0) {// 没有设置满减优惠
			return false;
		}
		Set<String> showApplySet = new HashSet<>(Arrays.asList(showApply.getShowCode().split(",")));
		if (!showApplySet.containsAll(set)) {// 每只犬需报名满所有参与优惠的场次
			return false;
		}
		Set<String> ageGroupSet = new HashSet<>(Arrays.asList(showApply.getAgeGroup().split(",")));
		for (String a : ageGroupSet) {// 参赛犬只报名组别，特幼公、特幼母、幼小公、幼小母不参与优惠；
			if (Integer.valueOf(a) < 5) {
				return false;
			}
		}
		Dog dog = dogService.getByPedigreeCertifiedCode(showApply.getPedigreeCertified());
		if (!checkDogOwnerChange(dog.getId())) {// 进行过犬主变更则不参加满减
			return false;
		}

		return checkCycleSignNo(showApply.getMainShowId(), showApply.getDogOwnerMemberCode());

	}

	/**
	 * 主犬展下所有参与优惠的子犬展code
	 * 
	 * @param mainShowId
	 * @return
	 */
	public Set<String> getDiscountChildShowCode(String mainShowId) {
		List<ChildShows> childShowsList = childShowsService.findListByMainShowId(mainShowId);
		Set<String> set = childShowsList.stream().filter(a -> Objects.equals("0", a.getIsDiscount()))
				.map(a -> a.getShowCode()).collect(Collectors.toSet());// 所有参与优惠的子犬展
		return set;

	}

	/**
	 * 参与减免明细
	 */
	public List<ApplyDiscountListVo> findApplyDiscountList(String discountSign, String showMainId) {
		List<ApplyDiscountListVo> list = dao.findApplyDiscountList(discountSign, showMainId);
		for (ApplyDiscountListVo vo : list) {
			vo.setPaymentState(getPaymentStateDecs(vo));
		}
		return list;
	}

	private String getPaymentStateDecs(ApplyDiscountListVo vo) {
		if (StringUtils.isNotEmpty(vo.getBusinessRefundState())) {
			switch (vo.getBusinessRefundState()) {
			case "1":
				return "退款中";
			case "2":
				return "退款已拒绝";
			case "3":
				return "已退款";
			}
		} else {
			return vo.getPaymentState().equals("1") ? "未付款" : "已付款";
		}
		return "";
	}

	/**
	 * 上线初始化满减表
	 * 
	 * @param mainShowId
	 * @return
	 * @throws Exception
	 */
	public int initialize(String mainShowId) throws Exception {
		Set<String> set = getDiscountChildShowCode(mainShowId);// 所有参与优惠的子犬展
		if (set.size() == 0) {// 没有设置满减优惠
			throw new ZAException(ZAErrorCode.ZA_VALID_FAILED, "该主犬展下子犬展没有设置满减优惠！");
		}
		List<ShowApply> list = dao.findInitializeList(mainShowId);
		int a = 0;
		for (ShowApply showApply : list) {
			// 是否满足进入满减周期的条件
			boolean isCycleSign = isCycleSign(showApply);
			if (isCycleSign) {
				saveNewRecord(showApply);
				a++;
			}
		}
		return a;

	}

	public boolean isCycleSign(ShowApply showApply) throws Exception {
		String[] showCodes = showApply.getShowCode().split(",");
		Set<String> showCodeSet = new HashSet<>();
		Collections.addAll(showCodeSet, showCodes);
		String[] ageGroups = showApply.getAgeGroup().split(",");

		Set<String> set = getDiscountChildShowCode(showApply.getMainShowId());// 所有参与优惠的子犬展
		if (set.size() == 0) {// 没有设置满减优惠
			return false;
		}
		if (!showCodeSet.containsAll(set)) {// 每只犬需报名满所有参与优惠的场次
			return false;
		}
		for (String a : ageGroups) {// 参赛犬只报名组别，特幼公、特幼母、幼小公、幼小母不参与优惠；
			if (Integer.valueOf(a) < 5) {
				return false;
			}
		}
		Dog dog = dogService.getByPedigreeCertifiedCode(showApply.getPedigreeCertified());
		if (!checkDogOwnerChange(dog.getId())) {// 进行过犬主变更则不参加满减
			return false;
		}

		return true;// 提前全部通过 则进入周期计数
	}

}