package com.house365.ws.interfaces.rest;

import com.google.common.base.Strings;
import com.house365.beans.entity.CmCreditRuleEntity;
import com.house365.beans.entity.CmUserEntity;
import com.house365.beans.system.QueryParams;
import com.house365.rest.context.CmConstant;
import com.house365.rest.context.Parameter;
import com.house365.rest.exception.ServiceRunException;
import com.house365.web.util.DateTimeUtils;
import com.house365.web.util.MemoryPropertyPlaceholderConfigurer;
import com.house365.ws.service.interfaces.ICmCreditRuleService;
import com.house365.ws.service.interfaces.ICmUserService;
import com.house365.ws.system.ReturnAppResult;
import com.house365.ws.util.CmCommonUtils;
import com.house365.ws.util.DateUtils;
import com.house365.ws.util.UserCreditTaskVO;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Transaction;

import java.math.BigDecimal;
import java.util.*;

import static com.house365.rest.context.CmConstant.*;

/**
 * <p>Title: 获取用户积分任务信息</p>
 * <p>Description: </p>
 * <p>Date: 2017/3/29</p>
 *
 * @author XN
 * @version 1.0
 */

@Component("userCreditTask")
public class UserCreditTaskImpl implements IUserCreditTask {

    private static final Logger LOGGER = LoggerFactory.getLogger("InterfaceLog");

    @Autowired
    private ICmUserService<CmUserEntity> iCmUserService;

    @Autowired
    private ICmCreditRuleService cmCreditRuleService;


