package com.ym.mec.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mysql.cj.protocol.MessageSender;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.biz.dal.dao.RedemptionCodeDao;
import com.ym.mec.biz.dal.entity.AppRedemptionCode;
import com.ym.mec.biz.dal.enums.*;
import com.ym.mec.biz.service.AppRedemptionCodeService;
import com.ym.mec.biz.service.SysMessageService;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.WrapperUtil;
import com.ym.mec.thirdparty.message.MessageSenderPluginContext;
import com.ym.mec.util.excel.POIUtil;
import com.ym.mec.util.ini.IniFileUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;

/**
 * 兑换码分配表(RedemptionCode)表服务实现类
 *
 * @author makejava
 * @since 2021-12-27 14:27:57
 */
@Service("redemptionCodeService")
public class AppRedemptionCodeServiceImpl extends ServiceImpl<RedemptionCodeDao, AppRedemptionCode>
        implements AppRedemptionCodeService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AppRedemptionCodeServiceImpl.class);

    @Autowired
    private RedemptionCodeDao redemptionCodeDao;

    @Autowired
    private SysUserFeignService sysUserFeignService;

    @Autowired
    private SysMessageService sysMessageService;

    private final static Logger logger = LoggerFactory.getLogger(AppRedemptionCodeServiceImpl.class);

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importRedemptionCode(MultipartFile file) throws Exception {
        Map<String, List<Map<String, Object>>> sheetsListMap = POIUtil.importExcel(
                new ByteArrayInputStream(file.getBytes()), 0, file.getOriginalFilename());

        InputStream inputStream = new ClassPathResource("columnMapper.ini").getInputStream();
        Map<String, String> columns = IniFileUtil.readIniFile(inputStream, TemplateTypeEnum.REDEMPTIONCODE.getMsg());

        List<AppRedemptionCode> redemptionCodesList = new ArrayList<>();
        for (String e : sheetsListMap.keySet()) {
            List<Map<String, Object>> sheet = sheetsListMap.get(e);
            for (Map<String, Object> row : sheet) {
                if (row.size() == 0) {
                    continue;
                }

                JSONObject objectMap = new JSONObject();
                for (String s : row.keySet()) {
                    if (!columns.containsKey(s)) {
                        continue;
                    }
                    String columnValue = columns.get(s);
                    if (null == row.get(s) || StringUtils.isBlank(row.get(s).toString())) {
                        LOGGER.error("导入异常：参数{}不可为空 param:{}", columnValue, objectMap);
                        continue;
                    }
                    objectMap.put(columnValue, row.get(s));
                }
                try {
                    AppRedemptionCode redemptionCode = JSONObject.parseObject(objectMap.toJSONString(),
                                                                              AppRedemptionCode.class);
                    if (redemptionCode.getCode() == null) continue;
                    redemptionCodesList.add(redemptionCode);
                } catch (Exception ex) {
                    throw new BizException("导入数据出错:" + ex, ex);
                }
            }
        }
        try {
            redemptionCodeDao.insertBatch(redemptionCodesList);
        } catch (DuplicateKeyException dupKeyEx) {
            logger.error("数据导入重复: " + dupKeyEx.getCause());
            throw new BizException("数据重复:" + dupKeyEx.getCause());
        } catch (Exception ex) {
            throw new BizException("导入数据出错:" + ex, ex);
        }
        return "成功导入 " + redemptionCodesList.size() + "条";
    }

    @Override
    public AppRedemptionCode allocation(Integer userId) {
        AppRedemptionCode redemptionCode = redemptionCodeDao.getByUserId(userId);
        if (redemptionCode != null) { // 如果有由直接返回， 不在分配
            redemptionCode.setStatus("用户已分配");
            return redemptionCode;
        }
        redemptionCode = redemptionCodeDao.findFirstNull();
        if (redemptionCode == null) {
            return null;
        }
        redemptionCode.setUserId(userId);
        int retCount = redemptionCodeDao.updateById(redemptionCode);
        if (retCount == 0) {
            return null;
        }
        return redemptionCode;
    }

    @Override
    public void checkLowVolume() {
        Integer volume = redemptionCodeDao.findNull();
        if (volume == null || volume < 10000) {
            Map<Integer, String> receivers = new HashMap<>(1);
            receivers.put(101223, "15623294575");
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS,
                                               MessageTypeEnum.APP_REDEMPTION_CODE, receivers, null, 0, null, null,
                                               volume, null, null);
        }
    }
}

