package com.YuyeTech.HeartRate.game.userinfo.controller;

import cn.hutool.core.date.DateUtil;
import com.YuyeTech.HeartRate.common.pojo.PageInfo;
import com.YuyeTech.HeartRate.dataobject.*;
import com.YuyeTech.HeartRate.dto.FriendInfoDTO;
import com.YuyeTech.HeartRate.dto.SignInDTO;
import com.YuyeTech.HeartRate.dto.UserDTO;
import com.YuyeTech.HeartRate.enums.ResultEnum;
import com.YuyeTech.HeartRate.enums.UserEnum;
import com.YuyeTech.HeartRate.exception.UserException;
import com.YuyeTech.HeartRate.game.TP_AppleInfo.projo.AppleInfo;
import com.YuyeTech.HeartRate.game.TP_AppleInfo.service.AppleInfoService;
import com.YuyeTech.HeartRate.game.TP_AppleInfo.vo.AppleInfoVo;
import com.YuyeTech.HeartRate.game.TP_WxInfo.projo.WxInfo;
import com.YuyeTech.HeartRate.game.TP_WxInfo.service.WxInfoService;
import com.YuyeTech.HeartRate.game.cDietInfo.projo.CDietInfo;
import com.YuyeTech.HeartRate.game.cDietInfo.service.CDietInfoService;
import com.YuyeTech.HeartRate.game.cDietInfo.vo.CDietInfoSimpleVo;
import com.YuyeTech.HeartRate.game.cDietInfo.vo.CDietInfoVo;
import com.YuyeTech.HeartRate.game.cHistoricalCalorie.projo.CHistoricalCalorie;
import com.YuyeTech.HeartRate.game.cHistoricalCalorie.service.CHistoricalCalorieService;
import com.YuyeTech.HeartRate.game.cHistoricalCalorie.vo.CHistoricalCalorieSimpleVo;
import com.YuyeTech.HeartRate.game.cHistoricalCalorie.vo.CHistoricalCalorieVo;
import com.YuyeTech.HeartRate.game.imageInfo.projo.Pictures;
import com.YuyeTech.HeartRate.game.imageInfo.service.PicturesService;
import com.YuyeTech.HeartRate.game.userinfo.projo.MainInfo;
import com.YuyeTech.HeartRate.game.userinfo.projo.UserInfo;
import com.YuyeTech.HeartRate.game.userinfo.service.MainInfoService;
import com.YuyeTech.HeartRate.game.userinfo.service.UserInfoService;
import com.YuyeTech.HeartRate.service.*;
import com.YuyeTech.HeartRate.utils.*;
import com.YuyeTech.HeartRate.VO.ResultVO;
import com.YuyeTech.HeartRate.VO.UserInfoVO;

import com.YuyeTech.HeartRate.form.UserForm;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author:slambb
 * @date:2019/12/5
 */
@RestController
@RequestMapping("/user_info")
@Slf4j
public class UserInfoController {
    @Autowired
    private AliyunOSSUtil aliyunOSSUtil;
    @Autowired
    private PicturesService picturesService;
    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private MainInfoService mainInfoService;

    @Autowired
    private WxInfoService wxInfoService;

    @Autowired
    private AppleInfoService appleInfoService;

    @Autowired
    private WeightInfoService weightInfoService;

    @Autowired
    private CHistoricalCalorieService cHistoricalCalorieService;

    @Autowired
    private CDietInfoService cDietInfoService;

    private ImageUtils imageUtils;

    @Autowired
    private FriendInfoService friendInfoService;

    @Autowired
    private UserWalletsService userWalletsService;

    @Autowired
    private SignInService signInService;


    @Value("${RSA.friendId.publicKey}")
    private String friendIdPublicKey;
    @Value("${RSA.friendId.privateKey}")
    private String friendIdPrivateKey;

    @GetMapping("/get")
    public ResultVO getUserInfo(@RequestParam(value = "userId", required = false) String userId) {
        //请求userId为空时候
        if (userId == null) {
            throw new UserException(UserEnum.USER_NOT_EXIST);
        }
        //查询对应数据
        UserInfo userInfo = userInfoService.findUserInfoById(userId, true);
        if (userInfo == null) {
            return ResultVOUtil.error(UserEnum.USER_NOT_EXIST.getCode(), UserEnum.USER_NOT_EXIST.getMessage());
        }
        Map map = new HashMap();
        //返回对应展示的信息
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userInfo, userInfoVO);

