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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.czg.account.dto.shopuser.ShopUserAddDTO;
import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO;
import com.czg.account.entity.ShopUser;
import com.czg.account.entity.ShopUserFlow;
import com.czg.account.entity.UserInfo;
import com.czg.account.service.ShopInfoService;
import com.czg.account.service.ShopUserFlowService;
import com.czg.account.service.ShopUserService;
import com.czg.account.service.UserInfoService;
import com.czg.enums.ShopUserFlowBizEnum;
import com.czg.exception.CzgException;
import com.czg.market.entity.MemberLevelConfig;
import com.czg.market.entity.SmsPushEventUser;
import com.czg.market.service.MemberLevelConfigService;
import com.czg.market.service.OrderInfoService;
import com.czg.market.service.TbMemberConfigService;
import com.czg.market.vo.InviteUserVO;
import com.czg.market.vo.MemberConfigVO;
import com.czg.order.entity.OrderInfo;
import com.czg.service.account.mapper.ShopUserMapper;
import com.czg.utils.FunUtils;
import com.czg.utils.PageUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.processor.util.StrUtil;
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 org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.List;


/**
 * 商户储值会员 服务层实现。
 *
 * @author Administrator
 * @since 2025-02-08
 */
@DubboService
public class ShopUserServiceImpl extends ServiceImpl<ShopUserMapper, ShopUser> implements ShopUserService {
    @Resource
    private ShopUserFlowService shopUserFlowService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private ShopInfoService shopInfoService;
    @DubboReference
    private OrderInfoService orderInfoService;
    @DubboReference
    private MemberLevelConfigService memberLevelConfigService;
    @DubboReference
    private TbMemberConfigService memberConfigService;

    private ShopUser getUserInfo(Long shopUserId) {
        ShopUser shopUser = queryChain().eq(ShopUser::getId, shopUserId).one();
        if (shopUser == null) {
            throw new CzgException("用户信息不存在");
        }
        return shopUser;
    }

    @Override
    public ShopUser getUserInfo(Long shopId, Long userId) {
        Long mainShopId = shopInfoService.getMainIdByShopId(shopId);
        return getOne(QueryWrapper.create().eq(ShopUser::getUserId, userId).eq(ShopUser::getMainShopId, mainShopId));
    }

    @Override
    public boolean updateInfo(ShopUser shopUser) {
        return super.updateById(shopUser);
    }

    @Override
    public void upMemberLevel(Long newMemberLevelId, Long oldMemberLevelId) {
        mapper.upMemberLevel(newMemberLevelId, oldMemberLevelId);
    }


    @Override
    public ShopUser getShopUserInfo(Long shopId, long userId) {
        ShopUser shopUser = getUserInfo(shopId, userId);
        if (shopUser == null) {
            Long mainShopId = shopInfoService.getMainIdByShopId(shopId);
            shopUser = new ShopUser();
            UserInfo userInfo = userInfoService.getById(userId);
            BeanUtil.copyProperties(userInfo, shopUser);
            shopUser.setMainShopId(mainShopId);
            shopUser.setSourceShopId(shopId);
            shopUser.setUserId(userId);
            shopUser.setId(null);
            if (StrUtil.isBlank(shopUser.getBirthDay())) {
                shopUser.setBirthDay(null);
            }
            save(shopUser);
        }
        if (shopUser.getMemberLevelId() != null) {
            MemberLevelConfig memberLevelConfig = memberLevelConfigService.getById(shopUser.getMemberLevelId());
            if (memberLevelConfig != null) {
                shopUser.setMemberName(memberLevelConfig.getName());
                MemberConfigVO configVO = memberConfigService.detail(memberLevelConfig.getShopId());
                if (configVO.getIsOpen().equals(1L)) {
                    shopUser.setIsMemberPrice(configVO.getIsMemberPrice());
                    shopUser.setDiscount(memberLevelConfig.getDiscount());
                } else {
                    shopUser.setIsMemberPrice(0);
                    shopUser.setDiscount(100);
                }
            }
        }
        return shopUser;
    }

    @Override
    public Page<InviteUserVO> getInviteUser(Long distributionUserId, Long shopId, Long shopUserId, Long distributionLevelId, Integer page, Integer size) {
        PageHelper.startPage(page, size);
        List<InviteUserVO> inviteUser = mapper.getInviteUser(distributionUserId, shopId, shopUserId, distributionLevelId);
        return PageUtil.convert(new PageInfo<>(inviteUser));
    }

