package ink.wgink.module.wechat.service.miniapp.impl;

import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.SearchException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.module.wechat.dao.miniapp.IMiniAppUserDao;
import ink.wgink.module.wechat.pojo.pos.miniapp.MiniappUserPO;
import ink.wgink.module.wechat.pojo.vos.miniapp.MiniAppUpdateInfoVO;
import ink.wgink.module.wechat.service.miniapp.IMiniappUserService;
import ink.wgink.pojo.dtos.miniapp.MiniappUserDTO;
import ink.wgink.properties.wechat.miniapp.MiniappProperties;
import ink.wgink.service.user.pojo.pos.UserPO;
import ink.wgink.service.user.pojo.vos.UserVO;
import ink.wgink.service.user.service.IUserService;
import ink.wgink.util.date.DateUtil;
import ink.wgink.util.string.WStringUtil;
import ink.wgink.util.verification.share.ShareCodeUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: MiniAppUserServiceImpl
 * @Description: 小程序用户
 * @Author: wanggeng
 * @Date: 2021/4/8 5:38 下午
 * @Version: 1.0
 */
@Service
public class MiniappUserServiceImpl extends DefaultBaseService implements IMiniappUserService {

    @Value("${user.default-password:" + ISystemConstant.DEFAULT_PASSWORD + "}")
    private String defaultPassword;
    @Autowired
    private IMiniAppUserDao miniappUserDao;
    @Autowired
    private IUserService userService;
    @Autowired
    private MiniappProperties miniappProperties;

    @Override
    public String createAndReturnUserId(String appKey, String openId) {
        MiniappUserPO miniAppUserPO = getPO(appKey, openId);
        if (miniAppUserPO != null) {
            LOG.debug("已经绑定小程序用户");
            return miniAppUserPO.getUserId();
        }
        // 随机字符串
        String randomUserName = WStringUtil.randomSubStr(openId, 6);
        UserVO userVO = new UserVO();
        userVO.setUserUsername(MINIAPP_RANDOM_USER_PREFIX + randomUserName);
        userVO.setUserName("微信M" + randomUserName);
        userVO.setUserPassword(defaultPassword);
        userVO.setUserState(0);
        // 公共用户
        userVO.setUserType(3);
        String userId = userService.saveAndReturnId(userVO, true);

        Map<String, Object> params = getHashMap(6);
        params.put("appId", appKey);
        params.put("openId", openId);
        params.put("userId", userId);
        params.put("isInitAccount", 1);
        params.put("gmtCreate", DateUtil.getTime());
        miniappUserDao.save(params);

        Long id = Long.parseLong(params.get("id").toString());
        String userCode = ShareCodeUtil.gen(id);
        updateUserCode(userCode, openId);
        return userId;
    }

    @Override
    public void delete(String userId) {
        if (StringUtils.isBlank(userId)) {
            return;
        }
        List<String> userIds = new ArrayList<>();
        userIds.add(userId);
        delete(userIds);
    }

    @Override
    public void delete(List<String> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return;
        }
        Map<String, Object> params = getHashMap(2);
        params.put("userIds", userIds);
        miniappUserDao.delete(params);
    }

    @Override
    public MiniappUserDTO getByUserId(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        List<MiniappUserDTO> miniappUserDTOS = listByUserIds(Arrays.asList(userId));
        if (miniappUserDTOS.isEmpty()) {
            return null;
        }
        return miniappUserDTOS.get(0);
    }

    @Override
    public List<MiniappUserDTO> listByUserIds(List<String> userIds) {
        if (userIds.isEmpty()) {
            return new ArrayList<>();
        }
        return listPO(userIds).stream().map(miniappUserPO -> {
            MiniappUserDTO miniappUserDTO = new MiniappUserDTO();
            BeanUtils.copyProperties(miniappUserPO, miniappUserDTO);
            return miniappUserDTO;
        }).collect(Collectors.toList());
    }

    @Override
    public MiniappUserDTO getByUserCode(String userCode) {
        if (StringUtils.isBlank(userCode)) {
            return null;
        }
        MiniappUserPO miniappUserPO = getPOByUserCode(userCode);
        if (miniappUserPO == null) {
            return null;
        }
        MiniappUserDTO miniappUserDTO = new MiniappUserDTO();
        BeanUtils.copyProperties(miniappUserPO, miniappUserDTO);
        return miniappUserDTO;
    }

    @Override
    public List<MiniappUserDTO> listByUserCodes(List<String> userCodes) {
        if (userCodes == null || userCodes.isEmpty()) {
            return new ArrayList<>();
        }
        return listPOByUserCodes(userCodes).stream().map(miniappUserPO -> {
            MiniappUserDTO miniappUserDTO = new MiniappUserDTO();
            BeanUtils.copyProperties(miniappUserPO, miniappUserDTO);
            return miniappUserDTO;
        }).collect(Collectors.toList());
    }

    @Override
    public void updateInfo(String token, MiniAppUpdateInfoVO miniAppUpdateInfoVO) throws Exception {
        String userId = getAppTokenUser(token).getId();
        UserPO userPO = userService.getPO(userId);
        if (userPO == null) {
            throw new SearchException("非系统用户，请刷新小程序");
        }
        MiniappUserPO miniAppUserPO = getPO(userId);
        if (miniAppUserPO == null) {
            throw new SearchException("未绑定为用户，请刷新小程序");
        }
        Map<String, Object> params = getHashMap(4);
        params.put("nickName", miniAppUpdateInfoVO.getNickName());
        params.put("avatarUrl", miniAppUpdateInfoVO.getAvatarUrl());
        params.put("userId", userId);
        miniappUserDao.updateInfo(params);
    }

    @Override
    public void updateIsInitAccount(String userId, Integer isInitAccount) {
        Map<String, Object> params = getHashMap(4);
        params.put("userId", userId);
        params.put("isInitAccount", isInitAccount);
        miniappUserDao.updateIsInitAccount(params);
    }

    @Override
    public List<MiniappUserPO> listPO(Map<String, Object> params) {
        return miniappUserDao.listPO(params);
    }

    @Override
    public List<MiniappUserPO> listPO(String userId) {
        return null;
    }

    @Override
    public List<MiniappUserPO> listPO(List<String> userIds) {
        Map<String, Object> params = getHashMap(2);
        params.put("userIds", userIds);
        return listPO(params);
    }

    @Override
    public MiniappUserPO getPO(Map<String, Object> params) {
        return miniappUserDao.getPO(params);
    }

    @Override
    public MiniappUserPO getPO(String userId) {
        Map<String, Object> params = getHashMap(2);
        params.put("userId", userId);
        return getPO(params);
    }

    @Override
    public MiniappUserPO getPO(String appId, String openId) {
        Map<String, Object> params = getHashMap(4);
        params.put("appId", appId);
        params.put("openId", openId);
        return getPO(params);
    }

    @Override
    public MiniappUserPO getPOByUserCode(String userCode) {
        Map<String, Object> params = getHashMap(2);
        params.put("userCode", userCode);
        return getPO(params);
    }

    @Override
    public List<MiniappUserPO> listPOByUserCodes(List<String> userCodes) {
        Map<String, Object> params = getHashMap(2);
        params.put("userCodes", userCodes);
        return listPO(params);
    }

    private void updateUserCode(String userCode, String openId) {
        Map<String, Object> params = getHashMap(6);
        params.put("userCode", userCode);
        params.put("appId", miniappProperties.getAppKey());
        params.put("openId", openId);
        miniappUserDao.updateUserCode(params);
    }

}
