package com.czg.service.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.czg.account.dto.user.userinfo.UserInfoAssetsSummaryDTO;
import com.czg.account.dto.user.userinfo.UserInfoDTO;
import com.czg.account.dto.user.userinfo.UserInfoEditDTO;
import com.czg.account.dto.user.userinfo.UserInfoPwdEditDTO;
import com.czg.account.entity.ShopUser;
import com.czg.account.entity.UserInfo;
import com.czg.account.service.ShopInfoService;
import com.czg.account.service.UserInfoService;
import com.czg.config.RedisCst;
import com.czg.exception.CzgException;
import com.czg.service.RedisService;
import com.czg.service.account.mapper.ShopUserMapper;
import com.czg.service.account.mapper.UserInfoMapper;
import com.czg.service.account.util.AcAccountUtil;
import com.czg.system.service.SmsService;
import com.czg.utils.CzgRandomUtils;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2025-02-11
 */
@DubboService
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    @Resource
    private ShopUserMapper shopUserMapper;
    @Resource
    private ShopInfoService shopInfoService;
    @Resource
    private RedisService redisService;
    @Resource
    private AcAccountUtil acAccountUtil;

    @DubboReference
    private SmsService smsService;

    @Override
    public UserInfoDTO getInfo(long userInfoId) {
        UserInfo userInfo = queryChain().eq(UserInfo::getId, userInfoId).one();
        if (userInfo == null) {
            throw new CzgException("用户信息不存在");
        }
        initAc(userInfo);
        UserInfoAssetsSummaryDTO assetsSummaryDTO = shopUserMapper.selectAssetsSummary(userInfoId);
        UserInfoDTO userInfoDTO = BeanUtil.copyProperties(userInfo, UserInfoDTO.class);
        userInfoDTO.setAssetsSummary(assetsSummaryDTO);
        return userInfoDTO;
    }
    @Override
    public Boolean updateInfo(long shopId, long userId, UserInfoEditDTO userInfoEditDTO) {
        UserInfo userInfo = getById(userId);
        BeanUtil.copyProperties(userInfoEditDTO, userInfo);
        if (updateById(userInfo)) {
            if (shopId != 0L) {
                ShopUser shopUser = BeanUtil.copyProperties(userInfo, ShopUser.class);
                Long mainIdByShopId = shopInfoService.getMainIdByShopId(shopId);
                return shopUserMapper.updateByQuery(shopUser, new QueryWrapper().eq(ShopUser::getMainShopId, mainIdByShopId).eq(ShopUser::getUserId, userId)) > 0;
            }
            return true;
        }
        return false;
    }

    @Override
    public Boolean getCode(Long userId, String type) {
        UserInfo userInfo = queryChain().eq(UserInfo::getId, userId).one();
        if (StrUtil.isBlank(userInfo.getPhone())) {
            throw new CzgException("账号未绑定手机号");
        }
        String code = CzgRandomUtils.randomNumber(6, false);
        redisService.set("%s%s:%s".formatted(RedisCst.SMS_CODE, userInfo.getPhone(), type), code, 300);
        smsService.sendCode(userInfo.getPhone(), code);
        return true;
    }

    @Override
    public Boolean updatePwd(long userId, UserInfoPwdEditDTO userInfoPwdEditDTO) {
        UserInfo userInfo = queryChain().eq(UserInfo::getId, userId).one();
        String key = "%s%s:%s".formatted(RedisCst.SMS_CODE, userInfo.getPhone(), "wxMiniPwd");
        Object val = redisService.get(key);
        if (val instanceof String code && !userInfoPwdEditDTO.getCode().equals(code)) {
            throw new CzgException("验证码错误");
        }

        if (StrUtil.isNotBlank(userInfoPwdEditDTO.getCheckPayPwd())) {
            userInfo.setPayPwd(SecureUtil.md5(userInfoPwdEditDTO.getPayPwd()));
        }
        userInfo.setUsePayPwd(userInfoPwdEditDTO.getUsePayPwd());
        boolean b = updateById(userInfo);
        if (b) {
            redisService.del(key);
        }
        return b;
    }

    @Override
    public void updateDistributionAmount(long userId, BigDecimal amount) {
        int b = mapper.updateAmount(userId, amount);
        if (b <= 0) {
            throw new CzgException("更新分销金额失败");
        }
    }

    /**
     * 初始化用户微信公众号二维码\
     */
    @Override
    public void initAc(UserInfo userInfo) {
        if (userInfo.getIsAc() == null) {
            userInfo.setIsAc(0);
        }
        if (userInfo.getIsAc() == 0 &&
                (StrUtil.isBlank(userInfo.getWechatAcQrcode()) || userInfo.getAcQrcodeValidTime() == null || userInfo.getAcQrcodeValidTime().isBefore(LocalDateTime.now()))) {
            String qrCode = acAccountUtil.createQrCode(userInfo.getId());
            if (StrUtil.isNotBlank(qrCode)) {
                userInfo.setWechatAcQrcode(qrCode);
                userInfo.setAcQrcodeValidTime(LocalDateTime.now().plusDays(29));
                updateById(userInfo);
            }
        }
    }
}
