package com.hwrj.cloud.admin.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSONArray;
import com.hwrj.cloud.admin.dao.PmsProductExcelDao;
import com.hwrj.cloud.admin.dto.param.PmsProductExcel;
import com.hwrj.cloud.admin.dto.param.PmsProductExcelParam;
import com.hwrj.cloud.admin.model.PmsBrand;
import com.hwrj.cloud.admin.util.ChineseCharToEn;
import com.hwrj.cloud.admin.util.MyStringUtils;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/*
 * 监听器批处理数据
 * */
@Component
@Transactional
public class PmsProductExcelListener extends AnalysisEventListener<PmsProductExcel> {

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

    private PmsProductExcelDao productExcelDao;

    public PmsProductExcelListener() {

    }

    private HttpServletResponse response;

    public PmsProductExcelListener(PmsProductExcelDao productExcelDao, HttpServletResponse response) {
        this.productExcelDao = productExcelDao;
        this.response = response;
    }


    /**
     * 批处理阈值2000
     */
    private static final int BATCH_COUNT = 2000;

    List<PmsProductExcelParam> list = new ArrayList();

    List<PmsProductExcelParam> alllist = new ArrayList();

    Set<String> companyList = new HashSet<>();

    Set<String> bandlist = new HashSet<>();

    List<PmsProductExcel> erroList = new ArrayList<>();


    @Override
    public void invoke(PmsProductExcel pmsProductExcel, AnalysisContext analysisContext) {
        LOGGER.info("解析到一条数据:{}", JSONArray.toJSONString(pmsProductExcel));

        addData(pmsProductExcel, analysisContext);

//        String productCategoryName = pmsProductExcel.getProductCategoryName();
//        if (StringUtils.isEmpty(productCategoryName)) {
//            pmsProductExcel.setErrMsg("没有商品类型无法导入!");
//            erroList.add(pmsProductExcel);
//            return;
//        }
//        String param = getParm(pmsProductExcel);
//        //判断数据是否重复
//        Long aLong = productExcelDao.checkOne(param);
//        if (aLong == 0) {
//            addData(pmsProductExcel, analysisContext);
//            return;
//        } else if (aLong > 0) {
//            pmsProductExcel.setErrMsg("数据库已存在!");
//            erroList.add(pmsProductExcel);
//            return;
//        }
    }

    private String getParm(PmsProductExcel pmsProductExcel) {
        //产品名称
        String name = pmsProductExcel.getName();

        //品牌
        String brandName = pmsProductExcel.getBrandName();

        //规格
        String spec = pmsProductExcel.getSpec();

        //价格
        BigDecimal price = pmsProductExcel.getPrice();
        // 四舍五入
        price.setScale(2, BigDecimal.ROUND_HALF_UP);
        // 不足两位小数补0
        DecimalFormat decimalFormat = new DecimalFormat("0.00#");
        String priceNew = decimalFormat.format(price);
        //供应商
        String umsCompanyInfo = pmsProductExcel.getUmsCompanyInfo();
        return replaceBlank(name + brandName + priceNew + spec + umsCompanyInfo);
    }

    private void addData(PmsProductExcel pmsProductExcel, AnalysisContext analysisContext) {
        //获取对应的行数
        int num = analysisContext.readRowHolder().getRowIndex();
        PmsProductExcelParam pmsProductExcelParam = getPmsProductParam(pmsProductExcel);
        list.add(pmsProductExcelParam);
        if (list.size() >= BATCH_COUNT) {
            saveData();
            alllist.addAll(list);
            list.clear();
        }
    }