        map.put("userInfo", userInfoVO);
        //还需要返回openid 和 phoneNumber,邮箱号
        //mainInfo 肯定是不为null 的
        MainInfo mainInfo = mainInfoService.findMainInfoById(userId);
        map.put("phoneNumber", mainInfo.getTelephoneNumber());
        map.put("mailboxNumber",mainInfo.getEmail());

        //如果是用户名和密码一样，默认是新注册并且没有设置过密码
        if(mainInfo.getUsername().equals(mainInfo.getPassword())){
            map.put("setPasswordFirstTime",true);
        }else {
            map.put("setPasswordFirstTime",false);
        }

        WxInfo wxInfo = wxInfoService.findWxInfoById(userId);
        if (wxInfo == null) {
            map.put("openid", null);
        } else {
            map.put("openid", wxInfo.getOpenid());
        }

        AppleInfoVo appleInfoVo = appleInfoService.getVo(userId);
        if(appleInfoVo ==null){
            map.put("appleid",null);
        } else {
            map.put("appleid",appleInfoVo.getAppleId());
        }

        return ResultVOUtil.success(map);
    }

//    @GetMapping("delete")
//    public ResultVO deleteUserInfo(@RequestParam(value = "userId") String userId) {
//        //请求userId为空时候
//        if (userId == null) {
//            throw new UserException(UserEnum.USER_NOT_EXIST);
//        }
//        try {
//            String callback = userInfoService.deleteUserInfoById(userId);
//            return ResultVOUtil.success(callback);
//
//        } catch (UserException e) {
//            return ResultVOUtil.error(e.getCode(), e.getMessage());
//        }
//
//    }

    /**
     * 前端替换头像等用户数据
     * @param file
     * @param form
     * @return
     */
    @PostMapping(value = "add_avatar", headers = "content-type=multipart/form-data")
    @Transactional
    public ResultVO addUserImage(@RequestParam(value = "file", required = false) MultipartFile file,
                                 @Valid UserForm form) {
        UserInfo userInfo = new UserInfo();
        //存的项目的中模版图片
        String contextPath = "";
        File uploadFile = null;
        try {
            String uploadUrl = "";
            String filename = file.getOriginalFilename();
            if (!"".equals(filename.trim())) {
                contextPath = imageUtils.getCompressPath(file, 200);
                uploadFile = new File(contextPath);
                uploadUrl = aliyunOSSUtil.upload(uploadFile, "avatar");
            }
            userInfo = userInfoService.findUserInfoById(form.getUserId(), false);
            //数据表没有数据
            if (userInfo == null) {
                userInfo = new UserInfo();
                userInfo.setUserId(form.getUserId());
                userInfo.setUsername("");
                userInfo.setGender("其他");
                userInfo.setBirthday(DateUtil.date());
                userInfo.setSignature("");
                userInfo.setAvatarUrl(uploadUrl);
                userInfo.setHeight(0.0);
                userInfo.setWeight(0.0);
                userInfo.setWaistline(0.0);
                userInfo.setSHeartRate(0.0);
                userInfo.setRegisterTime(DateUtil.date());
                userInfo.setStatus(1);//1为新注册
                userInfo.setUpdateTime(DateUtil.date());

            } else {
                //这里判断处理，把旧的头像数据删除
                //默认头像不用删除
                if (!userInfo.getAvatarUrl().equals("publicAvatar/defaultAvatar.png") && userInfo.getAvatarUrl() != null && userInfo.getAvatarUrl().length() != 0) {
                    //直接删除数据，替换新的url
                    if (aliyunOSSUtil.deleteBlog(userInfo.getAvatarUrl())) {
                        userInfo.setAvatarUrl(uploadUrl);
                    }
                } else {
                    //没有头像时候，设置上传新的头像
                    userInfo.setAvatarUrl(uploadUrl);
                }
            }
            BeanUtils.copyProperties(form, userInfo, PropertyUtil.getNullPropertyNames(form));
            //保存数据库，获取保存后的字段
            userInfo = userInfoService.addUserInfo(userInfo);
        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (!contextPath.equals("")) {
                imageUtils.deleteImage(contextPath);
            }
            uploadFile.delete();
        }

        //vo 返回给前端的字段筛选
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userInfo, userInfoVO);
        //修改url，添加访问域名
        String url = aliyunOSSUtil.addDomainName(userInfoVO.getAvatarUrl());
        userInfoVO.setAvatarUrl(url);
        return ResultVOUtil.success(userInfoVO);
    }

    /**
     * 操作微信头像
     * @param file
     * @param username
     * @param gender
     * @param userId
     * @return
     */
    @PostMapping("add_wx_avatar_info")
    @Transactional
    public ResultVO addAvatarUserInfo(@RequestParam(value = "file", required = false) MultipartFile file,
                                      @RequestParam("username") String username,
                                      @RequestParam("gender") String gender,
                                      @RequestParam("userId") String userId) {
        UserInfo userInfo = new UserInfo();
        String contextPath = "";
        File uploadFile = null;
        try {
            String uploadUrl = "";
            String filename = file.getOriginalFilename();
            if (!"".equals(filename.trim())) {
                contextPath = imageUtils.getCompressPath(file, 200);
                uploadFile = new File(contextPath);
                //上传到OSS
                uploadUrl = aliyunOSSUtil.upload(uploadFile, "avatar");
            }
            //数据表没有数据
            userInfo.setUsername(username);
            userInfo.setUserId(userId);
            userInfo.setGender(gender);
            userInfo.setBirthday(DateUtil.date());
            userInfo.setAvatarUrl(uploadUrl);
            userInfo.setHeight(0.0);
            userInfo.setWeight(0.0);
            userInfo.setWaistline(0.0);
            userInfo.setSHeartRate(0.0);
            userInfo.setRegisterTime(DateUtil.date());
            userInfo.setStatus(1);//1为新注册
            userInfo.setUpdateTime(DateUtil.date());
            //保存数据库，获取保存后的字段
            userInfo = userInfoService.addUserInfo(userInfo);
        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (!contextPath.equals("")) {
                imageUtils.deleteImage(contextPath);
            }
            uploadFile.delete();
        }

        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userInfo, userInfoVO);
        String url = aliyunOSSUtil.addDomainName(userInfoVO.getAvatarUrl());
        userInfoVO.setAvatarUrl(url);
        return ResultVOUtil.success(userInfoVO);
    }

    /**
     * 苹果登录信息添加，使用数据库默认头像
     * @param username
     * @param gender
     * @param userId
     * @return
     */
    @PostMapping("appleAdd")
    public ResultVO appleAddUserInfo(@RequestParam("username") String username,
                                     @RequestParam("gender") String gender,
                                     @RequestParam("userId") String userId) {
        UserInfo userInfo = new UserInfo();
        try {
            userInfo = userInfoService.findUserInfoById(userId, false);
            //数据表没有数据
            if (userInfo == null) {
                userInfo = new UserInfo();
                //使用默认头像，数据库设定
                List<Pictures> picturesList = userInfoService.getDefaultAvatar();
                if (picturesList.size() != 0) {
                    userInfo.setAvatarUrl(picturesList.get(0).getPictureUrl());
                } else {
                    return ResultVOUtil.error(UserEnum.USER_DEFAULT_NULL.getCode(), UserEnum.USER_DEFAULT_NULL.getMessage());
                }
                userInfo.setUserId(userId);
                userInfo.setUsername(username);
                userInfo.setGender(gender);
                userInfo.setBirthday(DateUtil.date());
                userInfo.setSignature("");
                userInfo.setHeight(0.0);
                userInfo.setWeight(0.0);
                userInfo.setWaistline(0.0);
                userInfo.setSHeartRate(0.0);
                userInfo.setRegisterTime(DateUtil.date());
                userInfo.setStatus(1);//1为新注册
                userInfo.setUpdateTime(DateUtil.date());
                //保存数据库，获取保存后的字段
                userInfo = userInfoService.addUserInfo(userInfo);
            } else {
                userInfo.setUserId(userId);
                userInfo.setUsername(username);
                userInfo.setGender(gender);
            }

        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        //vo 返回给前端的字段筛选

        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userInfo, userInfoVO);
        //修改url，添加访问域名
        String url = aliyunOSSUtil.addDomainName(userInfoVO.getAvatarUrl());
        userInfoVO.setAvatarUrl(url);
        return ResultVOUtil.success(userInfoVO);
    }

    /**
     * 添加用户信息，使用数据库默认头像
     * @param form
     * @param bAddWeightInfo
     * @return
     */
    @PostMapping("add")
    @Transactional
    public ResultVO addUserInfo(@Valid UserForm form,
                                @RequestParam(value = "bAddWeightInfo", required = false, defaultValue = "false") Boolean bAddWeightInfo) {
        UserInfo userInfo = new UserInfo();
        try {
            userInfo = userInfoService.findUserInfoById(form.getUserId(), false);
            //数据表没有数据
            if (userInfo == null) {
                userInfo = new UserInfo();
                //使用默认头像，数据库设定
                List<Pictures> picturesList = userInfoService.getDefaultAvatar();
                if (picturesList.size() != 0) {
                    userInfo.setAvatarUrl(picturesList.get(0).getPictureUrl());
                } else {
                    return ResultVOUtil.error(UserEnum.USER_DEFAULT_NULL.getCode(), UserEnum.USER_DEFAULT_NULL.getMessage());
                }
                userInfo.setUserId(form.getUserId());
                userInfo.setUsername(form.getUsername());
                userInfo.setGender(form.getGender());
                userInfo.setBirthday(DateUtil.date());
                userInfo.setSignature(form.getSignature());
                userInfo.setHeight(0.0);
                userInfo.setWeight(0.0);
                userInfo.setWaistline(0.0);
                userInfo.setSHeartRate(0.0);
                userInfo.setRegisterTime(DateUtil.date());
                userInfo.setStatus(1);//1为新注册
                userInfo.setUpdateTime(DateUtil.date());
                bAddWeightInfo = true;
            }

            BeanUtils.copyProperties(form, userInfo, PropertyUtil.getNullPropertyNames(form));
            //保存数据库，获取保存后的字段
            userInfo = userInfoService.addUserInfo(userInfo);
            if (bAddWeightInfo) {
                //第一次把体重保存到weightInfo表
                saveWeightInfo(userInfo);
            }

        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        //vo 返回给前端的字段筛选

        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userInfo, userInfoVO);
        //修改url，添加访问域名
        String url = aliyunOSSUtil.addDomainName(userInfoVO.getAvatarUrl());
        userInfoVO.setAvatarUrl(url);
        return ResultVOUtil.success(userInfoVO);
    }

    private void saveWeightInfo(UserInfo userInfo) {
        WeightInfo weightInfo = new WeightInfo();
        weightInfo.setUserId(userInfo.getUserId());
        weightInfo.setWeight(userInfo.getWeight());
        weightInfo.setWeightId(KeyUtil.genUniqueKey());
        weightInfo.setCreateTime(new Date());
        //保存数据库，获取保存后的字段
        weightInfoService.addWeightInfo(weightInfo);
    }

    @PostMapping("add_weight")
    @Transactional
    public ResultVO addUserWeightInfo(@RequestParam(value = "weight") Double weight, @RequestParam(value = "userId") String userId) {

        WeightInfo weightInfo = new WeightInfo();
        try {
            weightInfo.setUserId(userId);
            weightInfo.setWeight(weight);
            weightInfo.setWeightId(KeyUtil.genUniqueKey());
            weightInfo.setCreateTime(new Date());
            //保存数据库，获取保存后的字段
            weightInfo = weightInfoService.addWeightInfo(weightInfo);

            //把体重同步到user_info 里面
            UserInfo userInfo = userInfoService.findUserInfoById(userId, false);
            if (userInfo != null) {
                userInfo.setWeight(weightInfo.getWeight());
                userInfoService.addUserInfo(userInfo);
            }
        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        }
//        Map listWeightInfo = weightInfoService.findAll(userId);
        Integer page = 1;
        Integer size = 32;
        PageRequest request = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createTime"));
        Map listWeightInfo = weightInfoService.findWeightInfoByPage(userId, request);

        Map map = new HashMap();
        map.put("currentWeight", weightInfo.getWeight());
        map.put("weightList", listWeightInfo);
        return ResultVOUtil.success(map);
    }

    @GetMapping("get_weight")
    public ResultVO getWeightList(@RequestParam(value = "userId") String userId) {

        try {
            Integer page = 1;
            Integer size = 32;
            PageRequest request = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createTime"));
            Map weightInfo = weightInfoService.findWeightInfoByPage(userId, request);
//            Map weightInfo = weightInfoService.findAll(userId);
            return ResultVOUtil.success(weightInfo);

        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        }

    }


    @PostMapping("modify_heart_rate")
    @Transactional
    public ResultVO modifyHeartRate(@RequestParam(value = "heartRate") Double heartRate, @RequestParam(value = "userId") String userId) {

        UserInfo userInfo = new UserInfo();
        try {
            userInfo = userInfoService.findUserInfoById(userId, false);
            //数据表没有数据
            if (userInfo == null) {
              throw new UserException(UserEnum.USER_INFO_NULL);
            }
            userInfo.setSHeartRate(heartRate);
            //保存数据库，获取保存后的字段
            userInfo = userInfoService.addUserInfo(userInfo);
        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        //vo 返回给前端的字段筛选

        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userInfo, userInfoVO);
        //修改url，添加访问域名
        String url = aliyunOSSUtil.addDomainName(userInfoVO.getAvatarUrl());
        userInfoVO.setAvatarUrl(url);
        return ResultVOUtil.success(userInfoVO);
    }

    /**
     * 获取好友信息列表
     *
     * @param userId
     * @return
     */
    @GetMapping("get_friend_list")
    public ResultVO getFriendList(@RequestParam(value = "userId") String userId,
                                  @RequestParam(value = "page", defaultValue = "1") Integer page,
                                  @RequestParam(value = "size", defaultValue = "10") Integer size) {

        PageRequest request = PageRequest.of(page - 1, size);

        Page<FriendInfo> friendInfoPage = friendInfoService.getFriendUserInfo(request, userId);
        List<String> friendIds = friendInfoPage.getContent()
                .stream().map(e -> e.getFriendId()).collect(Collectors.toList());

        List<FriendInfoDTO> friendInfoVOList = new ArrayList<>();

        List<UserDTO> userInfos = userInfoService.findUserInfoListByIDs(friendIds);
        for (int i = 0; i < userInfos.size(); i++) {
            UserDTO e = userInfos.get(i);
            String encodedData = null; //friendId,不对外暴露,直接用RSA加密
            try {
                encodedData = RSAUtils.publicEncrypt(friendInfoPage.getContent().get(i).getFriendId(), RSAUtils.getPublicKey(friendIdPublicKey));
            } catch (NoSuchAlgorithmException ex) {
                ex.printStackTrace();
            } catch (InvalidKeySpecException ex) {
                ex.printStackTrace();
            }
            FriendInfoDTO friendInfoDTO = new FriendInfoDTO(
                    e.getUsername(),
                    e.getGender(),
                    e.getSignature(),
                    e.getAvatarUrl(),
                    e.getCityCode(),
                    e.getHeight(),
                    e.getWeight(),
                    e.getBirthday(),
                    true,
                    encodedData // friendInfoPage.getContent().get(i).getId()
            );

            friendInfoVOList.add(friendInfoDTO);
        }

        Map map = new HashMap();
        map.put("friends", friendInfoVOList);
        map.put("page", friendInfoPage.getNumber() + 1);
        map.put("size", friendInfoPage.getSize());

        return ResultVOUtil.success(map);
    }

    /**
     * 模糊搜索用户信息·
     *
     * @param username
     * @param page
     * @param size
     * @return
     */
    @GetMapping("friend_search_list")
    public ResultVO searchListFromUserInfo(
            @RequestParam(value = "userId") String userId,
            @RequestParam(value = "username") String username,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "size", defaultValue = "10") Integer size) {

        PageRequest request = PageRequest.of(page - 1, size);
        Page<UserInfo> userInfoPage = userInfoService.searchByUsername(request, username);

        List<FriendInfoDTO> friendInfoVOList = userInfoPage.stream().map(e -> {
            FriendInfo friendInfo = friendInfoService.findByUserIdAndFriendId(userId, e.getUserId());

            String encodedData = null; //显示用户id,不对外暴露,直接用RSA加密
            try {
                encodedData = RSAUtils.publicEncrypt(e.getUserId(), RSAUtils.getPublicKey(friendIdPublicKey));
            } catch (NoSuchAlgorithmException ex) {
                ex.printStackTrace();
            } catch (InvalidKeySpecException ex) {
                ex.printStackTrace();
            }
            return new FriendInfoDTO(
                    e.getUsername(),
                    e.getGender(),
                    e.getSignature(),
                    aliyunOSSUtil.addDomainName(e.getAvatarUrl()),
                    e.getCityCode(),
                    e.getHeight(),
                    e.getWeight(),
                    e.getBirthday(),
                    friendInfo != null ? true : false,
                    encodedData
            );
        }).collect(Collectors.toList());
        //处理关注状态。比如已关注之类的

        Map map = new HashMap();
        map.put("friends", friendInfoVOList);
        map.put("page", userInfoPage.getNumber() + 1);
        map.put("size", userInfoPage.getSize());

        return ResultVOUtil.success(map);

    }

    /**
     * 添加一个好友
     *
     * @param userId
     * @param friendRSA RSA处理的值,对外是显示friendId
     * @return
     */
    @GetMapping("/friend_add")
    public ResultVO addFriendInfo(@RequestParam(value = "userId", required = false) String userId,
                                  @RequestParam(value = "friendId") String friendRSA) {
        //请求userId为空时候
        if (userId == null) {
            throw new UserException(UserEnum.USER_NOT_EXIST);
        }

        try {
            String decFriendId = RSAUtils.privateDecrypt(friendRSA, RSAUtils.getPrivateKey(friendIdPrivateKey));
            FriendInfo friendInfo = friendInfoService.findByUserIdAndFriendId(userId, decFriendId);

            if (friendInfo != null) {
                Map tempMap = new HashMap();
                tempMap.put("bHas", true);
                tempMap.put("msg", "已添加过关注");
                return ResultVOUtil.success(tempMap);
            }

            //添加好友信息
            String _id = KeyUtil.genUniqueKey();
            friendInfo = new FriendInfo();
            friendInfo.setId(_id);
            friendInfo.setUserId(userId);
            friendInfo.setFriendId(decFriendId);
            friendInfo.setIsOut(0);//单向添加，类似于关注
            friendInfo.setCreatedAt(new Date());
            //添加后返回值 Favorites tempFavorite  =
            friendInfoService.addFriendInfo(friendInfo);
            Map tempMap = new HashMap();
            tempMap.put("isFriend", true);
            tempMap.put("msg", "新关注的好友");

            return ResultVOUtil.success(tempMap);

        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        } catch (NoSuchAlgorithmException e) {
            return ResultVOUtil.error(400, e.getMessage());
        } catch (InvalidKeySpecException e) {
            return ResultVOUtil.error(400, e.getMessage());
        }

    }


    @GetMapping("/friend_delete")
    @Transactional
    public ResultVO deleteFriendInfo(@RequestParam(value = "userId", required = false) String userId,
                                     @RequestParam(value = "friendId") String friendRSA) {

        //请求userId为空时候
        if (userId == null) {
            throw new UserException(UserEnum.USER_NOT_EXIST);
        }

        try {
//            friendInfoService.deleteById(id);
            friendInfoService.deleteFriendInfo(userId, RSAUtils.privateDecrypt(friendRSA, RSAUtils.getPrivateKey(friendIdPrivateKey)));
            Map tempMap = new HashMap();
            tempMap.put("isFriend", false);
            tempMap.put("msg", "已删除好友信息");
            return ResultVOUtil.success(tempMap);
        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        } catch (NoSuchAlgorithmException e) {
            return ResultVOUtil.error(400, e.getMessage());
        } catch (InvalidKeySpecException e) {
            return ResultVOUtil.error(400, e.getMessage());
        }

    }


    @GetMapping("/get_user_wallets")
    public ResultVO getUserWalletsInfo(@RequestParam(value = "userId") String userId) {

        try {
            UserWallets userWallets = userWalletsService.findUserWalletsByUserId(userId);
            Map tempMap = new HashMap();
            tempMap.put("gold", userWallets.getGold());
            tempMap.put("diamond", userWallets.getDiamond());
            return ResultVOUtil.success(tempMap);
        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        }

    }

    /**
     * 签到部分，获取已经签到的列表
     *
     * @param userId
     * @return
     */
    @GetMapping("/get_sign_in_list")
    public ResultVO getSignInList(@RequestParam(value = "userId") String userId) {
        Boolean isNewList = true;
        Boolean isSignIn = false;
        SignIn signIn = signInService.findByUserId(userId);
        List<SignInDTO> list = new ArrayList<>(7);
        Integer _filterDay = 7;
        List<SignInReward> signInRewards = signInService.getSignInRewardList().stream().filter(e -> e.getDays() <= _filterDay).collect(Collectors.toList());
        //如果没有对象，或者对应对象时间为0
        if (null != signIn) {
            Integer continueDays = signIn.getContinueDays();
            // 判断最后签到日期与当前日期是否超过一天
            LocalDate signInTime = signIn.getSettingTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            LocalDate currTime = LocalDate.now();
            long daysDiff = ChronoUnit.DAYS.between(signInTime, currTime);
            if (daysDiff > 1) {
                // 超过一天, 把连续签到的天数重置为 0,并记录到数据库，
                // 这一步是重置数据操作
                signIn.setContinueDays(0);
                signIn.setUpdateTime(new Date());
                signInService.addSignIn(signIn);
            } else {
                //如果小于或者等于0，判断为当天为签到. 连续签到时间不为0
                if(daysDiff <=0 && !signIn.getContinueDays().equals(0)){
                    isSignIn = true;
                }

                if (continueDays > 7) {
                    //不是默认的list
                    isNewList = false;
                    Integer currentDays = continueDays % _filterDay;
                    currentDays = currentDays == 0 ? _filterDay : currentDays;
                    Integer extraDays = continueDays / _filterDay;
                    for (int i = 0; i < signInRewards.size(); i++) {
                        SignInReward temp = signInRewards.get(i);
                        if (i < currentDays) {
                            list.add(new SignInDTO(i + 1 + extraDays * signInRewards.size(), temp.getDays(), 1, temp.getGold(), temp.getDiamond()));
                        } else {
                            list.add(new SignInDTO(i + 1 + (extraDays - 1) * signInRewards.size(), temp.getDays(), 0, temp.getGold(), temp.getDiamond()));
                        }
                    }
                }
            }
        }
        /**
         * isNewList 的情况下，continueDays 是小于7的。此时处理flag不需要考虑往后的数值
         */
        if (isNewList) {
            Integer continueDays = 0;
            if (null != signIn) {
                continueDays = signIn.getContinueDays();
            }
            // 没有签过到
            for (int i = 0; i < signInRewards.size(); i++) {
                SignInReward temp = signInRewards.get(i);
                list.add(new SignInDTO(i + 1, temp.getDays(), i < continueDays ? 1 : 0, temp.getGold(), temp.getDiamond()));
            }
        }

        Collections.sort(list, new Comparator<SignInDTO>() {
            @Override
            public int compare(SignInDTO u1, SignInDTO u2) {
                int diff = u1.getDayType() - u2.getDayType();
                if (diff > 0) {
                    return 1;
                } else if (diff < 0) {
                    return -1;
                }
                return 0; //相等为0
            }
        }); // 按天数排序
        Map map = new HashMap();
        map.put("signInList",list);
        map.put("isSignIn",isSignIn);
        return ResultVOUtil.success(map);

    }


    @GetMapping("/user_sign_in")
    @Transactional(rollbackFor = Exception.class)
    public ResultVO setUserSignIn(@RequestParam(value = "userId") String userId) {

        SignIn signIn = signInService.findByUserId(userId);

        if (null == signIn) {
            signIn = new SignIn();
            signIn.setUserId(userId);
            signIn.setContinueDays(1);
            signIn.setSettingTime(new Date());
            signIn.setUpdateTime(new Date());
            signInService.addSignIn(signIn);
        } else {/*签过到*/
            // 判断最后签到日期与当前日期是否超过一天
            LocalDate signInTime = signIn.getSettingTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            LocalDate currTime = LocalDate.now();
            long daysDiff = ChronoUnit.DAYS.between(signInTime, currTime);
            if (daysDiff <= 0) {
                return ResultVOUtil.error(ResultEnum.SIGN_IN_REPEAT.getCode(), ResultEnum.SIGN_IN_REPEAT.getMessage());
            }
            if (daysDiff > 1) {
                // 1, 超过一天, 把连续签到的天数重置为 1
                signIn.setContinueDays(1);
            } else {
                // 2, 没有超过一天, 把连续签到的天数+1
                signIn.setContinueDays(signIn.getContinueDays() + 1);
            }
            signIn.setSettingTime(new Date());
            signIn.setUpdateTime(new Date());
            signInService.addSignIn(signIn);


        }

        /**
         * 根据当前签到的天数，返回对应的奖励，奖励由数据库定义
         */
        Integer currentDays = signIn.getContinueDays() % 7;
        currentDays = currentDays == 0 ? 7 : currentDays;
        SignInReward signInReward = signInService.getSignInRewardByDays(currentDays);
        SignInDTO signInDTO = new SignInDTO();
        signInDTO.setDayType(currentDays);
        signInDTO.setDay(signIn.getContinueDays());
        signInDTO.setFlag(1);
        signInDTO.setGold(signInReward.getGold());
        signInDTO.setDiamond(signInReward.getDiamond());

        //todo 奖励用户相应信息
        UserWallets userWallets = userWalletsService.modifyGoldAndDiamondInUserWallets(userId, signInReward.getGold(), signInReward.getDiamond(), true);
        Map map = new HashMap();
        map.put("signIn", signInDTO);
        map.put("userGold", userWallets.getGold());
        map.put("userDiamond", userWallets.getDiamond());
        return ResultVOUtil.success(map);

    }


    @PostMapping("add_historical_calorie")
    @Transactional
    public ResultVO addHistoricalCalorie(@RequestParam(value = "calorie") Double calorie, @RequestParam(value = "userId") String userId) {


        try {
           CHistoricalCalorie cHistoricalCalorie = cHistoricalCalorieService.findByToday();
           boolean bSaveDate = true;
           if(cHistoricalCalorie == null){
               cHistoricalCalorie.setUserId(userId);
               cHistoricalCalorie.setCalorie(calorie);
           }else{
               if(cHistoricalCalorie.getCalorie().equals(calorie)){
                   bSaveDate = false;
               }else{
                   cHistoricalCalorie.setCalorie(calorie);
               }
           }
            CHistoricalCalorieVo cHistoricalCalorieVo = new CHistoricalCalorieVo();
            BeanUtils.copyProperties(cHistoricalCalorie, cHistoricalCalorieVo);
            //保存数据库，获取保存后的字段
            if(bSaveDate){
                cHistoricalCalorieVo = cHistoricalCalorieService.saveReturnVo(cHistoricalCalorieVo);
            }
            cHistoricalCalorieVo.setPage(1);
            cHistoricalCalorieVo.setRows(10);
            cHistoricalCalorieVo.setSidx("DESC");
            cHistoricalCalorieVo.setSord("createTime");
            PageInfo pageInfo = cHistoricalCalorieService.pageByClass(cHistoricalCalorieVo, CHistoricalCalorieSimpleVo.class);

            Map map = new HashMap();
            map.put("todayCalorie", cHistoricalCalorieVo.getCalorie());
            map.put("pageInfo", pageInfo);
            return ResultVOUtil.success();

        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        }

    }

    @GetMapping("get_historical_calorie")
    public ResultVO getHistoricalCalorie(@RequestParam(value = "userId") String userId,
                                         @RequestParam(value = "page",defaultValue = "1") Integer page,
                                         @RequestParam(value = "size",defaultValue = "10") Integer size) {

        try {
            CHistoricalCalorieVo cHistoricalCalorieVo = new CHistoricalCalorieVo();
            cHistoricalCalorieVo.setPage(page);
            cHistoricalCalorieVo.setRows(size);
            cHistoricalCalorieVo.setSidx("DESC");
            cHistoricalCalorieVo.setSord("createTime");
            PageInfo pageInfo = cHistoricalCalorieService.pageByClass(cHistoricalCalorieVo, CHistoricalCalorieSimpleVo.class);
            return ResultVOUtil.success(pageInfo);
        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        }

    }

    @PostMapping("upload_diet_calorie")
    @Transactional
    public ResultVO uploadDietCalorie(@RequestParam(value = "calorie") Double calorie, @RequestParam(value = "userId") String userId) {

        try {
            CDietInfo cDietInfo = cDietInfoService.findByUserId(userId);
            if(cDietInfo == null){
                cDietInfo = new CDietInfo();
                cDietInfo.setUserId(userId);
                cDietInfo.setPreCalorie(calorie);
                cDietInfo.setCreateTime(new Date());
                cDietInfo.setUpdateTime(new Date());
            }else{
                cDietInfo.setPreCalorie(calorie);
                // cDietInfo.setUpdateTime(new Date());
            }
            //保存数据库，获取保存后的字段
            CDietInfoVo  cDietInfoVo = new CDietInfoVo();
            BeanUtils.copyProperties(cDietInfo, cDietInfoVo);
            cDietInfoVo =  cDietInfoService.saveReturnVo(cDietInfoVo);
            Map map = new HashMap();
            map.put("calorie", cDietInfoVo.getPreCalorie());
            return ResultVOUtil.success(map);



        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        }


    }

    @GetMapping("get_diet_calorie")
    public ResultVO getDietCalorie(@RequestParam(value = "userId") String userId) {

        try {
            CDietInfo cDietInfo = cDietInfoService.findByUserId(userId);

            Map map = new HashMap();
            map.put("calorie",cDietInfo == null?0:cDietInfo.getPreCalorie());
            return ResultVOUtil.success(map);
        } catch (UserException e) {
            return ResultVOUtil.error(e.getCode(), e.getMessage());
        }

    }
}
