
package com.tmerclub.cloud.user.controller.app;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.api.platform.feign.ConfigFeignClient;
import com.tmerclub.cloud.api.platform.vo.ScoreExpireConfigVO;
import com.tmerclub.cloud.common.constant.ConfigNameConstant;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.Json;
import com.tmerclub.cloud.user.bo.mongo.MongoUserScoreLogBO;
import com.tmerclub.cloud.user.constant.DistributedIdKey;
import com.tmerclub.cloud.user.constant.ScoreIoTypeEnum;
import com.tmerclub.cloud.user.constant.ScoreLogTypeEnum;
import com.tmerclub.cloud.user.model.UserExtension;
import com.tmerclub.cloud.user.model.UserScoreGetLog;
import com.tmerclub.cloud.user.model.UserScoreLog;
import com.tmerclub.cloud.user.service.UserExtensionService;
import com.tmerclub.cloud.user.service.UserLevelService;
import com.tmerclub.cloud.user.service.UserScoreGetLogService;
import com.tmerclub.cloud.user.service.UserScoreLogService;
import com.tmerclub.cloud.user.vo.ScoreCompleteConfigVO;
import com.tmerclub.cloud.user.vo.ScoreDataVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 积分中心接口
 *
 * @author LHD
 * @date 2019-3-18 10:27:46
 */
@RestController
@RequestMapping("/score")
@Tag(name = "app-积分中心接口")
public class UserScoreController {

    @Autowired
    private UserScoreLogService scoreLogService;
    @Autowired
    private UserScoreGetLogService userScoreGetLogService;
    @Autowired
    private UserExtensionService userExtensionService;
    @Autowired
    private UserLevelService userLevelService;
    @Autowired
    private SegmentManager segmentManager;
    @DubboReference
    private ConfigFeignClient configFeignClient;

    @GetMapping("/signInUserScore")
    @Operation(summary = "积分签到", description = "积分签到")
    public ServerResponseEntity<String> signInUserScore() {
        Long userId = AuthUserContext.get().getUserId();
        UserExtension extension = userExtensionService.getByUserId(userId);
        String scoreConfigValue = configFeignClient.getConfig(ConfigNameConstant.SCORE_CONFIG).getData();
        ScoreCompleteConfigVO scoreParam = Json.parseObject(scoreConfigValue, ScoreCompleteConfigVO.class);
        //签到，计算连续签到日期
        if (isSignIn(userId, DateUtil.date())) {
            // 今天已经签到过了，请明天再试!
            return ServerResponseEntity.success("今天已经签到过了，请明天再试!");
        }
        //根据逗号分隔
        String[] signInScore = scoreParam.getSignInScoreString().split(StrUtil.COMMA);
        int count = Math.min(extension.getSignDay(), signInScore.length - 1);
        long score = Long.parseLong(signInScore[count]);
        // 查询昨天有没有签到,没有则初始化为1
        if (isSignIn(userId, DateUtil.offsetDay(DateUtil.date(), -1))) {
            extension.setSignDay(extension.getSignDay() + 1);
        } else {
            extension.setSignDay(1);
        }
//        String remarks = "签到第" + count + "天获取的积分";
        updateUserScoreBySign(score, ScoreIoTypeEnum.INCOME.value(), extension);
        // 领取积分成功
        return ServerResponseEntity.success("领取积分成功");
    }

