package com.iformall.controller.mem;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.afterturn.easypoi.handler.impl.ExcelDataHandlerDefaultImpl;
import cn.afterturn.easypoi.handler.inter.IExcelDataHandler;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.iformall.domain.po.MallUserInfo;
import com.iformall.domain.po.WxShop;
import com.iformall.domain.vo.WxBillDailyVo;
import com.iformall.enums.EnumDelStatus;
import com.iformall.enums.EnumShopStatus;
import com.iformall.mapper.WxShopMapper;
import com.iformall.service.WxBillDailyService;
import org.apache.shiro.session.UnknownSessionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class BillDailyAsyncTask {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxBillDailyService wxBillDailyService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    WxShopMapper wxShopMapper;

    private class BillDailyExcelHandler extends ExcelDataHandlerDefaultImpl<WxBillDailyVo> {
        @Override
        public Object importHandler(WxBillDailyVo obj, String name, Object value) {
            if (value == null) {
                value = "";
            }
            System.out.println(name + " + " + value.toString());
            return super.importHandler(obj, name, value);
        }

    }

    private void set_redis_value(String importKey, String allCount, String allSuccessCount, String processCount, String failCount, boolean fail) {
        stringRedisTemplate.opsForHash().put(importKey, "allCount", allCount);
        stringRedisTemplate.opsForHash().put(importKey, "allSuccessCount", allSuccessCount);
        stringRedisTemplate.opsForHash().put(importKey, "processCount", processCount);
        stringRedisTemplate.opsForHash().put(importKey, "failCount", failCount);
        if (fail) {
            stringRedisTemplate.expire(importKey, 10, TimeUnit.SECONDS);
        }
    }

    @Async
    public void importExcelData(File file, MallUserInfo user, String importKey, String tenantId) {
        ImportParams params = new ImportParams();
        // 需要验证
        params.setImportFields(new String[]{"商铺号*", "费用类型*", "实际应收金额(元)*", "实收金额(元)*", "缴款截止日期*", "租赁商铺类型*"});
        IExcelDataHandler<WxBillDailyVo> handler = new BillDailyAsyncTask.BillDailyExcelHandler();
        handler.setNeedHandlerFields(new String[]{"商铺号*", "费用类型*", "实际应收金额(元)*", "实收金额(元)*", "缴款截止日期*", "租赁商铺类型*"});
        params.setNeedVerify(true);

        ExcelImportResult<WxBillDailyVo> datalist = null;

        try {
            datalist = ExcelImportUtil.importExcelMore(file, WxBillDailyVo.class, params);
        } catch (Exception e) {
            set_redis_value(importKey, "1", "0", "0", "1", true);
            logger.error(e.getMessage());
            // 删除缓存文件
            file.delete();
            return;
        }
        // 删除缓存文件
        file.delete();

        if (datalist == null) {
            logger.error("导入模板失败: 模板数据解析失败");
            set_redis_value(importKey, "1", "0", "0", "1", true);
            return;
        }

        List<WxBillDailyVo> successList = datalist.getList();
        List<WxBillDailyVo> failList = datalist.getFailList();
        List<WxBillDailyVo> processList = new ArrayList<>();

        int fail = 0;
        for (WxBillDailyVo vo : successList) {

            //店铺
            WxShop shop = new WxShop();
            shop.setShopNumber(vo.getShopNumber());
            shop.setTenantId(tenantId);
            shop.setType(vo.getRentShopType());
            shop.setStatus(EnumShopStatus.RENT.getCode());
            shop.setIsDel(EnumDelStatus.NOT_DEL.getCode());
            WxShop wxShop = wxShopMapper.selectOne(new QueryWrapper(shop));
            if (wxShop == null) {
                logger.error("店铺不存在", vo.toString());
                fail++;
                continue;
            }

            String receivePayStr = vo.getReceivePayStr();
            long receivePay = new BigDecimal(receivePayStr).multiply(new BigDecimal(100)).longValue();
            if (receivePay <= 0) {
                logger.error("实际应收金额小于等于0", vo.toString());
                fail++;
                continue;
            }
            String payStr = vo.getPayStr();
            long pay = new BigDecimal(payStr).multiply(new BigDecimal(100)).longValue();
            if (pay < 0) {
                logger.error("实收金额小于0", vo.toString());
                fail++;
                continue;
            }
            if (receivePay < pay) {
                logger.error("实际应收金额小于实收金额", vo.toString());
                fail++;
                continue;
            }
            vo.setReceivePay(receivePay);
            vo.setPay(pay);
            vo.setTenantId(tenantId);
            vo.setShopId(wxShop.getId());
            vo.setRentShopType(wxShop.getType());
            processList.add(vo);
        }
        logger.info("验证通过的数量: " + processList.size());
        logger.info("验证未通过的数量: " + failList.size());

        int all_success = processList.size();
        int all_fail = failList.size() + fail;
        int total = processList.size() + all_fail;

        //添加到redis里
        set_redis_value(importKey, "" + total, "" + all_success, "0", "" + all_fail, total == all_fail);

        if (processList.size() > 0) {
            try {
                processList.parallelStream().forEach(billDaily -> {
                    try {
                        //插入数据
                        wxBillDailyService.insertData(billDaily, importKey, user);
                    } catch (UnknownSessionException ue) {
                        logger.error("session :" + ue.getMessage());
                    }
                });
            } catch (Exception e) {
                set_redis_value(importKey, "1", "0", "0", "1", true);
                e.printStackTrace();
                logger.error("导入模板失败:" + e.getMessage());
            }
        }
    }
}