    @Override
    public Object exectue(Parameter parameter) throws ServiceRunException {

        // 取得所需参数
        Map<String, Object> map = parameter.getArgs();
        Map<String, Object> resultMap = new HashMap<>(10);
        // 业务层统一处理
        try {
            if (!map.containsKey(CmConstant.USERID)) {
                resultMap.put("result", ReturnAppResult.APP_FAIL.getResultCode());
                resultMap.put("msg", "用户中心用户不存在!");
                return JSONObject.fromObject(resultMap).toString();
            }

            String userIdStr = ((String[]) map.get(CmConstant.USERID))[0];

            if (Strings.isNullOrEmpty(userIdStr)) {
                resultMap.put("result", ReturnAppResult.APP_FAIL.getResultCode());
                resultMap.put("msg", "用户中心用户不存在!");
                return JSONObject.fromObject(resultMap).toString();
            }

            String host = MemoryPropertyPlaceholderConfigurer.getContextProperty("redis.host");
            if (!Strings.isNullOrEmpty(host)) {
                final String key = userIdStr + ":userCreditTask";
                JedisPoolConfig config = new JedisPoolConfig();
                config.setMaxTotal(50);
                config.setMaxIdle(5);
                config.setMinIdle(1);
                JedisPool pool = new JedisPool(config, host);
                try (Jedis jedis = pool.getResource()) {
                    String current = jedis.get(key);
                    if (!Strings.isNullOrEmpty(current) && com.house365.web.util.StringUtils.isNumeric(
                            current) && (Integer.parseInt(current)) >= 5) {
                        LOGGER.warn("请求过于频繁，请稍后再试! [{}]", key);
                        resultMap.put("result", ReturnAppResult.APP_FAIL.getResultCode());
                        resultMap.put("msg", "请求过于频繁，请稍后再试!!");
                        return JSONObject.fromObject(resultMap).toString();
                    } else {
                        Transaction t = jedis.multi();
                        t.incr(key);
                        t.expire(key, 2);
                        t.exec();
                    }
                } finally {
                    pool.close();
                }
            } else {
                LOGGER.warn("can not get redis host !");
            }

            CmUserEntity cmUser = null;
            Map<String, Object> param = new HashMap<>();
            param.put("EQ_userId", userIdStr);
            QueryParams<CmUserEntity> queryParamUser = new QueryParams<>();
            queryParamUser.setSearchParams(param);
            List<CmUserEntity> cmUserList = iCmUserService.queryAll(queryParamUser);
            if (!cmUserList.isEmpty()) {
                cmUser = cmUserList.get(0);
            } else {
                resultMap.put("result", ReturnAppResult.APP_FAIL.getResultCode());
                resultMap.put("msg", "用户中心用户不存在!");
                return JSONObject.fromObject(resultMap).toString();
            }

            if (cmUser == null) {
                resultMap.put("result", ReturnAppResult.APP_FAIL.getResultCode());
                resultMap.put("msg", "用户中心用户不存在!");
                return JSONObject.fromObject(resultMap).toString();
            }

            List<CmCreditRuleEntity> ruleList = cmCreditRuleService.queryAll();
            System.out.println("*****ruleList**********" + ruleList);
            CmCreditRuleEntity rule = null;
            for (CmCreditRuleEntity ruleEntity : ruleList) {
                if (CREDITS_RULE_SIGN == ruleEntity.getId()) {
                    rule = ruleEntity;
                }
            }

            UserCreditTaskVO userCreditTaskVO = new UserCreditTaskVO();
            userCreditTaskVO.setUser_id(cmUser.getUserId());

            if (cmUser.getLastSignTime() == null) {
                cmUser.setIsSignedToday(0);
                cmUser.setContinuousSignCount(0);
            } else {
                boolean isSignedToday = DateUtils.isSameDay(new Date(), cmUser.getLastSignTime());
                if (isSignedToday) {
                    cmUser.setIsSignedToday(1);
                } else {
                    cmUser.setIsSignedToday(0);
                }
                //昨天是否签到，如果没有则连续签到为0
                int count = DateUtils.daysBetween(DateUtils.parseDate(cmUser.getLastSignTime(), "yyyy-MM-dd"),
                        DateUtils.parseDate(new Date(), "yyyy-MM-dd"));
                if (count > 1) {
                    cmUser.setContinuousSignCount(0);
                }
            }

            userCreditTaskVO.setContinueSignTime(cmUser.getContinuousSignCount());
            getUserCredit(cmUser, rule, userCreditTaskVO);
            Map info = iCmUserService.getUserCreditTask(cmUser.getUserId());
            List<UserCreditTaskVO.CreditVO> voList = new ArrayList<>();
            for (CmCreditRuleEntity creditRule : ruleList) {
                UserCreditTaskVO.CreditVO creditVO = userCreditTaskVO.new CreditVO();
                creditVO.setCountCircle(creditRule.getCountCircle());

                creditVO.setCredits(creditRule.getCredits());
                if (CREDITS_RULE_SIGN == creditRule.getId()){
                    creditVO.setCredits(userCreditTaskVO.getCanGetSignCreditToday());
                }

                creditVO.setCountLimit(creditRule.getCountLimit());

                switch (creditRule.getId()) {
                    case CREDITS_RULE_SIGN:
                        int done = ((BigDecimal) info.get("todaysign")).intValue();
                        creditVO.setDoneTime(done);
                        if (creditRule.getCountLimit() <= done) {
                            creditVO.setDisplay("0");
                        } else {
                            creditVO.setDisplay("1");
                        }
                        break;
                    case CREDITS_RULE_HOUSE_COMMENT:
                        int done1 = ((BigDecimal) info.get("commenttime")).intValue();
                        creditVO.setDoneTime(done1);
                        if (creditRule.getCountLimit() <= done1) {
                            creditVO.setDisplay("0");
                        } else {
                            creditVO.setDisplay("1");
                        }
                        break;
                    case CREDITS_RULE_INVITE_USER:
                        int done2 = ((BigDecimal) info.get("invitetime")).intValue();
                        creditVO.setDoneTime(done2);
                        creditVO.setDisplay("1");
                        break;
                    case CREDITS_RULE_POST:
                        int done3 = ((BigDecimal) info.get("posttime")).intValue();
                        creditVO.setDoneTime(done3);
                        if (creditRule.getCountLimit() <= done3) {
                            creditVO.setDisplay("0");
                        } else {
                            creditVO.setDisplay("1");
                        }
                        break;
                    case CREDITS_RULE_UPLOAD_PHOTO:
                        int done4 = ((BigDecimal) info.get("image")).intValue();
                        creditVO.setDoneTime(done4);
                        if (creditRule.getCountLimit() <= done4) {
                            creditVO.setDisplay("0");
                        } else {
                            creditVO.setDisplay("1");
                        }
                        break;
                    case CREDITS_RULE_QUESTION:
                        int done5 = ((BigDecimal) info.get("quest")).intValue();
                        creditVO.setDoneTime(done5);
                        if (creditRule.getCountLimit() <= done5) {
                            creditVO.setDisplay("0");
                        } else {
                            creditVO.setDisplay("1");
                        }
                        break;
                    default:
                        break;
                }

                creditVO.setRule_id(creditRule.getId());
                creditVO.setRule_name(creditRule.getCreditRuleName());
                voList.add(creditVO);
            }
            //只返回指定ID的积分规则
            if (map.containsKey("ruleId")) {
                String ruleId = ((String[]) map.get("ruleId"))[0];
                for (Iterator<UserCreditTaskVO.CreditVO> iter = voList.iterator(); iter.hasNext(); ) {
                    UserCreditTaskVO.CreditVO item = iter.next();
                    if (!ruleId.equalsIgnoreCase(String.valueOf(item.getRule_id()))) {
                        iter.remove();
                    }
                }

            }
            //屏蔽社区发帖/回帖
            for (int i = 0; i < voList.size(); i++) {
                Integer ruleId = voList.get(i).getRule_id();
                if (16 == ruleId) {
                    voList.remove(i);
                    break;
                }
            }
            userCreditTaskVO.setCreditList(voList);

            resultMap.put("data", userCreditTaskVO);
            resultMap.put("result", ReturnAppResult.APP_SUCCESS.getResultCode());
            resultMap.put("msg", "");

        } catch (Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            resultMap.put("result", ReturnAppResult.APP_FAIL.getResultCode());
            resultMap.put("msg", "获取信息失败!");
        }

        return JSONObject.fromObject(resultMap).toString();
    }

