package com.yonyou.hrcloud.pm.base.impl;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.yonyou.hrcloud.adder.model.query.Operator;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yonyou.hrcloud.adder.context.AppContext;
import com.yonyou.hrcloud.adder.exception.AdderBusinessException;
import com.yonyou.hrcloud.adder.model.param.PagerRequest;
import com.yonyou.hrcloud.adder.model.param.Sorter;
import com.yonyou.hrcloud.adder.model.query.Condition;
import com.yonyou.hrcloud.berry.helper.DateUtil;
import com.yonyou.hrcloud.pm.base.dao.IBaseDao;
import com.yonyou.hrcloud.pm.base.model.Period;
import com.yonyou.hrcloud.pm.base.service.IPeriodService;
import com.yonyou.hrcloud.pm.common.model.CommonValue;
import com.yonyou.hrcloud.pm.common.model.CommonValue.EnumPeriodType;
import com.yonyou.hrcloud.pm.helper.ListHelper;
import com.yonyou.hrcloud.pm.ps.model.Scheme;



/**
 * 绩效周期实现层
 * 
 * @author Flysea
 *
 */
@Service
@Transactional
public class PeriodServiceImpl implements IPeriodService {

	@Resource
	public com.yonyou.hrcloud.adder.service.IGenericService daoex;

	@Resource
	IBaseDao dao;

	@Override
	@Transactional(readOnly = true)
	public List<Period> queryPeriodByConditon(Condition cond, Sorter sort) {
		List<Period> objs = daoex.find(Period.class, cond, sort);
		for (Period obj : objs) {
			obj.setPeriodtypename(CommonValue.EnumPeriodType.values()[obj.getPeriodtype()].getDescription());
		}
		return objs;
	}

	@Override
	public List<Period> queryPeriodList(Boolean isEnable, Integer year) {
		Condition condObj = null;
		if (isEnable != null) {
			condObj = new Condition();
			condObj.addExpression("enablestate", isEnable);
		}
		if (year != null) {
			if (condObj == null)
				condObj = new Condition();
			condObj.addExpression("year", year);
		}
		Sorter sortObj = new Sorter(Direction.DESC, Arrays.asList("year"));
		Sorter sortObj2 = new Sorter(Direction.ASC, Arrays.asList("periodtype", "periodcode"));
		sortObj = sortObj.and(sortObj2);
		List<Period> objs = queryPeriodByConditon(condObj, sortObj);
		return objs;
	}

	@Override
	public List<Period> queryPeriodList(Boolean isEnable, List<Integer> years) {
		Condition condObj = null;
		if (isEnable != null) {
			condObj = new Condition();
			condObj.addExpression("enablestate", isEnable);
		}
		if (CollectionUtils.isNotEmpty(years)) {
			if (condObj == null)
				condObj = new Condition();
			condObj.addExpression("year", years, Operator.IN);
		}
		Sorter sortObj = new Sorter(Direction.DESC, Arrays.asList("year"));
		Sorter sortObj2 = new Sorter(Direction.ASC, Arrays.asList("periodtype", "periodcode"));
		sortObj = sortObj.and(sortObj2);
		List<Period> objs = queryPeriodByConditon(condObj, sortObj);
		return objs;
	}

	@Override
	@Transactional(readOnly = true)
	public Period queryPeriodByID(String id) {
		Period obj = daoex.load(Period.class, id);
		if (obj != null) {
			obj.setPeriodtypename(CommonValue.EnumPeriodType.values()[obj.getPeriodtype()].name());
			return obj;
		} else
			return null;
	}

	@Override
	public void insert(Period period) {
		daoex.insert(period);
	}

	@Override
	public void update(Period period) {
		// 只能更新启用、开始截止日期
		daoex.update(period);
	}

