package com.zanxiang.game.module.manage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zanxiang.game.module.base.pojo.enums.DeleteEnum;
import com.zanxiang.game.module.base.pojo.enums.GameCategoryEnum;
import com.zanxiang.game.module.base.pojo.enums.StatusEnum;
import com.zanxiang.game.module.manage.enums.GameStrategyTypeEnum;
import com.zanxiang.game.module.manage.pojo.dto.GameDTO;
import com.zanxiang.game.module.manage.pojo.dto.PayMerchantDTO;
import com.zanxiang.game.module.manage.pojo.params.GamePayStrategyAddUpdateParam;
import com.zanxiang.game.module.manage.pojo.params.GamePayStrategyListParam;
import com.zanxiang.game.module.manage.pojo.vo.GamePayStrategyListVO;
import com.zanxiang.game.module.manage.service.IGamePayStrategyService;
import com.zanxiang.game.module.manage.service.IGamePayWayService;
import com.zanxiang.game.module.manage.service.IGameService;
import com.zanxiang.game.module.manage.service.IPayMerchantService;
import com.zanxiang.game.module.mybatis.entity.GamePayStrategy;
import com.zanxiang.game.module.mybatis.mapper.GameStrategyMapper;
import com.zanxiang.module.util.bean.BeanUtil;
import com.zanxiang.module.util.exception.BaseException;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author : lingfeng
 * @time : 2022-06-23
 * @description : 游戏支付策略
 */
@Service
public class GamePayStrategyServiceImpl extends ServiceImpl<GameStrategyMapper, GamePayStrategy> implements IGamePayStrategyService {

    @Autowired
    private IGameService gameService;

    @Autowired
    private IPayMerchantService payMerchantService;

    @Autowired
    private IGamePayWayService gamePayWayService;

    @Override
    public boolean addOrUpdate(GamePayStrategyAddUpdateParam param) {
        Long id = param.getId();
        GamePayStrategy gamePayStrategy;
        if (id == null) {
            this.gamePayStrategyNameCheck(param.getName());
            gamePayStrategy = GamePayStrategy.builder()
                    .name(param.getName())
                    .type(param.getType())
                    .gameId(param.getGameId())
                    .totalPayAmount(param.getTotalPayAmount())
                    .mouthPayAmount(param.getMouthPayAmount())
                    .weakerPayAmount(param.getWeakerPayAmount())
                    .dayPayAmount(param.getDayPayAmount())
                    .status(StatusEnum.YES.getCode())
                    .isDelete(DeleteEnum.NO.getCode())
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .build();
        } else {
            gamePayStrategy = super.getById(id);
            if (gamePayStrategy == null) {
                throw new BaseException("参数错误, 游戏支付配置信息不存在");
            }
            if (!Objects.equals(gamePayStrategy.getName(), param.getName())) {
                this.gamePayStrategyNameCheck(param.getName());
            }
            gamePayStrategy.setName(param.getName());
            gamePayStrategy.setType(param.getType());
            gamePayStrategy.setGameId(param.getGameId());
            gamePayStrategy.setTotalPayAmount(param.getTotalPayAmount());
            gamePayStrategy.setMouthPayAmount(param.getMouthPayAmount());
            gamePayStrategy.setWeakerPayAmount(param.getWeakerPayAmount());
            gamePayStrategy.setDayPayAmount(param.getDayPayAmount());
            gamePayStrategy.setUpdateTime(LocalDateTime.now());
        }
        return super.saveOrUpdate(gamePayStrategy);
    }

    private void gamePayStrategyNameCheck(String name) {
        long count = super.count(new LambdaQueryWrapper<GamePayStrategy>()
                .eq(GamePayStrategy::getName, name));
        if (count > 0) {
            throw new BaseException("策略名称重复");
        }
    }

    @Override
    public IPage<GamePayStrategyListVO> pageList(GamePayStrategyListParam param) {
        Map<Long, GameDTO> gameMap = gameService.gameMap();
        Map<String, PayMerchantDTO> payMerchantMap = payMerchantService.payMerchantMap();
        return super.page(param.toPage(), new LambdaQueryWrapper<GamePayStrategy>()
                .like(Strings.isNotBlank(param.getName()), GamePayStrategy::getName, param.getName())
                .eq(param.getType() != null, GamePayStrategy::getType, param.getType())
                .eq(param.getGameId() != null, GamePayStrategy::getGameId, param.getGameId())
                .eq(param.getStatus() != null, GamePayStrategy::getStatus, param.getStatus())
                .orderByDesc(GamePayStrategy::getCreateTime))
                .convert(gamePayStrategy -> this.toVO(gameMap, gamePayStrategy, payMerchantMap));
    }

    private GamePayStrategyListVO toVO(Map<Long, GameDTO> gameMap, GamePayStrategy gamePayStrategy,
                                       Map<String, PayMerchantDTO> payMerchantMap) {
        GamePayStrategyListVO gamePayStrategyListVO = BeanUtil.copy(gamePayStrategy, GamePayStrategyListVO.class);
        if (gamePayStrategyListVO == null) {
            return null;
        }
        gamePayStrategyListVO.setTypeName(GameStrategyTypeEnum.getNameByType(gamePayStrategyListVO.getType()));
        GameDTO gameDTO = gameMap.get(gamePayStrategyListVO.getGameId());
        if (gameDTO != null) {
            gamePayStrategyListVO.setGameName(gameDTO.getName());
            GameCategoryEnum gameCategoryEnum = GameCategoryEnum.getGameCategory(gameDTO.getCategory());
            if (gameCategoryEnum != null) {
                gamePayStrategyListVO.setGameCategory(gameCategoryEnum.getName());
                gamePayStrategyListVO.setGameCategoryId(gameCategoryEnum.getId());
            }
        }
        Set<String> gameMerchantNoSet = gamePayWayService.getGameMerchantNo(gamePayStrategyListVO.getGameId());
        Map<String, String> merchantMap = new HashMap<>(gameMerchantNoSet.size());
        gameMerchantNoSet.forEach(merchantNo -> {
            PayMerchantDTO payMerchantDTO = payMerchantMap.get(merchantNo);
            if (payMerchantDTO != null) {
                merchantMap.put(payMerchantDTO.getMerchantNo(), payMerchantDTO.getMerchantName());
            }
        });
        gamePayStrategyListVO.setPayMerchantMap(merchantMap);
        return gamePayStrategyListVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean statusUpdate(Long id, Integer status) {
        return super.update(new LambdaUpdateWrapper<GamePayStrategy>()
                .set(GamePayStrategy::getStatus, status)
                .set(GamePayStrategy::getUpdateTime, LocalDateTime.now())
                .eq(GamePayStrategy::getId, id));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(Long id) {
        return super.removeById(id);
    }
}
