package com.scpyun.platform.jilinsscgsdp.utils;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.scpyun.base.core.utils.StringUtils;
import com.scpyun.base.core.utils.UUIDUtil;
import com.scpyun.base.db.service.CommonService;
import com.scpyun.platform.jilinsscgsdp.bean.entity.MaterialImp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public class MaterialFileListener extends AnalysisEventListener<MaterialImp> {
    private static final Logger log = LoggerFactory.getLogger(MaterialFileListener.class);
    private static final int BATCH_COUNT = 200;
    private List<MaterialImp> cached = new ArrayList<>(BATCH_COUNT);
    private AtomicInteger insertCount = new AtomicInteger(0);
    private AtomicInteger updateCount = new AtomicInteger(0);
    private AtomicInteger errorCount = new AtomicInteger(0);

    private CommonService commonService;
    private String namespace;
    private Map<String,Object> param;
    private List<String> errInfo = new ArrayList<>();


//    private String catgoryNamespace = "com.scpyun.platform.standard.jilinsscgsdp.keyDmMaterialCategory.";
//    private String materialNamespace = "com.scpyun.platform.standard.jilinsscgsdp.keyDmMaterial.";

    private Map<String, Map> catgoryMap = new HashMap<>();
    private Map<String, Map> materialMap = new HashMap<>();
    private int sortNo = 0;
    private Map<String, Object> user = null;


    public MaterialFileListener(CommonService commonService, String namespace, Map<String,Object> param) {
        this.commonService = commonService;
        this.namespace = namespace;
        this.param = param;
        user = (Map<String, Object>) param.get("_user");
        //获取所有办公用品分类信息
        List<Map<String, Object>> catgoryLisit = commonService.findList(namespace + "findMaterialCategoryList", param);
        catgoryLisit.forEach(item -> {
            catgoryMap.put(String.valueOf(item.get("category_name")), item);
        });
        //获取所有办公用品信息，后续根据办公用品编码来判断更新或插入
        List<Map<String, Object>> materialLisit = commonService.findList(namespace + "findMaterialList", param);
        for (int i = 0; i < materialLisit.size(); i++) {
            Map<String, Object> item =  materialLisit.get(i);
            materialMap.put(String.valueOf(item.get("material_code")), item);
            Integer sort =  (Integer)item.get("sort_no");
            if (sort != null && sortNo < sort.intValue()) {
                sortNo = sort;
            }
        }
        sortNo = sortNo + 1;
    }

    @Override
    public void invoke(MaterialImp data, AnalysisContext context) {
        try {
            // 这里可以添加数据校验逻辑
            if (isValidProduct(data)) {
                cached.add(data);
            } else {
                errorCount.incrementAndGet(); // 失败计数增加
            }

            if (cached.size() >= BATCH_COUNT) {
                saveBatch();
                cached.clear();
            }
        } catch (Exception e) {
            errorCount.incrementAndGet();
            log.error("解析物料导入行异常", e);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (!cached.isEmpty()) {
            saveBatch();
            cached.clear();
        }
    }

    private void saveBatch() {
        if (cached.isEmpty()) {
            return;
        }

        for (MaterialImp m : cached) {
            try {
                Map<String,Object> row = new HashMap<>();

                Map<String, Object> exists = materialMap.get(m.getMaterial_code());
                if(StringUtils.isNotEmpty(m.getCategory_name())) {
                    Map<String, Object> catgory = catgoryMap.get(m.getCategory_name());
                    if(catgory!=null) {
                        row.put("category_id", String.valueOf(catgory.get("id")));
                    }
                }

                double min = 0L;
                double max = 0L;
                int can_borrow = 0;
                double unit_price = 0L;
                if(m.getMin_stock()!=null) {
                    min = m.getMin_stock();
                }
                if(m.getMax_stock()!=null) {
                    max = m.getMax_stock();
                }
                if("是".equals(m.getCan_borrow())) {
                    can_borrow = 1;
                }
                if(m.getUnit_price()!=null) {
                    unit_price = m.getUnit_price();
                }

                row.put("material_code", m.getMaterial_code());
                row.put("material_name", m.getMaterial_name());
                row.put("material_spec", m.getMaterial_spec());
                row.put("unit", m.getUnit());
                row.put("unit_price", unit_price);
                row.put("storage_location", m.getStorage_location());
                row.put("min_stock", min);
                row.put("max_stock", max);
                row.put("can_borrow", can_borrow);
                row.put("material_desc", m.getMaterial_desc());
                row.put("order_no", sortNo++);
                row.put("supplier_name", m.getSupplier_name());
                row.put("status", 1);
                row.put("_user", user);
                if (exists == null) {
                    row.put("id", UUIDUtil.getUUID());
                    commonService.insert(namespace + "insertMaterial", row);
                    insertCount.incrementAndGet();
                } else {
                    row.put("id", exists.get("id"));
                    commonService.update(namespace + "updateMaterial", row);
                    updateCount.incrementAndGet();
                }
            } catch (Exception ex) {
                errorCount.incrementAndGet();
                errInfo.add(m.getMaterial_code() + ":" + ex.getMessage());
            }
        }
    }

    /**
     * 数据校验方法
     */
    private boolean isValidProduct(MaterialImp data) {
        //用品编码、名称
        return data.getMaterial_code() != null &&
                !data.getMaterial_code().trim().isEmpty() &&
                data.getMaterial_name() != null &&
                !data.getMaterial_name().trim().isEmpty(); //
    }

    public Map<String,Object> getResult() {
        Map<String,Object> r = new HashMap<>();
        r.put("insert", insertCount.get());
        r.put("update", updateCount.get());
        r.put("error", errorCount.get());
        r.put("errInfo", String.join(",", errInfo));
        return r;
    }
}