	@Override
	public void delete(String id) {
		// 方案使用了不能删除
		Condition condObj = new Condition();
		condObj.addExpression("periodid", id);
		Pageable page = new PagerRequest(0, 1);
		List<Scheme> schemeList = daoex.findPage(Scheme.class, condObj, page).getContent();
		if (CollectionUtils.isEmpty(schemeList)) {
			List<Integer> objs = dao.queryPeriodUsed(id);
			if (CollectionUtils.isEmpty(objs))
				daoex.delete(Period.class, id);
			else
				throw new AdderBusinessException("绩效期间已被目标使用", "pm.i18n_core.base.023");
		} else
			throw new AdderBusinessException("绩效期间已被方案使用", "pm.i18n_core.base.012");
	}

	@Override
	public List<Integer> queryPeriodYear() {
		Condition condObj = new Condition();
		condObj.addExpression("tenantid", AppContext.getContext().getScope());
		Sorter sortObj = new Sorter(Direction.DESC, "year");
		return dao.queryPeriodYear(condObj, sortObj);
	}

	@Override
	public void createPeriod(Map<String, String> period) {
		String stryear = period.get("year");
		String halfyear = period.get("halfyear");
		String season = period.get("season");
		String month = period.get("month");
		if (StringUtils.isEmpty(stryear) || StringUtils.isEmpty(halfyear) || StringUtils.isEmpty(season)
				|| StringUtils.isEmpty(month))
			throw new AdderBusinessException("参数不能为空", "pm.i18n_core.comm.002");
		int year = Integer.parseInt(stryear);
		List<Integer> yearList = queryNewPeriodYear();
		if (!yearList.contains(year))
			throw new AdderBusinessException("数据不正确", "pm.i18n_core.comm.003");
		List<Period> oldPeriodList = queryPeriodList(null, year);
		// 存在此年度的周期则增加时跳过
		// Map<String, String> oldPeriodMap = oldPeriodList.stream()
		// .collect(Collectors.toMap(Period::getPeriodcode, Period::getId));
		Map<String, String> oldPeriodMap = ListHelper.toMap(oldPeriodList, "getPeriodcode", "getId");
		List<Period> periodList = new ArrayList<Period>();
		if (stryear.length() > 0) {
			Period p = new Period();
			p.setPeriodcode(stryear);
			if (!oldPeriodMap.containsKey(p.getPeriodcode())) {
				p.setPeriodname(stryear + "年");
				p.setPeriodtype(EnumPeriodType.year.getIndex());
				p.setYear(year);
				p.setEnablestate(true);
				Date[] dates = getfdateAndtDate(Integer.parseInt(stryear), null, null, null);
				p.setFdate(dates[0]);
				p.setTdate(dates[1]);
				periodList.add(p);
			}
		}
		if (halfyear.equals("1")) {
			for (int i = 1; i <= 2; i++) {
				Period p = new Period();
				p.setPeriodcode(stryear + String.valueOf(i));
				if (!oldPeriodMap.containsKey(p.getPeriodcode())) {
					if (i == 1)
						p.setPeriodname(stryear + "年上半年");
					else
						p.setPeriodname(stryear + "年下半年");
					p.setPeriodtype(EnumPeriodType.halfyear.getIndex());
					p.setYear(year);
					p.setHalfyear(String.valueOf(i));
					p.setEnablestate(true);
					Date[] dates = getfdateAndtDate(Integer.parseInt(stryear), i, null, null);
					p.setFdate(dates[0]);
					p.setTdate(dates[1]);
					periodList.add(p);
				}
			}
		}
		if (season.equals("1")) {
			for (int i = 1; i <= 4; i++) {
				Period p = new Period();
				String half = "1";
				if (i > 2)
					half = "2";
				p.setPeriodcode(stryear + half + String.valueOf(i));
				if (!oldPeriodMap.containsKey(p.getPeriodcode())) {
					p.setPeriodname(stryear + "年" + i + "季");
					p.setPeriodtype(EnumPeriodType.season.getIndex());
					p.setYear(year);
					p.setHalfyear(half);
					p.setSeason(String.valueOf(i));
					p.setEnablestate(true);
					Date[] dates = getfdateAndtDate(Integer.parseInt(stryear), null, i, null);
					p.setFdate(dates[0]);
					p.setTdate(dates[1]);
					periodList.add(p);
				}
			}
		}
		if (month.equals("1")) {
			for (int i = 1; i <= 12; i++) {
				Period p = new Period();
				String half = "1";
				String s = "1";
				String m = "0";
				if (i > 6)
					half = "2";
				// 将月份转为第几季
				s = String.valueOf((int) ((i - 1) / 3) + 1);
				if (i >= 10)
					m = "";
				p.setPeriodcode(stryear + half + s + m + String.valueOf(i));
				if (!oldPeriodMap.containsKey(p.getPeriodcode())) {
					p.setPeriodname(stryear + "年" + i + "月");
					p.setPeriodtype(EnumPeriodType.month.getIndex());
					p.setYear(year);
					p.setHalfyear(half);
					p.setSeason(s);
					p.setMonth(m + String.valueOf(i));
					p.setEnablestate(true);
					Date[] dates = getfdateAndtDate(Integer.parseInt(stryear), null, null, i);
					p.setFdate(dates[0]);
					p.setTdate(dates[1]);
					periodList.add(p);
				}
			}
		}
		if (!periodList.isEmpty())
			daoex.insertBatch(periodList);
	}