    @GetMapping("/scoreInfo")
    @Operation(summary = "查看积分中心信息", description = "查看积分中心信息")
    public ServerResponseEntity<ScoreDataVO> scoreInfo() {
        ScoreDataVO scoreDataVO = new ScoreDataVO();
        Long userId = AuthUserContext.get().getUserId();
        String scoreParam = configFeignClient.getConfig(ConfigNameConstant.SCORE_CONFIG).getData();
        ScoreCompleteConfigVO scoreParamConfigVO = Json.parseObject(scoreParam, ScoreCompleteConfigVO.class);
        String scoreExpireParam = configFeignClient.getConfig(ConfigNameConstant.SCORE_EXPIRE).getData();
        //计算过期时间
        ScoreExpireConfigVO scoreExpireParamConfigVO = Json.parseObject(scoreExpireParam, ScoreExpireConfigVO.class);
        Integer expireYear = Objects.isNull(scoreExpireParamConfigVO) ? 0 : scoreExpireParamConfigVO.getExpireYear();
        List<Integer> signInScores = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (String s : scoreParamConfigVO.getSignInScoreString().trim().split(StrUtil.COMMA)) {
            Integer signInScore = Integer.valueOf(s);
            signInScores.add(signInScore);
        }
        UserExtension extension = userExtensionService.getByUserId(userId);
        // 查询连续签到天数大于0并且没有连续签到初始化为0
        boolean isContinuousSign = !isSignIn(userId, DateUtil.offsetDay(DateUtil.date(), -1)) && !isSignIn(userId, DateUtil.date());
        if (isContinuousSign && extension.getSignDay() != 0) {
            extension.setSignDay(0);
            userExtensionService.update(extension);
        }
        UserScoreLog scoreLog = scoreLogService.getExpireScoreLogByUserId(userId);
        scoreDataVO.setExpireScore(Objects.nonNull(scoreLog) ? scoreLog.getScore() : 0);
        scoreDataVO.setExpireYear(expireYear);
        scoreDataVO.setScoreExpireSwitch(scoreExpireParamConfigVO.getScoreExpireSwitch());
        scoreDataVO.setIsRegister(1);
        scoreDataVO.setScoreList(signInScores);
        scoreDataVO.setRegisterScore(scoreParamConfigVO.getRegisterScore());
        scoreDataVO.setShoppingScoreSwitch(scoreParamConfigVO.getShoppingScoreSwitch());
        scoreDataVO.setShoppingGetScore(scoreParamConfigVO.getShoppingGetScore());
        scoreDataVO.setIsSignIn(isSignIn(userId, DateUtil.date()) ? 1 : 0);
        scoreDataVO.setLevelType(extension.getLevelType());
        Long score = extension.getScore();
        scoreDataVO.setScore(score);
        scoreDataVO.setLevelName(userLevelService.getOneByTypeAndLevel(extension.getLevelType(), extension.getLevel()).getLevelName());
        int count = extension.getSignDay() <= 0 ? 1 : extension.getSignDay();
        // 如果不为第一天签到或者大于等于第七天的签到，+1
        if (extension.getSignDay() != 0 && !isSignIn(userId, DateUtil.date())) {
            count++;
        }
        // 连续签到天数
        scoreDataVO.setSignInCount(count);
        //根据逗号分隔
        String[] signInScore = scoreParamConfigVO.getSignInScoreString().split(StrUtil.COMMA);
        // 当天签到可领的积分
        int curScore;
        if (scoreDataVO.getIsSignIn() == 1) {
            count = Math.min(count, signInScore.length - 1);
            curScore = Integer.parseInt(signInScore[count]);
        } else {
            count = Math.min(count, signInScore.length);
            curScore = Integer.parseInt(signInScore[count - 1]);
        }
        scoreDataVO.setCurScore(curScore);
        return ServerResponseEntity.success(scoreDataVO);
    }

    private void updateUserScoreBySign(Long score, Integer ioType, UserExtension extension) {
        if (score == null) {
            return;
        }
        if (ioType == 1) {
            extension.setScore(extension.getScore() + score);
            // 添加积分明细
            UserScoreGetLog addDetail = new UserScoreGetLog();
            addDetail.setCreateTime(new Date());
            addDetail.setStatus(1);
            addDetail.setUserId(extension.getUserId());
            addDetail.setUsableScore(score);
            userScoreGetLogService.save(addDetail);
        } else {
            extension.setScore(extension.getScore() - score);
        }
        userExtensionService.update(extension);
        MongoUserScoreLogBO scoreLog = new MongoUserScoreLogBO();
        scoreLog.setLogId(segmentManager.getSegmentId(DistributedIdKey.tmerclub_USER_SCORE_LOG));
        scoreLog.setSource(ScoreLogTypeEnum.SIGN_IN.value());
        scoreLog.setIoType(ScoreIoTypeEnum.INCOME.value());
        //添加一条日志和修改用户积分
        scoreLog.setUserId(extension.getUserId());
        scoreLog.setScore(score);
        scoreLog.setBizId(1L);
        scoreLogService.saveToMongdb(scoreLog);
    }

    /**
     * 是否已经签到
     *
     * @param userId
     * @return
     */
    private boolean isSignIn(Long userId, Date date) {
        Long count = scoreLogService.countByUserIdAndDateTimeAndType(
                ScoreLogTypeEnum.SIGN_IN.value(), userId, DateUtil.beginOfDay(date), DateUtil.endOfDay(date));
        return Objects.nonNull(count) && count > 0;
    }

    /**
     * 配置信息
     */
    @GetMapping("/scoreConfigInfo/{id}")
    @Operation(summary = "查看积分成长值配置信息", description = "常见问题：SCORE_QUESTION；等级页展示：LEVEL_SHOW；成长值说明：MEMBER_GROWTH_DESCRIPTION")
    public ServerResponseEntity<String> info(@PathVariable("id") String key) {
        String config = configFeignClient.getConfig(key).getData();
        if (Objects.isNull(config)) {
            return ServerResponseEntity.success(null);
        }
        return ServerResponseEntity.success(config);
    }

}
