package ink.wgink.module.wechat.service.official.account.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.module.wechat.dao.official.account.IOfficialAccountUserDao;
import ink.wgink.module.wechat.enums.XmlEventTypeEnum;
import ink.wgink.module.wechat.pojo.dtos.official.account.OfficialAccountUserDTO;
import ink.wgink.module.wechat.pojo.pos.official.account.OfficialAccountUserPO;
import ink.wgink.module.wechat.pojo.vos.official.account.OfficialAccountUserVO;
import ink.wgink.module.wechat.service.official.account.IOfficialAccountUserService;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.properties.wechat.official.account.OfficialAccountProperties;
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.map.HashMapUtil;
import ink.wgink.util.string.WStringUtil;
import ink.wgink.util.verification.share.ShareCodeUtil;
import org.apache.commons.lang3.StringUtils;
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.List;
import java.util.Map;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: OfficialAccountUserServiceImpl
 * @Description: 公众号用户
 * @Author: wanggeng
 * @Date: 2021/4/28 6:15 下午
 * @Version: 1.0
 */
@Service
public class OfficialAccountUserServiceImpl extends DefaultBaseService implements IOfficialAccountUserService {

    @Value("${user.default-password:" + ISystemConstant.DEFAULT_PASSWORD + "}")
    private String defaultPassword;
    @Autowired
    private IOfficialAccountUserDao officialAccountUserDao;
    @Autowired
    private OfficialAccountProperties officialAccountProperties;
    @Autowired
    private IUserService userService;

    @Override
    public void save(OfficialAccountUserVO officialAccountUserVO) {
        OfficialAccountUserPO officialAccountUserPO = getPO(officialAccountProperties.getAppId(), officialAccountUserVO.getOpenId());
        if (officialAccountUserPO != null) {
            updateStatus(officialAccountUserVO.getOpenId(), XmlEventTypeEnum.SUBSCRIBE);
            return;
        }

        // 创建随机用户
        String openId = officialAccountUserVO.getOpenId();
        // 随机字符串
        String randomUserName = WStringUtil.randomSubStr(openId, 6);
        UserVO userVO = new UserVO();
        userVO.setUserUsername(OFFICIAL_ACCOUNT_RANDOM_USER_PREFIX + randomUserName);
        userVO.setUserName("微信" + randomUserName);
        userVO.setUserPassword(defaultPassword);
        userVO.setUserState(0);
        userVO.setUserType(2);
        String userId = userService.saveAndReturnId(userVO, true);

        String time = DateUtil.getTime();
        officialAccountUserVO.setAppId(officialAccountProperties.getAppId());
        // 用户码，用于绑定账号时使用
        // 绑定用户
        officialAccountUserVO.setUserId(userId);
        // 标记为初始化账号
        officialAccountUserVO.setIsInitAccount(1);
        Map<String, Object> params = HashMapUtil.beanToMap(officialAccountUserVO);
        // 标记订阅状态
        params.put("status", XmlEventTypeEnum.SUBSCRIBE.getType());
        params.put("gmtCreate", time);
        params.put("gmtModified", time);
        officialAccountUserDao.save(params);
        // 更新用户码
        Long id = Long.parseLong(params.get("id").toString());
        String userCode = ShareCodeUtil.gen(id);
        updateUserCode(openId, userCode);
    }


    @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.isEmpty()) {
            return;
        }
        Map<String, Object> params = getHashMap(4);
        params.put("userIds", userIds);
        officialAccountUserDao.delete(params);
    }

    @Override
    public void updateStatus(String openId, XmlEventTypeEnum xmlEventTypeEnum) {
        String time = DateUtil.getTime();
        Map<String, Object> params = getHashMap(6);
        params.put("status", xmlEventTypeEnum.getType());
        params.put("gmtModified", time);
        params.put("appId", officialAccountProperties.getAppId());
        params.put("openId", openId);
        officialAccountUserDao.update(params);
    }

    @Override
    public void updateIsInitAccount(String openId, int isInitAccount) {
        Map<String, Object> params = getHashMap(4);
        params.put("appId", officialAccountProperties.getAppId());
        params.put("openId", openId);
        params.put("isInitAccount", isInitAccount);
        officialAccountUserDao.updateIsInitAccount(params);
    }

    @Override
    public OfficialAccountUserDTO get(Map<String, Object> params) {
        return officialAccountUserDao.get(params);
    }

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

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

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

    @Override
    public List<OfficialAccountUserDTO> list(Map<String, Object> params) {
        return officialAccountUserDao.list(params);
    }

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

    @Override
    public SuccessResultList<List<OfficialAccountUserDTO>> listPage(ListPage page) {
        PageHelper.startPage(page.getPage(), page.getRows());
        List<OfficialAccountUserDTO> officialAccountUserDTOs = officialAccountUserDao.list(page.getParams());
        PageInfo<OfficialAccountUserDTO> pageInfo = new PageInfo<>(officialAccountUserDTOs);
        return new SuccessResultList<>(officialAccountUserDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
    }

    @Override
    public String getUserCodeByOpenId(String openId) {
        OfficialAccountUserPO officialAccountUserPO = getPO(officialAccountProperties.getAppId(), openId);
        return officialAccountUserPO.getUserCode();
    }

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

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

    /**
     * 更新用户码（邀请码）
     *
     * @param openId
     * @param userCode
     */
    private void updateUserCode(String openId, String userCode) {
        Map<String, Object> params = getHashMap(6);
        params.put("appId", officialAccountProperties.getAppId());
        params.put("openId", openId);
        params.put("userCode", userCode);
        officialAccountUserDao.updateUserCode(params);
    }

}