	@Override
	public List<Integer> queryNewPeriodYear() {
		List<Integer> yearList = queryPeriodYear();
		Calendar c = Calendar.getInstance();
		int year = c.get(Calendar.YEAR);
		if (yearList.isEmpty()) {
			yearList.add(year - 1);
			yearList.add(year);
			yearList.add(year + 1);
		} else {
//			if (!yearList.contains(year - 1))
//				yearList.add(year - 1);
//			if (!yearList.contains(year))
//				yearList.add(year);
//			if (!yearList.contains(year + 1))
//				yearList.add(year + 1);
			
			for(int i = 2017;i < year + 1; i++) {
				if (!yearList.contains(i))
					yearList.add(i);
			}
		}
		Collections.sort(yearList);
		Collections.reverse(yearList);
		return yearList;
	}
	
	/**
	 * 获取默认起止日期
	 * @param year
	 * @param halfyear
	 * @param season
	 * @param month
	 * @return
	 */
	public Date[] getfdateAndtDate(Integer year,Integer halfyear,Integer season,Integer month) {		
		Date fLocalDate= null;//开始日期
		Date tLocalDate = null;//结束日期	
		//获取年的起止日期
		fLocalDate = DateUtil.getMonthStart(year+"", "1");
		tLocalDate = DateUtil.getMonthEnd(year+"", "12");
		//获取半年的起止日期
		if(halfyear!=null) {
			if (halfyear == 1) {
				fLocalDate = DateUtil.getMonthStart(year+"", "1");
				tLocalDate = DateUtil.getMonthEnd(year+"", "6");
			}else {
				fLocalDate = DateUtil.getMonthStart(year+"", "7");
				tLocalDate = DateUtil.getMonthEnd(year+"", "12");
			}			
		}
		//获取季度的起止日期
		if(season!=null) {
			if (season == 1) {
				fLocalDate = DateUtil.getMonthStart(year+"", "1");
				tLocalDate = DateUtil.getMonthEnd(year+"", "3");
			}else if(season == 2) {
				fLocalDate = DateUtil.getMonthStart(year+"", "4");
				tLocalDate = DateUtil.getMonthEnd(year+"", "6");
			}else if(season == 3) {
				fLocalDate = DateUtil.getMonthStart(year+"", "7");
				tLocalDate = DateUtil.getMonthEnd(year+"", "9");
			}else {
				fLocalDate = DateUtil.getMonthStart(year+"", "10");
				tLocalDate = DateUtil.getMonthEnd(year+"", "12");
			}
		}
		//获取月份的起止日期
		if(month!=null) {
			fLocalDate = DateUtil.getMonthStart(year+"", month+"");
			tLocalDate = DateUtil.getMonthEnd(year+"", month+"");
		}
		return new Date[] {fLocalDate,tLocalDate};
	}
}
