package com.ifish.serviceImpl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.ifish.dao.GradeControlDao;
import com.ifish.dao.GradeDao;
import com.ifish.dao.GradeRecordDao;
import com.ifish.dao.GradeRuleDao;
import com.ifish.dao.UserAssetDao;
import com.ifish.dto.JsonResult;
import com.ifish.dto.PageingDto;
import com.ifish.dto.RuleInfoDto;
import com.ifish.dto.RuleRecordDto;
import com.ifish.dto.UserAssetDto;
import com.ifish.entity.GradeControl;
import com.ifish.entity.GradeControlId;
import com.ifish.entity.GradeRecord;
import com.ifish.entity.GradeTask;
import com.ifish.entity.UserAsset;
import com.ifish.enums.AddTypeEnum;
import com.ifish.enums.BooleanEnum;
import com.ifish.enums.GradeGetTypeEnum;
import com.ifish.enums.ResultEnum;
import com.ifish.exception.IfishException;
import com.ifish.hibernate.Pagination;
import com.ifish.service.AsyncTaskService;
import com.ifish.service.CacheService;
import com.ifish.service.GoldService;
import com.ifish.service.GradeService;
import com.ifish.util.IfishUtil;
import com.ifish.validator.AddValueParam;
import com.ifish.validator.PageParam;

/**
 * 等级service
 * @author Administrator
 *
 */
@Service
@Transactional
public class GradeServicempl implements GradeService{

	@Autowired
	private GradeDao gradeDao;
	@Autowired
	private GradeRuleDao gradeRuleDao;
	@Autowired
	private GradeRecordDao gradeRecordDao;
	@Autowired
	private GradeControlDao gradeControlDao;
	@Autowired
	private GradeControlDao GradeControlDao;
	@Autowired
	private UserAssetDao userAssetDao;
	@Autowired
	private CacheService cacheService;
	@Autowired
	private GoldService goldService;
	@Autowired
	private AsyncTaskService asyncTaskService;
	
	/**
	 * 是否加过经验
	 */
	@Override
	public UserAssetDto getGradeControl(UserAsset userAsset, GradeTask gradeRule,boolean isLogin){
		Integer userId = userAsset.getUserId();
		String ruleType = gradeRule.getRuleType();
		//日期
		Calendar calendar = Calendar.getInstance();
		//今天
		Date date = calendar.getTime();
		String today = IfishUtil.format1(date);
		//昨天
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		String yesterday = IfishUtil.format1(calendar.getTime());
		//控制信息
		GradeControlId id = new GradeControlId(userId, ruleType);
		GradeControl control = gradeControlDao.get(id);
		//加成类型
		String addType = gradeRule.getAddType();
		if(control==null){
			//加成一次或每天加成
			if(addType.equals(AddTypeEnum.once.getKey()) || addType.equals(AddTypeEnum.everyDay.getKey())){
				//新增控制今天加过经验
				control = new GradeControl(id, today, date);
				gradeControlDao.save(control);
				//加经验
				return addGradeValue(userAsset, gradeRule, today, yesterday, isLogin);
			}
		}
		else{
			//每天加成并且今天未加过经验
			if(addType.equals(AddTypeEnum.everyDay.getKey()) && !control.getControlParam().equals(today)){
				//更新今天加过
				control.setControlParam(today);
				control.setUpdateTime(date);
				//加经验
				return addGradeValue(userAsset, gradeRule, today, yesterday, isLogin);
			}
		}
		return goldService.getUserAssetInfo(userAsset, new BigDecimal(0), today, yesterday);
	}
	/**
	 * 加经验并保存记录
	 * @param userAsset
	 * @param GradeTask
	 * @param today
	 * @param yesterday
	 * @return
	 */
	public UserAssetDto addGradeValue(UserAsset userAsset,GradeTask gradeRule,String today,String yesterday,boolean isLogin){
		Integer userId = userAsset.getUserId();
		String ruleType = gradeRule.getRuleType();
		//用户经验
		Integer gradeValue = userAsset.getGradeValue();
		//加经验值
		Integer addValue = gradeRule.getAddValue();
		//加经验
		gradeValue += addValue;
		userAsset.setGradeValue(gradeValue);
		//登陆则保存登陆日期
		if(isLogin){
			userAsset.setLastLoginDate(today);
		}
		//加经验值记录
		GradeRecord gradeRecord = new GradeRecord(userId, ruleType, addValue, gradeRule.getRuleRemark());
		gradeRecordDao.save(gradeRecord);
		//用户动态
		asyncTaskService.saveUserActivity(userId, ruleType);
		return goldService.getUserAssetInfo(userAsset, new BigDecimal(addValue), today, yesterday);
	}

