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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.czg.account.dto.shopuser.ShopUserAddDTO;
import com.czg.account.dto.shopuser.ShopUserDetailDTO;
import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO;
import com.czg.account.dto.shopuser.ShopUserVipCardDTO;
import com.czg.account.entity.*;
import com.czg.account.service.*;
import com.czg.config.RedisCst;
import com.czg.exception.ApiNotPrintException;
import com.czg.market.entity.MkShopCouponRecord;
import com.czg.market.service.MkShopCouponRecordService;
import com.czg.market.service.TbMemberConfigService;
import com.czg.order.entity.OrderInfo;
import com.czg.order.service.OrderInfoService;
import com.czg.resp.CzgResult;
import com.czg.service.RedisService;
import com.czg.service.account.mapper.ShopConfigMapper;
import com.czg.system.entity.SysParams;
import com.czg.system.service.SysParamsService;
import com.czg.utils.AssertUtil;
import com.czg.utils.JoinQueryWrapper;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;


/**
 * 商户储值会员 服务层实现。
 *
 * @author Administrator
 * @since 2025-02-08
 */
@DubboService
public class UShopUserServiceImpl implements UShopUserService {
    @Resource
    private ShopUserService shopUserService;
    @DubboReference
    private SysParamsService sysParamsService;
    @DubboReference
    private OrderInfoService orderInfoService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private RedisService redisService;
    @DubboReference
    private MkShopCouponRecordService couponRecordService;
    @Resource
    private ShopInfoService shopInfoService;
    @Resource
    private ShopExtendService shopExtendService;
    @Resource
    private FreeDineConfigService freeDineConfigService;
    @Resource
    private ShopConfigMapper shopConfigMapper;
    @DubboReference
    private TbMemberConfigService memberConfigService;

    @Override
    public ShopUser getShopUserInfo(Long shopId, long userId) {
        return shopUserService.getShopUserInfo(shopId, userId);
    }

    @Override
    public Page<ShopUserVipCardDTO> vipCard(long userInfoId) {
        return shopUserService.getMapper().xmlPaginate("selectVipCard", PageUtil.buildPage(), new JoinQueryWrapper().eq(ShopUser::getUserId, userInfoId));
    }

    @Override
    public CzgResult<String> getCode(long userInfoId, long shopId) {
        shopId = shopInfoService.getMainIdByShopId(shopId);
        ShopUser shopUser = shopUserService.queryChain().eq(ShopUser::getMainShopId, shopId).eq(ShopUser::getUserId, userInfoId).one();
        AssertUtil.isNull(shopUser, "会员信息不存在");
        if (shopUser.getIsVip().equals(0)) {
            return CzgResult.failure("加入会员后使用");
        }
        String dynamicCode = generatePaymentCode(String.valueOf(shopId), String.valueOf(userInfoId));
        redisService.set(RedisCst.SHOP_USER_DYNAMIC_CODE + shopUser.getMainShopId() + ":" + dynamicCode, shopUser.getId(), 180);
        return CzgResult.success(dynamicCode);
    }

    public String generatePaymentCode(String shopId, String platformNumber) {
        // 获取当前毫秒时间戳的后四位
        String date = String.format("%04d", System.currentTimeMillis() % 10000);

        // 获取店铺ID的最后2位数字
        String shopIdLastTwoDigits = String.format("%02d", Integer.parseInt(shopId) % 100);

        // 生成一个6位随机数
        String randomPart = RandomUtil.randomNumbers(6);

        // 拼接生成支付码：毫秒后的四位 + 平台号码 + 店铺ID的最后2位 + 随机数

        return date + platformNumber + shopIdLastTwoDigits + randomPart;
    }

    public String generateCode(long shopId) {
        String code = "shop_user_code_val%d".formatted(shopId);
        SysParams sysParam = sysParamsService.getOne(new QueryWrapper().eq(SysParams::getParamCode, code));

        if (sysParam == null) {
            SysParams sysParams = new SysParams()
                    .setParamValue("1")
                    .setParamType(1)
                    .setCreateTime(DateUtil.date().toLocalDateTime())
                    .setParamCode(code);
            sysParamsService.save(sysParams);
            return generateRandomCode(1);
        }

        long parseLong = Long.parseLong(sysParam.getParamValue());
        long l = ++parseLong;
        sysParam.setParamValue(String.valueOf(l));
        sysParamsService.updateById(sysParam);

        return generateRandomCode(l);
    }

