package com.house365.ws.interfaces.rest;

import com.google.common.base.Strings;
import com.house365.beans.entity.CmCreditRuleEntity;
import com.house365.beans.entity.CmOrderEntity;
import com.house365.beans.entity.CmUserEntity;
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.web.util.SpringContextUtil;
import com.house365.ws.cached.RedisUtils;
import com.house365.ws.cached.RedisUtilsInterface;
import com.house365.ws.service.interfaces.ICmCreditRuleService;
import com.house365.ws.service.interfaces.ICmOrderService;
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.InviteCodeUtil;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component("getUserCreditsInfo")
public class GetUserCreditsInfoImpl implements IGetUserCreditsInfo {

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

    @Autowired
    private ICmUserService<CmUserEntity> iCmUserService;

    @Autowired
    private ICmCreditRuleService<CmCreditRuleEntity> iCmCreditRuleService;

    @Autowired
    private ICmOrderService<CmOrderEntity> cmOrderService;

    @Autowired
    private ICmCreditRuleService cmCreditRuleService;

    /**
     * 周期内最多订单数, 默认2次
     */
    @Value("#{system.orderLimitCount}")
    private Integer ORDER_LIMIT_COUNT = 0;
    /**
     * 订单周期
     */
    @Value("#{system.orderLimitCircle}")
    private Integer ORDER_LIMIT_CIRCLE = 0;

    @Override
    public Object exectue(Parameter parameter) throws ServiceRunException {
        // 取得所需参数
        Map<String, Object> map = parameter.getArgs();
        Map<String, Object> resultMap = new HashMap<>(10);
        RedisUtilsInterface redisUtils = (RedisUtilsInterface) SpringContextUtil.getBean("redisUtils");
        String userIdStr = null;
        // 业务层统一处理
        try {
            if (map.get(CmConstant.USERID) == null) {
                resultMap.put("result", ReturnAppResult.APP_FAIL.getResultCode());
                resultMap.put("msg", "用户中心用户不存在!");
                return JSONObject.fromObject(resultMap).toString();
            }

            String host = MemoryPropertyPlaceholderConfigurer.getContextProperty("redis.host");
            userIdStr = ((String[]) map.get(CmConstant.USERID))[0];

            if (!Strings.isNullOrEmpty(host)) {
                final String key = RedisUtils.PREFIX + userIdStr + ":getUserCreditsInfo";
                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 !");
            }

            String cacheKey = "USERINFO:" + userIdStr;
            if (Strings.isNullOrEmpty(cacheKey) || redisUtils.getValByKeyNew(cacheKey) == null || Strings.isNullOrEmpty(
                    redisUtils.getValByKeyNew(cacheKey)) || "null".equalsIgnoreCase(
                    redisUtils.getValByKeyNew(cacheKey))) {
            } else {
                return redisUtils.getValByKeyNew(cacheKey).trim();
            }

            CmUserEntity cmUser = iCmUserService.registUserByUserId(map);

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

            CmCreditRuleEntity rule = (CmCreditRuleEntity) cmCreditRuleService.getById(CmConstant.CREDITS_RULE_SIGN);
            //活动加权
            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();
                }
            }

            cmUser.setCanGetSignCreditToday(canGetSignCreditToday);
            cmUser.setCanGetSignCreditTomorrow(canGetSignCreditTomorrow);

            if (map.get("isInviteUser") != null) {
                String isInviteUser = ((String[]) map.get("isInviteUser"))[0];
                if ("true".equals(isInviteUser)) {
                    Integer credits = iCmCreditRuleService.getById(CmConstant.CREDITS_RULE_INVITE_USER).getCredits();
                    cmUser.setInviteScore(credits);
                }
            }

            //获取30天内的兑换次数
            Map<String, Integer> orderMap = cmOrderService.userOrderCountInCircle(cmUser);
            Integer allOrderCount = orderMap.get("allOrderCount");
            Integer limitProductOrderCount = orderMap.get("limitProductOrderCount");
            cmUser.setExchangeCount(allOrderCount);
            cmUser.setExchangeCountCircle(ORDER_LIMIT_CIRCLE);
            cmUser.setExchangeCountLimit(ORDER_LIMIT_COUNT);
            cmUser.setLimitProductOrderCount(limitProductOrderCount);

            //设定邀请码
            cmUser.setInviteCode(InviteCodeUtil.getInviteCode(cmUser));
            //设置是否已经签到
            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);
                }
            }

            //设置是否已经抽奖
            if (cmUser.getLastSignLotteryTime() == null) {
                cmUser.setIsLotterySignedToday(0);
            } else {
                boolean isSignedToday = DateUtils.isSameDay(new Date(), cmUser.getLastSignLotteryTime());
                if (isSignedToday) {
                    cmUser.setIsLotterySignedToday(1);
                } else {
                    cmUser.setIsLotterySignedToday(0);
                }
            }
            if (cmUser.getIsDeleted() == 2) {
                resultMap.put("msg", "您的账号已注销!");
                cmUser.setCode(-1);
                resultMap.put("result", "0");
            } else {
                resultMap.put("msg", "");
                cmUser.setCode(0);
                resultMap.put("result", ReturnAppResult.APP_SUCCESS.getResultCode());
            }
            resultMap.put("data", cmUser);

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

        String res = JSONObject.fromObject(resultMap).toString();
        if (!Strings.isNullOrEmpty(userIdStr)) {
            redisUtils.setValueExpireNew("USERINFO:" + userIdStr, res, 10, TimeUnit.MINUTES);
        }
        return res;
    }

    @Override
    public boolean isControlService() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isLogService() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean isMonitorService() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public Object rollback() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void commit() {
        // TODO Auto-generated method stub

    }

}