    @Override
    @Transactional
    public Long updateMoney(ShopUserMoneyEditDTO shopUserEditDTO) {
        shopUserEditDTO.setMoney(shopUserEditDTO.getMoney().setScale(2, RoundingMode.DOWN));
        ShopUser userInfo = getUserInfo(shopUserEditDTO.getId());

        ShopUserFlow userFlow = new ShopUserFlow();
        int flag;
        if (shopUserEditDTO.getType() == 0) {
            if (shopUserEditDTO.getMoney().compareTo(userInfo.getAmount()) > 0) {
                //如果超额退款 则退为0
                flag = mapper.decrAccount(shopUserEditDTO.getId(), DateUtil.date().toLocalDateTime(), userInfo.getAmount());
            } else {
                flag = mapper.decrAccount(shopUserEditDTO.getId(), DateUtil.date().toLocalDateTime(), shopUserEditDTO.getMoney());
            }
        } else {
            flag = mapper.incrAccount(shopUserEditDTO.getId(), DateUtil.date().toLocalDateTime(), shopUserEditDTO.getMoney());
        }
        if (flag == 0) {
            throw new CzgException("增减用户余额操作失败");
        }

        if (userInfo.getAmount() == null) {
            userInfo.setAmount(BigDecimal.ZERO);
        }
        userFlow.setUserId(userInfo.getUserId());
        userFlow.setShopUserId(shopUserEditDTO.getId());
        userFlow.setShopId(userInfo.getSourceShopId());
        userFlow.setAmount(shopUserEditDTO.getType() == 0 ? shopUserEditDTO.getMoney().negate() : shopUserEditDTO.getMoney());
        userFlow.setBalance(shopUserEditDTO.getType() == 0 ? userInfo.getAmount().subtract(shopUserEditDTO.getMoney()) : userInfo.getAmount().add(shopUserEditDTO.getMoney()));
        if (userFlow.getBalance().compareTo(BigDecimal.ZERO) < 0) {
            userFlow.setBalance(BigDecimal.ZERO);
        }
        userFlow.setBizCode(shopUserEditDTO.getBizEnum().getCode());
        userFlow.setRemark(shopUserEditDTO.getRemark());
        userFlow.setRelationId(shopUserEditDTO.getRelationId());
        userFlow.setRechargeId(shopUserEditDTO.getRechargeId());
        shopUserFlowService.save(userFlow);
        //次数
        if (shopUserEditDTO.getType() == 0 && shopUserEditDTO.getBizEnum().equals(ShopUserFlowBizEnum.ORDER_PAY)) {
            ShopUser shopUser = new ShopUser();
            shopUser.setId(userInfo.getId());
            shopUser.setConsumeCount(userInfo.getConsumeCount() + 1);
            shopUser.setConsumeAmount(userInfo.getConsumeAmount().add(shopUserEditDTO.getMoney()));
            updateById(shopUser);
        } else if (shopUserEditDTO.getType() == 1 && shopUserEditDTO.getBizEnum().getCode().contains("In")) {
            ShopUser shopUser = new ShopUser();
            shopUser.setId(userInfo.getId());
            shopUser.setRechargeCount(userInfo.getRechargeCount() + 1);
            updateById(shopUser);
        }
        return userFlow.getId();
    }

    @Override
    public List<ShopUser> selectBirthdayUser(LocalDate current, Long mainShopId, String userType) {
        QueryWrapper queryWrapper = new QueryWrapper().isNotNull(ShopUser::getBirthDay)
                .eq(ShopUser::getMainShopId, mainShopId)
                .eq("DATE_FORMAT(birth_day, '%m-%d')", DateUtil.format(DateUtil.date(current), "MM-dd"));
        if ("vip".equals(userType)) {
            queryWrapper.eq(ShopUser::getIsVip, 1);
        }

        return list(queryWrapper);
    }

    @Override
    public void updateOneOrTwoAmount(Long shopUserId, Long shopId, BigDecimal bigDecimal, Integer isOne) {
        mapper.updateOneOrTwoAmount(shopUserId, shopId, bigDecimal, isOne);
    }


    @Override
    public List<ShopUser> getPushEventUserList(SmsPushEventUser smsPushEventUser) {
        Long mainShopId = shopInfoService.getMainIdByShopId(smsPushEventUser.getShopId());
        smsPushEventUser.checkIsAll();
        // 调用Mapper层查询
        List<ShopUser> shopUsers = mapper.selectPushEventUser(mainShopId,
                smsPushEventUser.getShopId(), smsPushEventUser);
        return shopUsers;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean join(Long shopId, Long userId, ShopUserAddDTO shopUserAddDTO) {
        Long mainId = shopInfoService.getMainIdByShopId(shopId);
        // 当前用户信息
        UserInfo userInfo = userInfoService.getById(userId);
        ShopUser shopUser = getShopUserInfo(shopId, userId);

        // 查询系统添加的会员
        UserInfo oriInfo = userInfoService.getOne(new QueryWrapper().eq(UserInfo::getPhone, shopUserAddDTO.getPhone()));
        if (oriInfo != null && !oriInfo.getId().equals(userId)) {
            // 迁移订单
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setUserId(userId);
            orderInfoService.update(orderInfo, new QueryWrapper().eq(OrderInfo::getUserId, oriInfo.getId()));
            // 删除多余用户信息
            userInfoService.removeById(oriInfo.getId());
            BeanUtil.copyProperties(oriInfo, userInfo, "id", "alipayOpenId", "wechatOpenId");

            ShopUser oldUserInfo = getOne(new QueryWrapper().eq(ShopUser::getMainShopId, mainId).eq(ShopUser::getUserId, oriInfo.getId()));
            if (oldUserInfo != null) {
                removeById(oldUserInfo.getId());
                BeanUtil.copyProperties(oldUserInfo, shopUser, "id", "userId");
            }
        }

        BeanUtil.copyProperties(shopUserAddDTO, shopUser, "accountPoints", "amount");
        BeanUtil.copyProperties(shopUserAddDTO, userInfo);
        userInfoService.updateById(userInfo);
        if (StrUtil.isBlank(shopUser.getCode())) {
            shopUser.setCode(ShopUser.generateCode());
        }
        if (StrUtil.isBlank(shopUser.getBirthDay())) {
            shopUser.setBirthDay(null);
        }
        shopUser.setNickName(userInfo.getNickName());
//        if (shopUser.getJoinTime() == null) {
//            shopUser.setJoinTime(LocalDateTime.now());
//        }
        boolean b = saveOrUpdate(shopUser);
        if (b) {
            FunUtils.transactionSafeRun(() -> memberConfigService.joinMemberByCondition(shopId, userId, shopUser));
        }
        return b;
    }
}