    private void updateProduct() {
        //更新商品品牌
        if(bandlist.size()>0){
            //获取所有的品牌
            List<PmsBrand> allBrand = new ArrayList<>();
            for (String bandName : bandlist) {
                PmsBrand pmsBrand = new PmsBrand();
                //去除空格
                pmsBrand.setName(MyStringUtils.replaceBlank(bandName));
                //获取首字母大写
                pmsBrand.setFirstLetter(ChineseCharToEn.getAllFirstLetter(bandName));
                pmsBrand.setShowStatus(1);
                pmsBrand.setSort(1);
                pmsBrand.setFactoryStatus(1);
                pmsBrand.setProductCount(list.size());
                pmsBrand.setCreateId((long) 1);
                pmsBrand.setCreateTime(new Date());
                allBrand.add(pmsBrand);
            }
            //插入品牌数据
            if (allBrand.size() > 0) {
                productExcelDao.saveBrandData(allBrand);
            }
            LOGGER.info("存储数据库成功！");
            if (companyList.size() > 0) {
                //更新大小类以及品牌生产地
                List<String> companyNameList = new ArrayList<>(companyList);
                updateProductType(companyNameList);
            }
        }
    }

    @NotNull
    private PmsProductExcelParam getPmsProductParam(PmsProductExcel pmsProductExcel) {
        PmsProductExcelParam pmsProductExcelParam = new PmsProductExcelParam();
        BeanUtils.copyProperties(pmsProductExcel, pmsProductExcelParam);
        //名称
        String name = pmsProductExcel.getName();
        //价格
        BigDecimal price = pmsProductExcel.getPrice();
        //标题
        pmsProductExcelParam.setDetailTitle(name);
        //笔记
        pmsProductExcelParam.setNote(name);
        //关键字
        pmsProductExcelParam.setKeywords(name);

        String description = replaceBlank(pmsProductExcel.getDescription());

        //商品描述
        pmsProductExcelParam.setDescription(description);
        //简述
        pmsProductExcelParam.setSubTitle(description);
        //使用说明
        String instructions = replaceBlank(pmsProductExcel.getInstructions());
        //默认文本
        pmsProductExcelParam.setDetailDesc(instructions);
        //web网页显示
        pmsProductExcelParam.setDetailHtml(instructions);
        //手机网页显示
        pmsProductExcelParam.setDetailMobileHtml(instructions);
        //市场价
        pmsProductExcelParam.setOriginalPrice(price);
        //创建人 admin 1
        pmsProductExcelParam.setCreateUser((long) 1);
        //创建时间
        pmsProductExcelParam.setCreateTime(new Date());
        //未上架
        pmsProductExcelParam.setPublishStatus(0);
        //未审核
        pmsProductExcelParam.setVerifyStatus(0);
        return pmsProductExcelParam;
    }


    //更新大小类
    public void updateProductType(List<String> compName) {
        List<Long> ids = alllist.stream().map(PmsProductExcelParam::getId).distinct().collect(Collectors.toList());
        productExcelDao.updateBrand(compName,ids);
        productExcelDao.updateBigType(compName,ids);
        productExcelDao.updateSimType(compName,ids);
        productExcelDao.updateMemberOrigin(compName,ids);
    }

    @SneakyThrows
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();
        LOGGER.info("所有数据解析完成！");
//        if (erroList.size() > 0) {
//            String fileName = "导入失败数据" + System.currentTimeMillis();
//            // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
//            response.setContentType("application/vnd.ms-excel");
//            response.setCharacterEncoding("utf-8");
//            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
//            String fileNameNew = URLEncoder.encode(fileName, "UTF-8");
//            response.setHeader("Content-disposition", "attachment;filename=" + fileNameNew + ".xlsx");
//            EasyExcel.write(response.getOutputStream(), PmsProductExcel.class).sheet("Sheet").doWrite(erroList);
//        }

        updateProduct();


    }

    private void saveData() {
        LOGGER.info("{}条数据，开始存储数据库！", list.size());
        //调用saveData()方法
        if (list.size() > 0) {
            LOGGER.info("开始插入商品数据");
            productExcelDao.saveData(list);
            //获取品牌
            List<String> bandNameNew= list.stream().map(PmsProductExcelParam::getBrandName).distinct().collect(Collectors.toList());
            bandlist.addAll(bandNameNew);
            //获取供应商
            List<String>CompanyNameNew= list.stream().map(PmsProductExcelParam::getUmsCompanyInfo).distinct().collect(Collectors.toList());
            companyList.addAll(CompanyNameNew);
        }

    }

    public static String replaceBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }
}