    // 使用Hutool生成十六进制代码并随机填充字母
    private String generateRandomCode(long value) {
        // 生成十六进制代码，确保为10位
        String hexCode = String.format("%010X", value);

        // 计算需要补充的字母数量
        int missingLength = 10 - hexCode.length();
        StringBuilder codeBuilder = new StringBuilder(hexCode);

        for (int i = 0; i < missingLength; i++) {
            // 生成随机字母
            char randomChar = RandomUtil.randomChar("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
            codeBuilder.append(randomChar);
        }

        return codeBuilder.toString();
    }


    @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 = shopUserService.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 = shopUserService.getOne(new QueryWrapper().eq(ShopUser::getMainShopId, mainId).eq(ShopUser::getUserId, oriInfo.getId()));
            if (oldUserInfo != null) {
                shopUserService.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(generateCode(shopId));
        }
        if (StrUtil.isBlank(shopUser.getBirthDay())) {
            shopUser.setBirthDay(null);
        }
        shopUser.setJoinTime(shopUser.getJoinTime() == null ? DateUtil.date().toLocalDateTime() : shopUser.getJoinTime());


        return shopUserService.saveOrUpdate(shopUser);
    }

    @Override
    public ShopUserDetailDTO getInfo(Long shopId, long userId) {
        Long mainId = shopInfoService.getMainIdByShopId(shopId);
        ShopUser shopUser = shopUserService.getShopUserInfo(mainId, userId);
        UserInfo userInfo = userInfoService.getById(userId);
        if (userInfo == null) {
            throw new ApiNotPrintException("用户信息不存在");
        }

        long couponNum = 0;
        if (shopUser == null) {
            shopUser = BeanUtil.copyProperties(userInfo, ShopUser.class);
            shopUser.setMainShopId(mainId);
            shopUser.setSourceShopId(shopId);
            shopUser.setId(null);
            shopUser.setUserId(userId);
            shopUserService.save(shopUser);
//            shopUser = getById(shopUser.getId());
        } else {
            couponNum = couponRecordService.count(new QueryWrapper()
                    .eq(MkShopCouponRecord::getUserId, shopUser.getUserId())
                    .eq(MkShopCouponRecord::getStatus, 0)
                    .eq(MkShopCouponRecord::getIsDel, 0)
            );
        }
        ShopUserDetailDTO shopUserDetailDTO = BeanUtil.copyProperties(shopUser, ShopUserDetailDTO.class);
        shopUserDetailDTO.setCouponNum(couponNum);

        ShopInfo shopInfo = shopInfoService.getById(shopId);
        if (shopInfo != null) {
            shopUserDetailDTO.setShopName(shopInfo.getShopName());
            shopUserDetailDTO.setShopId(shopInfo.getId());

            ShopConfig config = shopConfigMapper.selectOneByQuery(new QueryWrapper().eq(ShopConfig::getId, shopId));
            if (config != null) {
                BeanUtil.copyProperties(config, shopInfo, "id");
            }
            shopUserDetailDTO.setShopInfo(shopInfo);
            List<ShopExtend> shopExtends = shopExtendService.list(new QueryWrapper().eq(ShopExtend::getShopId, shopInfo.getId()));
            shopUserDetailDTO.setShopExtendList(shopExtends);
        }

        shopUserDetailDTO.setFreeDineConfig(freeDineConfigService.getConfig(shopInfoService.getMainIdByShopId(shopId)));
        shopUserDetailDTO.setPayPwd(userInfo.getPayPwd());
        shopUserDetailDTO.setUsePayPwd(userInfo.getUsePayPwd());
        return shopUserDetailDTO;
    }

    @Override
    public Long updateMoney(ShopUserMoneyEditDTO shopUserEditDTO) {
        return shopUserService.updateMoney(shopUserEditDTO);
    }
}
