package com.bonus.canteen.core.account.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.bonus.canteen.core.account.business.AccWalletInfoBusiness;
import com.bonus.canteen.core.account.domain.AccWalletInfo;
import com.bonus.canteen.core.account.domain.WalletUpdateDTO;
import com.bonus.canteen.core.account.domain.vo.AccWalletInfoVO;
import com.bonus.canteen.core.account.mapper.AccWalletInfoMapper;
import com.bonus.canteen.core.account.service.IAccTradeService;
import com.bonus.canteen.core.account.service.IAccTradeWalletDetailService;
import com.bonus.canteen.core.account.service.IAccWalletInfoService;
import com.bonus.canteen.core.account.utils.AccRedisUtils;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.security.utils.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 钱包详情信息Service业务层处理
 * 
 * @author xsheng
 * @date 2025-04-05
 */
@Service
public class AccWalletInfoServiceImpl implements IAccWalletInfoService {
    private static final Logger log = LoggerFactory.getLogger(AccWalletInfoServiceImpl.class);

    @Autowired
    private AccWalletInfoMapper accWalletInfoMapper;
    @Autowired
    IAccTradeService accTradeService;
    @Autowired
    IAccTradeWalletDetailService accTradeWalletDetailService;
    @Autowired
    AccWalletInfoBusiness accWalletInfoBusiness;

    /**
     * 查询钱包详情信息
     * 
     * @param userId 钱包详情信息主键
     * @return 钱包详情信息
     */
    @Override
    public List<AccWalletInfo> selectAccWalletInfoByUserId(Long userId) {
        return accWalletInfoMapper.selectAccWalletInfoByUserId(userId);
    }

    @Override
    public AccWalletInfo selectAccWalletInfoByUserIdAndWalletType(Long userId, Integer walletType) {
        return accWalletInfoMapper.selectAccWalletInfoByUserIdAndWalletType(userId, walletType);
    }

    /**
     * 查询钱包详情信息列表
     * 
     * @param accWalletInfo 钱包详情信息
     * @return 钱包详情信息
     */
    @Override
    public List<AccWalletInfo> selectAccWalletInfoList(AccWalletInfo accWalletInfo) {
        return accWalletInfoMapper.selectAccWalletInfoList(accWalletInfo);
    }

    /**
     * 新增钱包详情信息
     * 
     * @param accWalletInfo 钱包详情信息
     * @return 结果
     */
    @Override
    public int insertAccWalletInfo(AccWalletInfo accWalletInfo) {
        accWalletInfo.setCreateTime(DateUtils.getNowDate());
        try {
            return accWalletInfoMapper.insertAccWalletInfo(accWalletInfo);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    @Override
    public int batchInsertAccWalletInfo(List<AccWalletInfo> accWalletInfos) {
        accWalletInfos.stream().forEach(o -> o.setCreateBy(SecurityUtils.getUsername()));
        try {
            return accWalletInfoMapper.batchInsertAccWalletInfo(accWalletInfos);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 批量删除钱包详情信息
     * 
     * @param userIds 需要删除的钱包详情信息主键
     * @return 结果
     */
    @Override
    public int deleteAccWalletInfoByUserIds(Long[] userIds) {
        return accWalletInfoMapper.deleteAccWalletInfoByUserIds(userIds);
    }

    /**
     * 删除钱包详情信息信息
     * 
     * @param userId 钱包详情信息主键
     * @return 结果
     */
    @Override
    public int deleteAccWalletInfoByUserId(Long userId) {
        return accWalletInfoMapper.deleteAccWalletInfoByUserId(userId);
    }

    public Map<Long, List<AccWalletInfoVO>> selectAccWalletInfoByUserIds(List<Long> userIds) {
        List<AccWalletInfoVO> walletInfoList = accWalletInfoMapper.selectAccWalletInfoByUserIds(userIds);
        return walletInfoList.stream()
                .collect(Collectors.groupingBy(AccWalletInfoVO::getUserId));
    }

    @Override
    public void updateMinBalance(List<Long> userIds, Integer walletType, BigDecimal minBalance) {
        if (ObjectUtil.isNull(minBalance)) {
            log.warn("修改钱包最低余额限制-最低余额不能为空");
            return;
        }

        if (ObjectUtil.isNull(walletType)) {
            log.warn("修改钱包最低余额限制-钱包编号为空");
            return;
        }

        if (ObjectUtil.isEmpty(userIds)) {
            log.warn("修改钱包最低余额限制-用户编号为空");
            return;
        }

        try {
            accWalletInfoMapper.updateMinBalanceByUserId(minBalance, walletType, userIds,
                    SecurityUtils.getUserId().toString(), DateUtils.toLocalDateTime(new Date()));
        } catch (Exception e) {
            log.error("修改钱包最低余额限制失败", e);
            throw new ServiceException("修改钱包最低余额限制失败");
        }
    }

    @Override
    public void addAccWalletBalance(WalletUpdateDTO walletUpdateDTO) {
        if(!walletUpdateDTO.isBatch()) {
            if(Objects.isNull(walletUpdateDTO.getUserId())) {
                throw new ServiceException("用户编号不能为空");
            }
            AccRedisUtils.lockUpdateAccWalletBalance(walletUpdateDTO.getUserId());
        }
        try {
            accWalletInfoBusiness.addAccWalletBalance(walletUpdateDTO);
        }catch (Exception ex) {
            log.error("钱包充值失败", ex);
            throw new ServiceException(ex.getMessage());
        }finally {
            if(!walletUpdateDTO.isBatch()) {
                AccRedisUtils.unlockUpdateAccWalletBalance(walletUpdateDTO.getUserId());
            }
        }
    }

    @Override
    public void clearAccWalletBalance(WalletUpdateDTO walletUpdateDTO) {
        if(!walletUpdateDTO.isBatch()) {
            if(Objects.isNull(walletUpdateDTO.getUserId())) {
                throw new ServiceException("用户编号不能为空");
            }
            AccRedisUtils.lockUpdateAccWalletBalance(walletUpdateDTO.getUserId());
        }
        try {
            accWalletInfoBusiness.clearAccWalletBalance(walletUpdateDTO);

        }catch (Exception ex) {
            log.error("钱包扣钱失败", ex);
            throw new ServiceException(ex.getMessage());
        }finally {
            if(!walletUpdateDTO.isBatch()) {
                AccRedisUtils.unlockUpdateAccWalletBalance(walletUpdateDTO.getUserId());
            }
        }
    }

//    private void clearAccWalletInfo(WalletBalanceOperation operation) {
//        accWalletInfoMapper.clearAccWalletInfo(operation.getUserId(), operation.getWalletId(),
//        SecurityUtils.getUserId().toString(), DateUtils.toLocalDateTime(new Date()));
//    }


}