    //set can get credit today and tommrrow
    private void getUserCredit(CmUserEntity cmUser, CmCreditRuleEntity rule, UserCreditTaskVO userCreditTaskVO) {
        //活动加权
        boolean inActive = false;
        Date now = new Date();
        Date startDate = null;
        Date endDate = null;
        if (rule.getActiveStartTime() != null) {
            startDate = rule.getActiveStartTime();
        }
        if (rule.getActiveEndTime() != null) {
            endDate = rule.getActiveEndTime();
        }

        if (startDate != null && endDate != null && now.compareTo(startDate) >= 0 && now.compareTo(endDate) <= 0) {
            inActive = true;
        } else if (startDate != null && endDate == null && now.compareTo(startDate) >= 0) {
            inActive = true;
        } else if (endDate != null && startDate == null && now.compareTo(endDate) <= 0) {
            inActive = true;
        }

        //目前只计算整数
        if (inActive) {
            rule.setCredits(rule.getCredits() * rule.getActiveWeight().intValue());
        }

        //获取今日的签到积分
        Integer continueSignCount = cmUser.getContinuousSignCount() == null ? 0 : cmUser.getContinuousSignCount();
        if (DateUtils.isSameDay(new Date(), cmUser.getLastSignTime())) {
            cmUser.setTodaySignedCredits(
                    CmCommonUtils.getSignCreditsByContinuousSignCount(continueSignCount) + rule.getCredits());
        } else {
            cmUser.setTodaySignedCredits(0);
        }

        Integer canGetSignCreditToday;
        Integer canGetSignCreditTomorrow;
        if (DateUtils.isSameDay(new Date(), cmUser.getLastSignTime())) {
            canGetSignCreditToday = CmCommonUtils.getSignCreditsByContinuousSignCount(
                    continueSignCount - 1) + rule.getCredits();
            canGetSignCreditTomorrow = CmCommonUtils.getSignCreditsByContinuousSignCount(
                    continueSignCount + 1) + rule.getCredits();
        } else {
            if (DateUtils.isSameDay(DateTimeUtils.getDaysAgo(new Date(), 1), cmUser.getLastSignTime())) {
                canGetSignCreditToday = CmCommonUtils.getSignCreditsByContinuousSignCount(
                        continueSignCount + 1) + rule.getCredits();
                canGetSignCreditTomorrow = CmCommonUtils.getSignCreditsByContinuousSignCount(
                        continueSignCount + 2) + rule.getCredits();
            } else {
                canGetSignCreditToday = rule.getCredits();
                canGetSignCreditTomorrow = rule.getCredits();
            }
        }

        userCreditTaskVO.setCanGetSignCreditToday(canGetSignCreditToday);
        userCreditTaskVO.setCanGetSignCreditTomorrow(canGetSignCreditTomorrow);
    }


    @Override
    public Object rollback() {
        return null;
    }

    @Override
    public void commit() {

    }

    @Override
    public boolean isControlService() {
        return false;
    }

    @Override
    public boolean isLogService() {
        return false;
    }

    @Override
    public boolean isMonitorService() {
        return false;
    }
}