	/**
	 * 根据类型加经验
	 */
	@Override
	public JsonResult<?> addGradeValue(AddValueParam addValueParam) {
		//用户ID
		UserAsset userAsset = userAssetDao.get(addValueParam.getUserId());
		if(userAsset==null){
			throw new IfishException(ResultEnum.error402);
		}
		//规则类型
		GradeTask gradeRule = cacheService.getGradeRule(addValueParam.getRuleType());
		//不存在和未返回给app的以及登陆的(在登陆时处理)
		if(gradeRule==null || !gradeRule.getState().equals(BooleanEnum.YES.getKey()) || gradeRule.getRuleType().equals(GradeGetTypeEnum.everyDayLogin.getKey())){
			throw new IfishException(ResultEnum.error402);
		}
		return new JsonResult<UserAssetDto>(ResultEnum.success.getKey(), getGradeControl(userAsset, gradeRule, false));
	}

	@Override
	public PageingDto<?> getGradeRecordByPage(PageParam pageParam) {
		Integer firstResult = pageParam.getFirstResult();
		//根据ID查询获取经验记录
		Pagination<GradeRecord> page = gradeRecordDao.findByCriteria(firstResult, pageParam.getPageSize(), Order.desc("recordId"),Restrictions.eq("userId", pageParam.getUserId()));
		List<GradeRecord> gradeRecordList = page.getList();
		firstResult+=gradeRecordList.size();
		//数据封装
		List<RuleRecordDto> recordList = new ArrayList<RuleRecordDto>();
		for (GradeRecord record : gradeRecordList) {
				RuleRecordDto recordDto = new RuleRecordDto(record.getRecordId(), record.getAddValue().toString(), record.getRecordRemark(), IfishUtil.format1(record.getCreateTime()));
				recordList.add(recordDto);
		}
		//分页数据封装
		PageingDto<RuleRecordDto> pageingData = new PageingDto<RuleRecordDto>(ResultEnum.success.getKey(), firstResult, page.getTotalCount(), recordList);
		return pageingData;
	}

	@Override
	public JsonResult<?> getGradeRuleInfo(Integer userId) {
		//今天日期
		String today = IfishUtil.format1(new Date());
		//已完成任务规则
		List<GradeControl> gradeControls = gradeControlDao.findByProperty(Restrictions.eq("gradeControlId.userId", userId),Restrictions.eq("controlParam", today));
		Map<String, String> finishTask = new HashMap<String, String>();
		for (GradeControl gradeControl : gradeControls) {
			finishTask.put(gradeControl.getGradeControlId().getRuleType(), gradeControl.getControlParam());
		}
		//规则信息
		List<RuleInfoDto> ruleInfoList = new ArrayList<RuleInfoDto>();
		//所有任务规则
		for (GradeTask gradeRule : cacheService.getGradeRuleList()) {
			//类型
			String ruleType = gradeRule.getRuleType();
			//加成类型
			String addType = gradeRule.getAddType();
			//规则信息DTO
			RuleInfoDto ruleInfoDto = new RuleInfoDto(ruleType, gradeRule.getRuleName(), addType, gradeRule.getAddValue().toString(), gradeRule.getRuleRemark(), BooleanEnum.NO.getKey());
			ruleInfoList.add(ruleInfoDto);
			//任务是否完成
			String controlDate = finishTask.get(ruleType);
			if(controlDate!=null){
				if(addType.equals(AddTypeEnum.once.getKey()) || (addType.equals(AddTypeEnum.everyDay.getKey()) && controlDate.equals(today))){
					ruleInfoDto.setIsFinish(BooleanEnum.YES.getKey());
				}
			}
		}
		JSONObject json = new JSONObject();
		//规则信息
		json.put("gradeRules", ruleInfoList);
		//等级信息
		json.put("grades", cacheService.getGradeList());
		return new JsonResult<JSONObject>(ResultEnum.success.getKey(), json);
	}

}
