package com.seer.teach.pay.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.common.enums.CoinConfigEnableEnum;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.common.utils.MoneyUtil;
import com.seer.teach.pay.entity.CoinConfigEntity;
import com.seer.teach.pay.mapper.CoinConfigMapper;
import com.seer.teach.pay.service.ICoinConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

/**
 * <p>
 * 学豆配置表 服务实现类
 * </p>
 *
 * @author Wang
 * @since 2025-06-17
 */
@Slf4j
@Service
public class CoinConfigServiceImpl extends ServiceImpl<CoinConfigMapper, CoinConfigEntity> implements ICoinConfigService {

    @Override
    public boolean create(CoinConfigEntity coinConfigEntity) {
        // 保存新的硬币配置实体
        coinConfigEntity.setIsUsed(CoinConfigEnableEnum.ENABLED.getCode());
        boolean save = super.save(coinConfigEntity);
        log.info("保存结果:{}", save);
        // 获取所有学豆，排除当前保存的实体，因为我们要将其他学豆标记为不可用
        List<CoinConfigEntity> oldCoinConfigEntities = super.list().stream()
                .filter(coinConfig -> coinConfig.getId().intValue() != coinConfigEntity.getId().intValue())
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(oldCoinConfigEntities)) {
            // 批量更新，将原来的配置更新为不可用
            for (CoinConfigEntity coinConfig : oldCoinConfigEntities) {
                coinConfig.setIsUsed(CoinConfigEnableEnum.DISABLED.getCode());
            }
            boolean updateBatchResult = super.updateBatchById(oldCoinConfigEntities);
            log.info("批量更新结果:{}", updateBatchResult);
        }
        return save;
    }

    @Override
    public boolean update(CoinConfigEntity coinConfigEntity) {
        CoinConfigEntity configEntity = getById(coinConfigEntity.getId());
        AssertUtils.notNull(configEntity, ResultCodeEnum.COIN_CONFIG_NOT_FOUND);

        boolean update = update(new LambdaUpdateWrapper<>(CoinConfigEntity.class).set(CoinConfigEntity::getExchangeRatio, coinConfigEntity.getExchangeRatio())
                .set(CoinConfigEntity::getCoinName, coinConfigEntity.getCoinName())
                .set(CoinConfigEntity::getIsUsed, coinConfigEntity.getIsUsed())
                .set(CoinConfigEntity::getIsUsed, coinConfigEntity.getIsUsed())
                .eq(CoinConfigEntity::getId, coinConfigEntity.getId()));
        log.info("管理员[{}]更新结果:{}", StpUtil.getLoginIdAsInt(), update);
        return update;
    }

    @Override
    public CoinConfigEntity getActiveAndLatestCoinConfig() {
        return super.getOne(
                new LambdaQueryWrapper<CoinConfigEntity>()
                        .eq(CoinConfigEntity::getIsUsed, 1)
                        .orderByDesc(CoinConfigEntity::getCreateTime)
        );
    }

    @Override
    public BigDecimal convertCoinToAmount(BigDecimal coin) {
        CoinConfigEntity coinConfig = this.getActiveAndLatestCoinConfig();
        AssertUtils.notNull(coinConfig, ResultCodeEnum.COIN_CONFIG_NOT_FOUND);
        log.info("获取学豆配置:{}", coinConfig);
        return this.convertCoinToAmount(coin, coinConfig);
    }

    @Override
    public BigDecimal convertCoinToAmount(String coin, CoinConfigEntity coinConfig) {
        BigDecimal coinBigDecimal = new BigDecimal(coin);
        AssertUtils.isTrue(coinConfig.getExchangeRatio().compareTo(BigDecimal.ZERO) != 0, ResultCodeEnum.COIN_EXCHANGE_RATIO_NOT_ZERO);
        BigDecimal amount = MoneyUtil.convertCoinToAmount(coinBigDecimal, coinConfig.getExchangeRatio());
        log.info("学豆[{}]转换金额:{}", coinBigDecimal, amount);
        return amount;
    }

    @Override
    public BigDecimal convertCoinToAmount(BigDecimal coin, CoinConfigEntity coinConfig) {
        AssertUtils.isTrue(coinConfig.getExchangeRatio().compareTo(BigDecimal.ZERO) != 0, ResultCodeEnum.COIN_EXCHANGE_RATIO_NOT_ZERO);
        BigDecimal amount = MoneyUtil.convertCoinToAmount(coin, coinConfig.getExchangeRatio());
        log.info("convertCoinToAmount学豆[{}]转换金额:{}", coin, amount);
        return amount;
    }

    @Override
    public BigDecimal convertAmountToCoin(BigDecimal amount, Integer coinConfigId) {
        CoinConfigEntity coinConfig = super.getById(coinConfigId);
        AssertUtils.notNull(coinConfig, ResultCodeEnum.COIN_CONFIG_NOT_FOUND);
        return convertAmountToCoin(amount, coinConfig);
    }

    @Override
    public BigDecimal convertAmountToCoin(BigDecimal amount, CoinConfigEntity coinConfig) {
        AssertUtils.notNull(coinConfig, ResultCodeEnum.COIN_CONFIG_NOT_FOUND);
        BigDecimal coin = MoneyUtil.convertAmountToCoin(amount, coinConfig.getExchangeRatio());
        log.info("金额[{}]转换学豆:{}", amount, coin);
        return coin;
    }
}