package com.goafanti.achievement.service.impl;

import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.goafanti.achievement.bo.AchievementOrderListBo;
import com.goafanti.achievement.bo.OrgAchievementOrderListBo;
import com.goafanti.achievement.bo.UserAchievementOrderListBo;
import com.goafanti.achievement.service.AchievementOrderService;
import com.goafanti.common.constant.AFTConstants;
import com.goafanti.common.dao.AchievementOrderLogMapper;
import com.goafanti.common.dao.AchievementOrderMapper;
import com.goafanti.common.enums.AchievementOrderStatus;
import com.goafanti.common.enums.DeleteStatus;
import com.goafanti.common.model.AchievementOrder;
import com.goafanti.common.model.AchievementOrderLog;
import com.goafanti.core.mybatis.BaseMybatisDao;
import com.goafanti.core.mybatis.page.Pagination;
import com.goafanti.core.shiro.token.TokenManager;

@Service
public class AchievementOrderServiceImpl extends BaseMybatisDao<AchievementOrderMapper>
		implements AchievementOrderService {
	@Autowired
	private AchievementOrderMapper		achievementOrderMapper;
	@Autowired
	private AchievementOrderLogMapper	achievementOrderLogMapper;

	@Override
	public List<AchievementOrder> selectAchievementOrderByUidAndAchievementId(String uid, String achievementId) {
		return achievementOrderMapper.selectAchievementOrderByUidAndAchievementId(uid, achievementId);
	}

	@Override
	public void saveAchievementOrder(AchievementOrder ao, AchievementOrderLog aol) {
		ao.setId(UUID.randomUUID().toString());
		ao.setDeletedSign(DeleteStatus.UNDELETE.getCode());
		Calendar now = Calendar.getInstance();
		now.set(Calendar.MILLISECOND, 0);
		ao.setCreateTime(now.getTime());
		ao.setStatus(AchievementOrderStatus.UNPAYED.getCode());
		ao.setUid(TokenManager.getUserId());
		if (StringUtils.isBlank(ao.getUid())) {
			return;
		}
		achievementOrderMapper.insert(ao);

		aol.setId(UUID.randomUUID().toString());
		aol.setAchievementOrderId(ao.getId());
		aol.setRecordTime(ao.getCreateTime());
		aol.setStatus(ao.getStatus());
		achievementOrderLogMapper.insert(aol);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<AchievementOrderListBo> listOrderList(Integer status, Integer pNo, Integer pSize) {

		if (pNo == null || pNo < 0) {
			pNo = 1;
		}

		if (pSize == null || pSize < 0 || pSize > 10) {
			pSize = 10;
		}
		return (Pagination<AchievementOrderListBo>) findPage("findAchievementOrderListByPage",
				"findAchievementOrderCount", disposeAchievementOrder(null, null, null, status, false), pNo, pSize);
	}

	@Override
	public AchievementOrder selectByPrimaryKey(String id) {
		return achievementOrderMapper.selectByPrimaryKey(id);
	}

	@Override
	public int updateShutdownByUser(AchievementOrder order) {
		order.setStatus(AchievementOrderStatus.CANCELLED.getCode());

		AchievementOrderLog aol = new AchievementOrderLog();
		aol.setId(UUID.randomUUID().toString());
		aol.setStatus(AchievementOrderStatus.CANCELLED.getCode());
		aol.setAchievementOrderId(order.getId());
		Calendar now = Calendar.getInstance();
		now.set(Calendar.MILLISECOND, 0);
		aol.setRecordTime(now.getTime());
		achievementOrderLogMapper.insert(aol);
		return achievementOrderMapper.updateByPrimaryKeySelective(order);
	}

	@Override
	public List<AchievementOrder> selectAchievementOrderByAchievementId(String achievementId) {
		return achievementOrderMapper.selectAchievementOrderByAchievementId(achievementId);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<UserAchievementOrderListBo> listUserAchievementOrder(String uid, String username, Integer status,
			Integer pNo, Integer pSize) {
		if (pNo == null || pNo < 0) {
			pNo = 1;
		}

		if (pSize == null || pSize < 0 || pSize > 10) {
			pSize = 10;
		}
		return (Pagination<UserAchievementOrderListBo>) findPage("findUserAchievementOrderListByPage",
				"findUserAchievementOrderCount", disposeAchievementOrder(uid, username, null, status, true), pNo,
				pSize);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<OrgAchievementOrderListBo> listOrgAchievementOrder(String uid, String unitName, Integer status,
			Integer pNo, Integer pSize) {
		if (pNo == null || pNo < 0) {
			pNo = 1;
		}

		if (pSize == null || pSize < 0 || pSize > 10) {
			pSize = 10;
		}
		return (Pagination<OrgAchievementOrderListBo>) findPage("findOrgAchievementOrderListByPage",
				"findOrgAchievementOrderCount", disposeAchievementOrder(uid, null, unitName, status, true), pNo, pSize);
	}

	@Override
	public int updateAchievementOrder(AchievementOrder achievementOrder, AchievementOrderLog aol,
			String recordTimeFormattedDate) {
		if (!StringUtils.isBlank(recordTimeFormattedDate)) {
			aol.setId(UUID.randomUUID().toString());
			aol.setOperator(TokenManager.getAdminId());
			aol.setAchievementOrderId(achievementOrder.getId());
			Date recordTime = null;
			try {
				recordTime = DateUtils.parseDate(recordTimeFormattedDate, AFTConstants.YYYYMMDDHHMMSS);
			} catch (ParseException e) {
			}
			aol.setRecordTime(recordTime);
			achievementOrderLogMapper.insert(aol);
			if (AchievementOrderStatus.PAYED == AchievementOrderStatus.getStatus(achievementOrder.getStatus())) {
				achievementOrder.setPaymentTime(recordTime);
			}
		}
		return achievementOrderMapper.updateByPrimaryKeySelective(achievementOrder);
	}

	private Map<String, Object> disposeAchievementOrder(String uid, String username, String unitName, Integer status,
			Boolean flag) {
		Map<String, Object> params = new HashMap<>();

		if (null != status) {
			params.put("status", status);
		}

		if (!StringUtils.isBlank(unitName)) {
			params.put("unitName", unitName);
		}

		if (!StringUtils.isBlank(username)) {
			params.put("username", username);
		}

		if (!StringUtils.isBlank(uid)) {
			params.put("uid", uid);
		}

		if (flag) {
			if (!TokenManager.hasRole(AFTConstants.SUPERADMIN)) {
				params.put("techBrokerId", TokenManager.getAdminId());
			}
		} else {
			params.put("uid", TokenManager.getUserId());
		}

		return params;
	}

}
